diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-07 15:09:13 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-07 15:09:13 +0300 |
commit | 211a8c3361ccf4eb92f36edbdcf15c98fcdcc8b7 (patch) | |
tree | 0ad37172721a39b0d57240bb1b4e70f200a0d93e /lib/gitlab/graphql | |
parent | 456a7247f9e88fc2518b69a1a00e905c6db6d775 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/graphql')
3 files changed, 41 insertions, 16 deletions
diff --git a/lib/gitlab/graphql/connections/keyset/conditions/base_condition.rb b/lib/gitlab/graphql/connections/keyset/conditions/base_condition.rb index 8c0d71aff6d..26c9d77a8df 100644 --- a/lib/gitlab/graphql/connections/keyset/conditions/base_condition.rb +++ b/lib/gitlab/graphql/connections/keyset/conditions/base_condition.rb @@ -6,6 +6,12 @@ module Gitlab module Keyset module Conditions class BaseCondition + # @param [Arel::Table] arel_table for the relation being ordered + # @param [Array<OrderInfo>] order_list of extracted orderings + # @param [Array] values from the decoded cursor + # @param [Array<String>] operators determining sort comparison + # @param [Symbol] before_or_after indicates whether we want + # items :before the cursor or :after the cursor def initialize(arel_table, order_list, values, operators, before_or_after) @arel_table, @order_list, @values, @operators, @before_or_after = arel_table, order_list, values, operators, before_or_after @@ -20,18 +26,25 @@ module Gitlab attr_reader :arel_table, :order_list, :values, :operators, :before_or_after - def table_condition(attribute, value, operator) + def table_condition(order_info, value, operator) + if order_info.named_function + target = order_info.named_function + value = value&.downcase if target&.name&.downcase == 'lower' + else + target = arel_table[order_info.attribute_name] + end + case operator when '>' - arel_table[attribute].gt(value) + target.gt(value) when '<' - arel_table[attribute].lt(value) + target.lt(value) when '=' - arel_table[attribute].eq(value) + target.eq(value) when 'is_null' - arel_table[attribute].eq(nil) + target.eq(nil) when 'is_not_null' - arel_table[attribute].not_eq(nil) + target.not_eq(nil) end end end diff --git a/lib/gitlab/graphql/connections/keyset/order_info.rb b/lib/gitlab/graphql/connections/keyset/order_info.rb index e112154cfbc..7f61bf937b4 100644 --- a/lib/gitlab/graphql/connections/keyset/order_info.rb +++ b/lib/gitlab/graphql/connections/keyset/order_info.rb @@ -5,10 +5,10 @@ module Gitlab module Connections module Keyset class OrderInfo - attr_reader :attribute_name, :sort_direction + attr_reader :attribute_name, :sort_direction, :named_function def initialize(order_value) - @attribute_name, @sort_direction = + @attribute_name, @sort_direction, @named_function = if order_value.is_a?(String) extract_nulls_last_order(order_value) else @@ -69,11 +69,24 @@ module Gitlab def extract_nulls_last_order(order_value) tokens = order_value.downcase.split - [tokens.first, (tokens[1] == 'asc' ? :asc : :desc)] + [tokens.first, (tokens[1] == 'asc' ? :asc : :desc), nil] end def extract_attribute_values(order_value) - [order_value.expr.name, order_value.direction] + named = nil + name = if ordering_by_lower?(order_value) + named = order_value.expr + named.expressions[0].name.to_s + else + order_value.expr.name + end + + [name, order_value.direction, named] + end + + # determine if ordering using LOWER, eg. "ORDER BY LOWER(boards.name)" + def ordering_by_lower?(order_value) + order_value.expr.is_a?(Arel::Nodes::NamedFunction) && order_value.expr&.name&.downcase == 'lower' end end end diff --git a/lib/gitlab/graphql/connections/keyset/query_builder.rb b/lib/gitlab/graphql/connections/keyset/query_builder.rb index e93c25d85fc..fe85898f638 100644 --- a/lib/gitlab/graphql/connections/keyset/query_builder.rb +++ b/lib/gitlab/graphql/connections/keyset/query_builder.rb @@ -40,17 +40,16 @@ module Gitlab # "issues"."id" > 500 # def conditions - attr_names = order_list.map { |field| field.attribute_name } - attr_values = attr_names.map { |name| decoded_cursor[name] } + attr_values = order_list.map { |field| decoded_cursor[field.attribute_name] } - if attr_names.count == 1 && attr_values.first.nil? + if order_list.count == 1 && attr_values.first.nil? raise Gitlab::Graphql::Errors::ArgumentError.new('Before/after cursor invalid: `nil` was provided as only sortable value') end - if attr_names.count == 1 || attr_values.first.present? - Keyset::Conditions::NotNullCondition.new(arel_table, attr_names, attr_values, operators, before_or_after).build + if order_list.count == 1 || attr_values.first.present? + Keyset::Conditions::NotNullCondition.new(arel_table, order_list, attr_values, operators, before_or_after).build else - Keyset::Conditions::NullCondition.new(arel_table, attr_names, attr_values, operators, before_or_after).build + Keyset::Conditions::NullCondition.new(arel_table, order_list, attr_values, operators, before_or_after).build end end |