aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2017-10-14 13:19:26 +0900
committerRyuta Kamizono <kamipo@gmail.com>2017-10-14 13:36:51 +0900
commit5668dc6b1863ef43be8f8ef0fb1d5db913085fb3 (patch)
tree0f46675c24941c36c97426ae6e71829b3f35406d
parent3d1ff79742c46930fa35352c42fb585c3408511b (diff)
downloadrails-5668dc6b1863ef43be8f8ef0fb1d5db913085fb3.tar.gz
rails-5668dc6b1863ef43be8f8ef0fb1d5db913085fb3.tar.bz2
rails-5668dc6b1863ef43be8f8ef0fb1d5db913085fb3.zip
Fix `COUNT(DISTINCT ...)` for `GROUP BY` with `ORDER BY` and `LIMIT`
This is the fix for the regression of #29848. In #29848, I've kept existing select list in the subquery for the count if ORDER BY is given. But it had accidentally affect to GROUP BY queries also. It should keep the previous behavior in that case. Fixes #30886.
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb2
-rw-r--r--activerecord/test/cases/calculations_test.rb4
3 files changed, 11 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 288f22a9d3..490908417a 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Fix `COUNT(DISTINCT ...)` for `GROUP BY` with `ORDER BY` and `LIMIT`.
+
+ Fixes #30886.
+
+ *Ryuta Kamizono*
+
* PostgreSQL `tsrange` now preserves subsecond precision.
PostgreSQL 9.1+ introduced range types, and Rails added support for using
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 4ef0502893..116bddce85 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -216,7 +216,7 @@ module ActiveRecord
if operation == "count"
column_name ||= select_for_count
if column_name == :all
- if distinct && !(has_limit_or_offset? && order_values.any?)
+ if distinct && (group_values.any? || !(has_limit_or_offset? && order_values.any?))
column_name = primary_key
end
elsif column_name =~ /\s*DISTINCT[\s(]+/i
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index b47fd0af41..66bc14b5ab 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -260,6 +260,10 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 3, Account.joins(:firm).distinct.order(:firm_id).limit(3).offset(2).count
end
+ def test_distinct_count_with_group_by_and_order_and_limit
+ assert_equal({ 6 => 2 }, Account.group(:firm_id).distinct.order("1 DESC").limit(1).count)
+ end
+
def test_should_group_by_summed_field_having_condition
c = Account.group(:firm_id).having("sum(credit_limit) > 50").sum(:credit_limit)
assert_nil c[1]