Permalink
Browse files

Don't preserve SELECT columns on COUNT

The COUNT clause of a finder_sql relationship is being rewritten from
COUNT(*) to COUNT(table_name.*). This does not appear to be valid syntax
in MySQL:

```
mysql> SELECT COUNT( table_name.* ) FROM `table_name`;
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near '* ) FROM `table_name`' at line 1
```

This Fixes the bug, as well as adding tests so we don't re-introduce
it in the future.

Fixes #3956.
  • Loading branch information...
1 parent 60c88e6 commit 812099f1fbb5ca96f127f312341ca89669c2f533 @steveklabnik committed Sep 15, 2012
@@ -373,7 +373,7 @@ def custom_counter_sql
# replace the SELECT clause with COUNT(SELECTS), preserving any hints within /* ... */
interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) do
count_with = $2.to_s
- count_with = '*' if count_with.blank? || count_with =~ /,/
+ count_with = '*' if count_with.blank? || count_with =~ /,/ || count_with =~ /\.*/
"SELECT #{$1}COUNT(#{count_with}) FROM"
end
end
@@ -46,20 +46,53 @@ def test_should_fail
end
end
-class HasManyAssociationsTestForCountDistinctWithFinderSql < ActiveRecord::TestCase
+class HasManyAssociationsTestForCountWithFinderSql < ActiveRecord::TestCase
class Invoice < ActiveRecord::Base
ActiveSupport::Deprecation.silence do
has_many :custom_line_items, :class_name => 'LineItem', :finder_sql => "SELECT DISTINCT line_items.amount from line_items"
+ has_many :custom_full_line_items, :class_name => 'LineItem', :finder_sql => "SELECT line_items.invoice_id, line_items.amount from line_items"
+ has_many :custom_star_line_items, :class_name => 'LineItem', :finder_sql => "SELECT * from line_items"
+ has_many :custom_qualified_star_line_items, :class_name => 'LineItem', :finder_sql => "SELECT line_items.* from line_items"
end
end
def test_should_count_distinct_results
+ return unless current_adapter?(:MysqlAdapter, :Mysql2Adapter)
+
invoice = Invoice.new
invoice.custom_line_items << LineItem.new(:amount => 0)
invoice.custom_line_items << LineItem.new(:amount => 0)
+
+ assert_nothing_raised(Exception) do
+ invoice.save!
+ end
+ end
+
+ def test_should_count_results_with_multiple_fields
+ invoice = Invoice.new
+ invoice.custom_full_line_items << LineItem.new(:amount => 0)
+ invoice.custom_full_line_items << LineItem.new(:amount => 0)
+ invoice.save!
+
+ assert_equal 2, invoice.custom_full_line_items.count
+ end
+
+ def test_should_count_results_with_star
+ invoice = Invoice.new
+ invoice.custom_star_line_items << LineItem.new(:amount => 0)
+ invoice.custom_star_line_items << LineItem.new(:amount => 0)
+ invoice.save!
+
+ assert_equal 2, invoice.custom_star_line_items.count
+ end
+
+ def test_should_count_results_with_qualified_star
+ invoice = Invoice.new
+ invoice.custom_qualified_star_line_items << LineItem.new(:amount => 0)
+ invoice.custom_qualified_star_line_items << LineItem.new(:amount => 0)
invoice.save!
- assert_equal 1, invoice.custom_line_items.count
+ assert_equal 2, invoice.custom_qualified_star_line_items.count
end
end

0 comments on commit 812099f

Please sign in to comment.