diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-01-09 21:08:04 +0900 |
---|---|---|
committer | Jeremy Daer <jeremydaer@gmail.com> | 2017-02-25 19:10:33 -0700 |
commit | d38e5d2719ad8f236d3bd30c60a113d8087db43e (patch) | |
tree | 35b4adda7486c32f9a3206bd1069740c31736496 | |
parent | 558336ee2afad116077df07b5b963077ac5f5021 (diff) | |
download | rails-d38e5d2719ad8f236d3bd30c60a113d8087db43e.tar.gz rails-d38e5d2719ad8f236d3bd30c60a113d8087db43e.tar.bz2 rails-d38e5d2719ad8f236d3bd30c60a113d8087db43e.zip |
Suppress `DISTINCT` clause outside aggregate function
`DISTINCT` clause is applied inside aggregate function by
`operation_over_aggregate_column` if needed. Unneeded outside aggregate
function.
```ruby
# Before
author.unique_categorized_posts.count
# => SELECT DISTINCT COUNT(DISTINCT "posts"."id") FROM "posts" INNER JOIN "categorizations" ON "posts"."id" = "categorizations"."post_id" WHERE "categorizations"."author_id" = ? [["author_id", 2]]
# After
author.unique_categorized_posts.count
# => SELECT COUNT(DISTINCT "posts"."id") FROM "posts" INNER JOIN "categorizations" ON "posts"."id" = "categorizations"."post_id" WHERE "categorizations"."author_id" = ? [["author_id", 2]]
```
Closes #27615
-rw-r--r-- | activerecord/lib/active_record/relation/calculations.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/calculations_test.rb | 11 |
2 files changed, 13 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 35c670f1a1..b3168772e1 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -232,7 +232,7 @@ module ActiveRecord query_builder = build_count_subquery(spawn, column_name, distinct) else # PostgreSQL doesn't like ORDER BY when there are no GROUP BY - relation = unscope(:order) + relation = unscope(:order).distinct!(false) column = aggregate_column(column_name) @@ -292,7 +292,7 @@ module ActiveRecord end } - relation = except(:group) + relation = except(:group).distinct!(false) relation.group_values = group_fields relation.select_values = select_values diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 1813534b62..acea955021 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -227,6 +227,17 @@ class CalculationsTest < ActiveRecord::TestCase assert_match "credit_limit, firm_name", e.message end + def test_apply_distinct_in_count + queries = assert_sql do + Account.distinct.count + Account.group(:firm_id).distinct.count + end + + queries.each do |query| + assert_match %r{\ASELECT(?! DISTINCT) COUNT\(DISTINCT\b}, query + end + 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] |