Permalink
Browse files

Fixed PostgreSQL bug with group by clause

  • Loading branch information...
1 parent 8ad9091 commit d8010372bcfc20b4d9731ad9d89919a6d167f191 @binarylogic committed Sep 28, 2008
Showing with 33 additions and 9 deletions.
  1. +1 −0 CHANGELOG.rdoc
  2. +1 −1 README.rdoc
  3. +17 −0 lib/searchgasm/config.rb
  4. +13 −7 lib/searchgasm/search/base.rb
  5. +1 −1 test/test_search_base.rb
View
@@ -4,6 +4,7 @@
* False is a meaningful value for some conditions, and false.blank? == true. So instead of using value.blank? to ignore conditions we use meaningless?(value), which returns false if it is false.
* Fixed aliases for lt, lte, gt, and gte.
* Fixed bug when writing conditions on associations via a hash with string keys
+* Fixed bug in PostgreSQL where group by causes an error. Switched to DISTINCT instead.
== 1.2.1 released 2008-09-25
View
@@ -345,7 +345,7 @@ What that rule means is that any options you pass when searching get "sanitized"
Author: {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com]
-Credit to {Zack Ham}[http://github.com/zackham] and {Robert Malko}[http://github.com/malkomalko/] for helping with feature suggestions.
+Credit to {Zack Ham}[http://github.com/zackham] for helping with feature suggestions.
Copyright (c) 2008 {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com], released under the MIT license
View
@@ -153,6 +153,23 @@ def per_page_choices # :nodoc:
def per_page_choices=(value)
@per_page_choices = value
end
+
+ def remove_duplicates # :nodoc:
+ @remove_duplicates = true unless @set_remove_duplicates
+ @remove_duplicates
+ end
+
+ def remove_duplicates? # :nodoc:
+ remove_duplicates == true
+ end
+
+ # Searchgasm removes all duplicates results in *ALL* search / calculation queries. It does this by forcing the DISTINCT operation in your SQL. ActiveRecord does this if you provide the :include option, but
+ # does not do this if you provide the :joins option. This is as expected because if you are using the joins you should know what you are doing. :joins are MUCH faster than the alternative :include. So to get
+ # the best of both world Searchgasm forces the DISTINCT option. If this comes as a surprise to you and don't want Searchgasm to do this, just set this to false.
+ def remove_duplicates=(value)
+ @set_remove_duplicates = true
+ @remove_duplicates = value
+ end
end
end
end
@@ -112,13 +112,19 @@ def sanitize(searching = true)
next if value.blank?
find_options[find_option] = value
end
-
- unless find_options[:joins].blank?
- # The following is to return uniq records since we are using joins instead of includes
- if searching
- find_options[:group] ||= "#{quote_table_name(klass.table_name)}.#{quote_column_name(klass.primary_key)}"
- else
- find_options[:distinct] = true
+
+ if Config.remove_duplicates?
+ unless find_options[:joins].blank?
+ # The following is to return uniq records since we are using joins instead of includes
+ if searching
+ if !find_options[:select] || !find_options[:select] =~ /DISTINCT/i
+ select = find_options[:select] ? find_options[:select] : "*"
+ select = "#{quote_table_name(klass.table_name)}.#{select}" unless select.include?(".")
+ find_options[:select] = "DISTINCT #{select}"
+ end
+ else
+ find_options[:distinct] = true
+ end
end
end
View
@@ -140,7 +140,7 @@ def test_sanitize
search.conditions.users.id_greater_than = 2
search.page = 3
search.readonly = true
- assert_equal({:joins => :users, :group => "\"accounts\".\"id\"", :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize)
+ assert_equal({:joins => :users, :select=>"DISTINCT \"accounts\".*", :offset => 4, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }, search.sanitize)
end
def test_scope

0 comments on commit d801037

Please sign in to comment.