From 4762adc5e671743030a2cadfa43e25c002e4295f Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 19 Sep 2023 16:27:40 +0100 Subject: [PATCH 1/2] Fix tests in NullRelationTest --- .../sqlserver/core_ext/calculations.rb | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb index da0e37f80..0853cd35d 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb @@ -8,18 +8,41 @@ module ConnectionAdapters module SQLServer module CoreExt module Calculations - # Same as original except we don't perform PostgreSQL hack that removes ordering. def calculate(operation, column_name) - return super unless klass.connection.adapter_name == "SQLServer" + if klass.connection.sqlserver? + _calculate(operation, column_name) + else + super + end + end + + private + + # Same as original `calculate` method except we don't perform PostgreSQL hack that removes ordering. + def _calculate(operation, column_name) + operation = operation.to_s.downcase + + if @none + case operation + when "count", "sum" + result = group_values.any? ? Hash.new : 0 + return @async ? Promise::Complete.new(result) : result + when "average", "minimum", "maximum" + result = group_values.any? ? Hash.new : nil + return @async ? Promise::Complete.new(result) : result + end + end if has_include?(column_name) relation = apply_join_dependency - if operation.to_s.downcase == "count" + if operation == "count" unless distinct_value || distinct_select?(column_name || select_for_count) relation.distinct! - relation.select_values = [klass.primary_key || table[Arel.star]] + relation.select_values = [ klass.primary_key || table[Arel.star] ] end + # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT + # relation.order_values = [] if group_values.empty? end relation.calculate(operation, column_name) @@ -28,8 +51,6 @@ def calculate(operation, column_name) end end - private - def build_count_subquery(relation, column_name, distinct) return super unless klass.connection.adapter_name == "SQLServer" From 9e03b0391f1977bd7df307d004ae3c2fa96f9050 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 19 Sep 2023 16:37:14 +0100 Subject: [PATCH 2/2] Cleanup --- .../sqlserver/core_ext/calculations.rb | 2 ++ .../sqlserver/core_ext/finder_methods.rb | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb index 0853cd35d..34355ef53 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb @@ -42,7 +42,9 @@ def _calculate(operation, column_name) relation.select_values = [ klass.primary_key || table[Arel.star] ] end # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT + # Start of monkey-patch # relation.order_values = [] if group_values.empty? + # End of monkey-patch end relation.calculate(operation, column_name) diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb index 03932d492..fe9271508 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb @@ -10,18 +10,26 @@ module CoreExt module FinderMethods private - # Same as original except we order by values in distinct select if present. def construct_relation_for_exists(conditions) - return super unless klass.connection.adapter_name == "SQLServer" + if klass.connection.sqlserver? + _construct_relation_for_exists(conditions) + else + super + end + end + # Same as original except we order by values in distinct select if present. + def _construct_relation_for_exists(conditions) conditions = sanitize_forbidden_attributes(conditions) if distinct_value && offset_value + # Start of monkey-patch if select_values.present? relation = order(*select_values).limit!(1) else relation = except(:order).limit!(1) end + # End of monkey-patch else relation = except(:select, :distinct, :order)._select!(::ActiveRecord::FinderMethods::ONE_AS_ONE).limit!(1) end