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.rb24
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/gitlab/pagination/keyset/order.rb b/lib/gitlab/pagination/keyset/order.rb
index cef3a7b291a..19d44ee69dd 100644
--- a/lib/gitlab/pagination/keyset/order.rb
+++ b/lib/gitlab/pagination/keyset/order.rb
@@ -139,6 +139,8 @@ module Gitlab
verify_incoming_values!(values)
+ return use_composite_row_comparison(values) if composite_row_comparison_possible?
+
where_values = []
reversed_column_definitions = column_definitions.reverse
@@ -187,6 +189,28 @@ module Gitlab
private
+ def composite_row_comparison_possible?
+ !column_definitions.one? &&
+ column_definitions.all?(&:not_nullable?) &&
+ column_definitions.map(&:order_direction).uniq.one? # all columns uses the same order direction
+ end
+
+ # composite row comparison works with NOT NULL columns and may use only one index scan given a proper index setup
+ # Example: (created_at, id) > ('2012-09-18 01:40:01+00', 15)
+ def use_composite_row_comparison(values)
+ columns = Arel::Nodes::Grouping.new(column_definitions.map(&:column_expression))
+ values = Arel::Nodes::Grouping.new(column_definitions.map do |column_definition|
+ value = values[column_definition.attribute_name]
+ Arel::Nodes.build_quoted(value, column_definition.column_expression)
+ end)
+
+ if column_definitions.first.ascending_order?
+ [columns.gt(values)]
+ else
+ [columns.lt(values)]
+ end
+ end
+
# Adds extra columns to the SELECT clause
def apply_custom_projections(scope)
additional_projections = column_definitions.select(&:add_to_projections).map do |column_definition|