提交 ebc09ed9 编写于 作者: R Ryuta Kamizono

Fix `count(:all)` with eager loading and having an order other than the driving table

This is a regression caused by 6beb4de7.

In PostgreSQL, ORDER BY expressions must appear in SELECT list when
using DISTINCT.

When using `count(:all)` with eager loading, Active Record enforces
DISTINCT to count the driving table records only. 6beb4de7 was caused the
regression because `count(:all)` with DISTINCT path no longer removes
ORDER BY.

We need to ignore ORDER BY when DISTINCT is enforced, otherwise not
always generated valid SQL for PostgreSQL.

Fixes #31783.
上级 8223408c
* Fix `count(:all)` with eager loading and having an order other than the driving table.
Fixes #31783.
*Ryuta Kamizono*
* Clear the transaction state when an Active Record object is duped.
Fixes #31670.
......
......@@ -131,7 +131,14 @@ def sum(column_name = nil)
def calculate(operation, column_name)
if has_include?(column_name)
relation = apply_join_dependency
relation.distinct! if operation.to_s.downcase == "count"
if operation.to_s.downcase == "count" && !distinct_value
relation.distinct!
# PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
if (column_name == :all || column_name.nil?) && select_values.empty?
relation.order_values = []
end
end
relation.calculate(operation, column_name)
else
......
......@@ -21,7 +21,7 @@
require "models/rating"
class CalculationsTest < ActiveRecord::TestCase
fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books
fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books, :posts, :comments
def test_should_sum_field
assert_equal 318, Account.sum(:credit_limit)
......@@ -236,6 +236,12 @@ def test_apply_distinct_in_count
end
end
def test_count_with_eager_loading_and_custom_order
posts = Post.includes(:comments).order("comments.id")
assert_queries(1) { assert_equal 11, posts.count }
assert_queries(1) { assert_equal 11, posts.count(:all) }
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) }
......
......@@ -969,6 +969,12 @@ def test_size_with_distinct
assert_queries(1) { assert_equal 8, posts.load.size }
end
def test_size_with_eager_loading_and_custom_order
posts = Post.includes(:comments).order("comments.id")
assert_queries(1) { assert_equal 11, posts.size }
assert_queries(1) { assert_equal 11, posts.load.size }
end
def test_update_all_with_scope
tag = Tag.first
Post.tagged_with(tag.id).update_all title: "rofl"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册