From c6cd9a59f200863ccfe8ad1d9c5a8876c39b9c5c Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Wed, 20 Dec 2017 05:09:49 +0900 Subject: Fix `count(:all)` to correctly work `distinct` with custom SELECT list Currently `count(:all)` with `distinct` doesn't work correctly because SELECT list is always replaced to `*` or primary key in that case even if having custom SELECT list. And also, PostgreSQL has a limitation that ORDER BY expressions must appear in select list for SELECT DISTINCT. Therefore, we should not replace custom SELECT list when using `count(:all)` with `distinct`. Closes #31277. --- activerecord/test/cases/calculations_test.rb | 6 ++++++ activerecord/test/cases/relations_test.rb | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 55b50e4f84..5eda39a0c7 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -236,6 +236,12 @@ class CalculationsTest < ActiveRecord::TestCase end end + def test_distinct_count_all_with_custom_select_and_order + accounts = Account.distinct.select("credit_limit % 10").order(Arel.sql("credit_limit % 10")) + assert_queries(1) { assert_equal 3, accounts.count(:all) } + assert_queries(1) { assert_equal 3, accounts.load.size } + end + def test_distinct_count_with_order_and_limit assert_equal 4, Account.distinct.order(:firm_id).limit(4).count end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 474f8c3da7..7785f8c99b 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -963,6 +963,12 @@ class RelationTest < ActiveRecord::TestCase assert_equal 11, posts.distinct(false).select(:comments_count).count end + def test_size_with_distinct + posts = Post.distinct.select(:author_id, :comments_count) + assert_queries(1) { assert_equal 8, posts.size } + assert_queries(1) { assert_equal 8, posts.load.size } + end + def test_update_all_with_scope tag = Tag.first Post.tagged_with(tag.id).update_all title: "rofl" -- cgit v1.2.3