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 'lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb')
-rw-r--r--lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb41
1 files changed, 7 insertions, 34 deletions
diff --git a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
index 39d6e016ac7..53faf8469f2 100644
--- a/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
+++ b/lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb
@@ -6,10 +6,7 @@ module Gitlab
module InOperatorOptimization
# rubocop: disable CodeReuse/ActiveRecord
class QueryBuilder
- UnsupportedScopeOrder = Class.new(StandardError)
-
RECURSIVE_CTE_NAME = 'recursive_keyset_cte'
- RECORDS_COLUMN = 'records'
# This class optimizes slow database queries (PostgreSQL specific) where the
# IN SQL operator is used with sorting.
@@ -42,26 +39,19 @@ module Gitlab
# > array_mapping_scope: array_mapping_scope,
# > finder_query: finder_query
# > ).execute.limit(20)
- def initialize(scope:, array_scope:, array_mapping_scope:, finder_query:, values: {})
+ def initialize(scope:, array_scope:, array_mapping_scope:, finder_query: nil, values: {})
@scope, success = Gitlab::Pagination::Keyset::SimpleOrderBuilder.build(scope)
- unless success
- error_message = <<~MSG
- The order on the scope does not support keyset pagination. You might need to define a custom Order object.\n
- See https://docs.gitlab.com/ee/development/database/keyset_pagination.html#complex-order-configuration\n
- Or the Gitlab::Pagination::Keyset::Order class for examples
- MSG
- raise(UnsupportedScopeOrder, error_message)
- end
+ raise(UnsupportedScopeOrder) unless success
@order = Gitlab::Pagination::Keyset::Order.extract_keyset_order_object(scope)
@array_scope = array_scope
@array_mapping_scope = array_mapping_scope
- @finder_query = finder_query
@values = values
@model = @scope.model
@table_name = @model.table_name
@arel_table = @model.arel_table
+ @finder_strategy = finder_query.present? ? Strategies::RecordLoaderStrategy.new(finder_query, model, order_by_columns) : Strategies::OrderValuesLoaderStrategy.new(model, order_by_columns)
end
def execute
@@ -74,7 +64,7 @@ module Gitlab
q = cte
.apply_to(model.where({})
.with(selector_cte.to_arel))
- .select(result_collector_final_projections)
+ .select(finder_strategy.final_projections)
.where("count <> 0") # filter out the initializer row
model.from(q.arel.as(table_name))
@@ -82,13 +72,13 @@ module Gitlab
private
- attr_reader :array_scope, :scope, :order, :array_mapping_scope, :finder_query, :values, :model, :table_name, :arel_table
+ attr_reader :array_scope, :scope, :order, :array_mapping_scope, :finder_strategy, :values, :model, :table_name, :arel_table
def initializer_query
array_column_names = array_scope_columns.array_aggregated_column_names + order_by_columns.array_aggregated_column_names
projections = [
- *result_collector_initializer_columns,
+ *finder_strategy.initializer_columns,
*array_column_names,
'0::bigint AS count'
]
@@ -156,7 +146,7 @@ module Gitlab
order_column_value_arrays = order_by_columns.replace_value_in_array_by_position_expressions
select = [
- *result_collector_columns,
+ *finder_strategy.columns,
*array_column_list,
*order_column_value_arrays,
"#{RECURSIVE_CTE_NAME}.count + 1"
@@ -254,23 +244,6 @@ module Gitlab
end.join(", ")
end
- def result_collector_initializer_columns
- ["NULL::#{table_name} AS #{RECORDS_COLUMN}"]
- end
-
- def result_collector_columns
- query = finder_query
- .call(*order_by_columns.array_lookup_expressions_by_position(RECURSIVE_CTE_NAME))
- .select("#{table_name}")
- .limit(1)
-
- ["(#{query.to_sql})"]
- end
-
- def result_collector_final_projections
- ["(#{RECORDS_COLUMN}).*"]
- end
-
def array_scope_columns
@array_scope_columns ||= ArrayScopeColumns.new(array_scope.select_values)
end