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/order.rb')
-rw-r--r--lib/gitlab/pagination/keyset/order.rb33
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/gitlab/pagination/keyset/order.rb b/lib/gitlab/pagination/keyset/order.rb
index e596e1bac9d..cef3a7b291a 100644
--- a/lib/gitlab/pagination/keyset/order.rb
+++ b/lib/gitlab/pagination/keyset/order.rb
@@ -135,7 +135,7 @@ module Gitlab
#
# (id < 3 AND created_at IS NULL) OR (created_at IS NOT NULL)
def build_where_values(values)
- return if values.blank?
+ return [] if values.blank?
verify_incoming_values!(values)
@@ -156,13 +156,26 @@ module Gitlab
end
end
- build_or_query(where_values)
+ where_values
+ end
+
+ def where_values_with_or_query(values)
+ build_or_query(build_where_values(values.with_indifferent_access))
end
# rubocop: disable CodeReuse/ActiveRecord
- def apply_cursor_conditions(scope, values = {})
+ def apply_cursor_conditions(scope, values = {}, options = { use_union_optimization: false })
+ values ||= {}
+ transformed_values = values.with_indifferent_access
scope = apply_custom_projections(scope)
- scope.where(build_where_values(values.with_indifferent_access))
+
+ where_values = build_where_values(transformed_values)
+
+ if options[:use_union_optimization] && where_values.size > 1
+ build_union_query(scope, where_values).reorder(self)
+ else
+ scope.where(build_or_query(where_values)) # rubocop: disable CodeReuse/ActiveRecord
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -170,6 +183,8 @@ module Gitlab
self.class.build(column_definitions.map(&:reverse))
end
+ alias_method :to_sql, :to_s
+
private
# Adds extra columns to the SELECT clause
@@ -210,11 +225,19 @@ module Gitlab
end
def build_or_query(expressions)
- or_expression = expressions.reduce { |or_expression, expression| Arel::Nodes::Or.new(or_expression, expression) }
+ return [] if expressions.blank?
+ or_expression = expressions.reduce { |or_expression, expression| Arel::Nodes::Or.new(or_expression, expression) }
Arel::Nodes::Grouping.new(or_expression)
end
+ def build_union_query(scope, where_values)
+ scopes = where_values.map do |where_value|
+ scope.dup.where(where_value).reorder(self) # rubocop: disable CodeReuse/ActiveRecord
+ end
+ scope.model.from_union(scopes, remove_duplicates: false, remove_order: false)
+ end
+
def to_sql_literal(column_definitions)
column_definitions.map do |column_definition|
if column_definition.order_expression.respond_to?(:to_sql)