mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #35361 from jvillarejo/fix_wrong_size_query_with_distinct_select
Fix different `count` calculation when using `size` with DISTINCT `select`
This commit is contained in:
commit
350ad01b81
4 changed files with 40 additions and 3 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
* Fix different `count` calculation when using `size` with manual `select` with DISTINCT.
|
||||||
|
|
||||||
|
Fixes #35214.
|
||||||
|
|
||||||
|
*Juani Villarejo*
|
||||||
|
|
||||||
|
|
||||||
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
||||||
|
|
||||||
* Fix prepared statements caching to be enabled even when query caching is enabled.
|
* Fix prepared statements caching to be enabled even when query caching is enabled.
|
||||||
|
|
|
@ -221,7 +221,6 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def has_include?(column_name)
|
def has_include?(column_name)
|
||||||
eager_loading? || (includes_values.present? && column_name && column_name != :all)
|
eager_loading? || (includes_values.present? && column_name && column_name != :all)
|
||||||
end
|
end
|
||||||
|
@ -236,10 +235,12 @@ module ActiveRecord
|
||||||
if operation == "count"
|
if operation == "count"
|
||||||
column_name ||= select_for_count
|
column_name ||= select_for_count
|
||||||
if column_name == :all
|
if column_name == :all
|
||||||
if distinct && (group_values.any? || select_values.empty? && order_values.empty?)
|
if !distinct
|
||||||
|
distinct = distinct_select?(select_for_count) if group_values.empty?
|
||||||
|
elsif group_values.any? || select_values.empty? && order_values.empty?
|
||||||
column_name = primary_key
|
column_name = primary_key
|
||||||
end
|
end
|
||||||
elsif column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
|
elsif distinct_select?(column_name)
|
||||||
distinct = nil
|
distinct = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -251,6 +252,10 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def distinct_select?(column_name)
|
||||||
|
column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
|
||||||
|
end
|
||||||
|
|
||||||
def aggregate_column(column_name)
|
def aggregate_column(column_name)
|
||||||
return column_name if Arel::Expressions === column_name
|
return column_name if Arel::Expressions === column_name
|
||||||
|
|
||||||
|
|
|
@ -473,6 +473,24 @@ class CalculationsTest < ActiveRecord::TestCase
|
||||||
assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
|
assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_should_count_manual_select_with_count_all
|
||||||
|
assert_equal 5, Account.select("DISTINCT accounts.firm_id").count(:all)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_count_with_manual_distinct_select_and_distinct
|
||||||
|
assert_equal 4, Account.select("DISTINCT accounts.firm_id").distinct(true).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_count_manual_select_with_group_with_count_all
|
||||||
|
expected = { nil => 1, 1 => 1, 2 => 1, 6 => 2, 9 => 1 }
|
||||||
|
actual = Account.select("DISTINCT accounts.firm_id").group("accounts.firm_id").count(:all)
|
||||||
|
assert_equal expected, actual
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_count_manual_with_count_all
|
||||||
|
assert_equal 6, Account.count(:all)
|
||||||
|
end
|
||||||
|
|
||||||
def test_count_selected_arel_attribute
|
def test_count_selected_arel_attribute
|
||||||
assert_equal 5, Account.select(Account.arel_table[:firm_id]).count
|
assert_equal 5, Account.select(Account.arel_table[:firm_id]).count
|
||||||
assert_equal 4, Account.distinct.select(Account.arel_table[:firm_id]).count
|
assert_equal 4, Account.distinct.select(Account.arel_table[:firm_id]).count
|
||||||
|
|
|
@ -972,6 +972,13 @@ class RelationTest < ActiveRecord::TestCase
|
||||||
assert_queries(1) { assert_equal 11, posts.load.size }
|
assert_queries(1) { assert_equal 11, posts.load.size }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_size_with_eager_loading_and_manual_distinct_select_and_custom_order
|
||||||
|
accounts = Account.select("DISTINCT accounts.firm_id").order("accounts.firm_id")
|
||||||
|
|
||||||
|
assert_queries(1) { assert_equal 5, accounts.size }
|
||||||
|
assert_queries(1) { assert_equal 5, accounts.load.size }
|
||||||
|
end
|
||||||
|
|
||||||
def test_count_explicit_columns
|
def test_count_explicit_columns
|
||||||
Post.update_all(comments_count: nil)
|
Post.update_all(comments_count: nil)
|
||||||
posts = Post.all
|
posts = Post.all
|
||||||
|
|
Loading…
Reference in a new issue