Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/pagination/keyset')
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb63
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb32
-rw-r--r--spec/lib/gitlab/pagination/keyset/iterator_spec.rb2
-rw-r--r--spec/lib/gitlab/pagination/keyset/order_spec.rb54
4 files changed, 135 insertions, 16 deletions
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
index cc85c897019..1c67c9e0b95 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb
@@ -33,6 +33,18 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
]
end
+ let_it_be(:ignored_column_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = 'issues'
+
+ include IgnorableColumns
+
+ ignore_column :title, remove_with: '16.4', remove_after: '2023-08-22'
+ end
+ end
+
+ let(:scope_model) { Issue }
+ let(:created_records) { issues }
let(:iterator) do
Gitlab::Pagination::Keyset::Iterator.new(
scope: scope.limit(batch_size),
@@ -79,6 +91,55 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
end
end
+ context 'when the scope model has ignored columns' do
+ let(:scope) { ignored_column_model.order(id: :desc) }
+ let(:expected_order) { ignored_column_model.where(id: issues.map(&:id)).sort_by(&:id).reverse }
+
+ let(:in_operator_optimization_options) do
+ {
+ array_scope: Project.where(namespace_id: top_level_group.self_and_descendants.select(:id)).select(:id),
+ array_mapping_scope: -> (id_expression) { ignored_column_model.where(ignored_column_model.arel_table[:project_id].eq(id_expression)) },
+ finder_query: -> (id_expression) { ignored_column_model.where(ignored_column_model.arel_table[:id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples'
+
+ context 'when scope selects only some columns' do
+ let(:scope) { ignored_column_model.order(id: :desc).select(:id) }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples'
+
+ context 'when scope selects only some columns' do
+ let(:scope) { ignored_column_model.order(id: :desc).select(:id) }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+
+ context 'when loading records at once' do
+ let(:batch_size) { issues.size + 1 }
+
+ it_behaves_like 'correct ordering examples'
+
+ context 'when scope selects only some columns' do
+ let(:scope) { ignored_column_model.order(id: :desc).select(:id) }
+
+ it_behaves_like 'correct ordering examples'
+ end
+ end
+ end
+
context 'when ordering by issues.id DESC' do
let(:scope) { Issue.order(id: :desc) }
let(:expected_order) { issues.sort_by(&:id).reverse }
@@ -332,7 +393,7 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
end
context 'when ordering by JOIN-ed columns' do
- let(:scope) { cte_with_issues_and_projects.apply_to(Issue.where({})).reorder(order) }
+ let(:scope) { cte_with_issues_and_projects.apply_to(Issue.where({}).select(Arel.star)).reorder(order) }
let(:cte_with_issues_and_projects) do
cte_query = Issue.select('issues.id AS id', 'project_id', 'projects.id AS projects_id', 'projects.name AS projects_name').joins(:project)
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
index 5180403b493..3fe858f33da 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb
@@ -3,12 +3,12 @@
require 'spec_helper'
RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::RecordLoaderStrategy do
- let(:finder_query) { -> (created_at_value, id_value) { Project.where(Project.arel_table[:id].eq(id_value)) } }
+ let(:finder_query) { -> (created_at_value, id_value) { model.where(model.arel_table[:id].eq(id_value)) } }
let(:model) { Project }
let(:keyset_scope) do
scope, _ = Gitlab::Pagination::Keyset::SimpleOrderBuilder.build(
- Project.order(:created_at, :id)
+ model.order(:created_at, :id)
)
scope
@@ -22,6 +22,16 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::R
Gitlab::Pagination::Keyset::InOperatorOptimization::OrderByColumns.new(keyset_order.column_definitions, model.arel_table)
end
+ let_it_be(:ignored_column_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = 'projects'
+
+ include IgnorableColumns
+
+ ignore_column :name, remove_with: '16.4', remove_after: '2023-08-22'
+ end
+ end
+
subject(:strategy) { described_class.new(finder_query, model, order_by_columns) }
describe '#initializer_columns' do
@@ -57,4 +67,22 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::R
expect(strategy.columns).to eq([expected_loader_query.chomp])
end
end
+
+ describe '#final_projections' do
+ context 'when model does not have ignored columns' do
+ it 'does not specify the selected column names' do
+ expect(strategy.final_projections).to contain_exactly("(#{described_class::RECORDS_COLUMN}).*")
+ end
+ end
+
+ context 'when model has ignored columns' do
+ let(:model) { ignored_column_model }
+
+ it 'specifies the selected column names' do
+ expect(strategy.final_projections).to match_array(
+ model.default_select_columns.map { |column| "(#{described_class::RECORDS_COLUMN}).#{column.name}" }
+ )
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/pagination/keyset/iterator_spec.rb b/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
index eee743c5e48..afaad48d363 100644
--- a/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Iterator do
time = Time.current
iterator.each_batch(of: 2) do |relation|
- Issue.connection.execute("UPDATE issues SET updated_at = '#{time.to_s(:inspect)}' WHERE id IN (#{relation.reselect(:id).to_sql})")
+ Issue.connection.execute("UPDATE issues SET updated_at = '#{time.to_fs(:inspect)}' WHERE id IN (#{relation.reselect(:id).to_sql})")
end
expect(Issue.pluck(:updated_at)).to all(be_within(5.seconds).of(time))
diff --git a/spec/lib/gitlab/pagination/keyset/order_spec.rb b/spec/lib/gitlab/pagination/keyset/order_spec.rb
index e99846ad424..05bb0bb8b3a 100644
--- a/spec/lib/gitlab/pagination/keyset/order_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/order_spec.rb
@@ -148,7 +148,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'id',
@@ -193,7 +193,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'year',
@@ -260,7 +260,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'year',
@@ -327,7 +327,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'year',
@@ -394,7 +394,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
end
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'year',
@@ -452,7 +452,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
context 'when ordering by the named function LOWER' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'title',
@@ -494,7 +494,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
context 'when the passed cursor values do not match with the order definition' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'year',
@@ -564,7 +564,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
context 'when string attribute name is given' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'id',
@@ -580,7 +580,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
context 'when symbol attribute name is given' do
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: :id,
@@ -606,7 +606,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
context 'when there are additional_projections' do
let(:order) do
- order = Gitlab::Pagination::Keyset::Order.build(
+ order = described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'created_at_field',
@@ -645,6 +645,16 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
let_it_be(:user_2) { create(:user, created_at: five_months_ago) }
let_it_be(:user_3) { create(:user, created_at: 1.month.ago) }
let_it_be(:user_4) { create(:user, created_at: 2.months.ago) }
+ let_it_be(:ignored_column_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = 'users'
+
+ include IgnorableColumns
+ include FromUnion
+
+ ignore_column :username, remove_with: '16.4', remove_after: '2023-08-22'
+ end
+ end
let(:expected_results) { [user_3, user_4, user_2, user_1] }
let(:scope) { User.order(created_at: :desc, id: :desc) }
@@ -672,6 +682,26 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
iterator_options[:use_union_optimization] = true
end
+ context 'when the scope model has ignored columns' do
+ let(:ignored_expected_results) { expected_results.map { |r| r.becomes(ignored_column_model) } } # rubocop:disable Cop/AvoidBecomes
+
+ context 'when scope selects all columns' do
+ let(:scope) { ignored_column_model.order(created_at: :desc, id: :desc) }
+
+ it 'returns items in the correct order' do
+ expect(items).to eq(ignored_expected_results)
+ end
+ end
+
+ context 'when scope selects only specific columns' do
+ let(:scope) { ignored_column_model.order(created_at: :desc, id: :desc).select(:id, :created_at) }
+
+ it 'returns items in the correct order' do
+ expect(items).to eq(ignored_expected_results)
+ end
+ end
+ end
+
it 'returns items in the correct order' do
expect(items).to eq(expected_results)
end
@@ -687,7 +717,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
it 'builds UNION query' do
cursor_attributes = { created_at: five_months_ago, id: user_2.id }
- order = Gitlab::Pagination::Keyset::Order.extract_keyset_order_object(keyset_aware_scope)
+ order = described_class.extract_keyset_order_object(keyset_aware_scope)
query = order.apply_cursor_conditions(scope, cursor_attributes, use_union_optimization: true).to_sql
expect(query).to include('UNION ALL')
@@ -698,7 +728,7 @@ RSpec.describe Gitlab::Pagination::Keyset::Order do
describe '#attribute_names' do
let(:expected_attribute_names) { %w(id name) }
let(:order) do
- Gitlab::Pagination::Keyset::Order.build(
+ described_class.build(
[
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
attribute_name: 'id',