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/order_by_column_data_spec.rb35
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder_spec.rb73
-rw-r--r--spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb37
3 files changed, 136 insertions, 9 deletions
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb
new file mode 100644
index 00000000000..b4869f49081
--- /dev/null
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/order_by_column_data_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::OrderByColumnData do
+ let(:arel_table) { Issue.arel_table }
+
+ let(:column) do
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ column_expression: arel_table[:id],
+ order_expression: arel_table[:id].desc
+ )
+ end
+
+ subject(:column_data) { described_class.new(column, 'column_alias', arel_table) }
+
+ describe '#arel_column' do
+ it 'delegates to column_expression' do
+ expect(column_data.arel_column).to eq(column.column_expression)
+ end
+ end
+
+ describe '#column_for_projection' do
+ it 'returns the expression with AS using the original column name' do
+ expect(column_data.column_for_projection.to_sql).to eq('"issues"."id" AS id')
+ end
+ end
+
+ describe '#projection' do
+ it 'returns the expression with AS using the specified column lias' do
+ expect(column_data.projection.to_sql).to eq('"issues"."id" AS column_alias')
+ end
+ end
+end
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 00beacd4b35..58db22e5a9c 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,14 +33,14 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
]
end
- shared_examples 'correct ordering examples' do
- let(:iterator) do
- Gitlab::Pagination::Keyset::Iterator.new(
- scope: scope.limit(batch_size),
- in_operator_optimization_options: in_operator_optimization_options
- )
- end
+ let(:iterator) do
+ Gitlab::Pagination::Keyset::Iterator.new(
+ scope: scope.limit(batch_size),
+ in_operator_optimization_options: in_operator_optimization_options
+ )
+ end
+ shared_examples 'correct ordering examples' do |opts = {}|
let(:all_records) do
all_records = []
iterator.each_batch(of: batch_size) do |records|
@@ -49,8 +49,10 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
all_records
end
- it 'returns records in correct order' do
- expect(all_records).to eq(expected_order)
+ unless opts[:skip_finder_query_test]
+ it 'returns records in correct order' do
+ expect(all_records).to eq(expected_order)
+ end
end
context 'when not passing the finder query' do
@@ -248,4 +250,57 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
expect { described_class.new(**options).execute }.to raise_error(/The order on the scope does not support keyset pagination/)
end
+
+ context 'when ordering by SQL expression' do
+ let(:order) do
+ # ORDER BY (id * 10), id
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_multiplied_by_ten',
+ order_expression: Arel.sql('(id * 10)').asc,
+ sql_type: 'integer'
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: :id,
+ order_expression: Issue.arel_table[:id].asc
+ )
+ ])
+ end
+
+ let(:scope) { Issue.reorder(order) }
+ let(:expected_order) { issues.sort_by(&:id) }
+
+ 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) { Issue.where(Issue.arel_table[:project_id].eq(id_expression)) }
+ }
+ end
+
+ context 'when iterating records one by one' do
+ let(:batch_size) { 1 }
+
+ it_behaves_like 'correct ordering examples', skip_finder_query_test: true
+ end
+
+ context 'when iterating records with LIMIT 3' do
+ let(:batch_size) { 3 }
+
+ it_behaves_like 'correct ordering examples', skip_finder_query_test: true
+ end
+
+ context 'when passing finder query' do
+ let(:batch_size) { 3 }
+
+ it 'raises error, loading complete rows are not supported with SQL expressions' do
+ in_operator_optimization_options[:finder_query] = -> (_, _) { Issue.select(:id, '(id * 10)').where(id: -1) }
+
+ expect(in_operator_optimization_options[:finder_query]).not_to receive(:call)
+
+ expect do
+ iterator.each_batch(of: batch_size) { |records| records.to_a }
+ end.to raise_error /The "RecordLoaderStrategy" does not support/
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
index fe95d5406dd..ab1037b318b 100644
--- a/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/order_values_loader_strategy_spec.rb
@@ -31,4 +31,41 @@ RSpec.describe Gitlab::Pagination::Keyset::InOperatorOptimization::Strategies::O
])
end
end
+
+ context 'when an SQL expression is given' do
+ context 'when the sql_type attribute is missing' do
+ let(:order) do
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_times_ten',
+ order_expression: Arel.sql('id * 10').asc
+ )
+ ])
+ end
+
+ let(:keyset_scope) { Project.order(order) }
+
+ it 'raises error' do
+ expect { strategy.initializer_columns }.to raise_error(Gitlab::Pagination::Keyset::SqlTypeMissingError)
+ end
+ end
+
+ context 'when the sql_type_attribute is present' do
+ let(:order) do
+ Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id_times_ten',
+ order_expression: Arel.sql('id * 10').asc,
+ sql_type: 'integer'
+ )
+ ])
+ end
+
+ let(:keyset_scope) { Project.order(order) }
+
+ it 'returns the initializer columns' do
+ expect(strategy.initializer_columns).to eq(['NULL::integer AS id_times_ten'])
+ end
+ end
+ end
end