aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-01-12 05:14:55 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-01-12 05:14:55 +0000
commitef4ac31de3f310c6426a6d9ebc86b4810ac6325b (patch)
tree6bc6dc2072ad82162968ce699ba80d0cbf2fc4ae /activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
parent3b6555acd4516167f5ca094eeae50bf5ffc59db9 (diff)
downloadrails-ef4ac31de3f310c6426a6d9ebc86b4810ac6325b.tar.gz
rails-ef4ac31de3f310c6426a6d9ebc86b4810ac6325b.tar.bz2
rails-ef4ac31de3f310c6426a6d9ebc86b4810ac6325b.zip
PostgreSQL: use a subselect to correctly perform eager finds with :limit and :order. Closes #4668.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5887 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb20
1 files changed, 16 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index c0efd1a341..5ef117a749 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -383,17 +383,29 @@ module ActiveRecord
# construct a clean list of column names from the ORDER BY clause, removing
# any asc/desc modifiers
- order_columns = order_by.split(',').collect! { |s| s.split.first }
+ order_columns = order_by.split(',').collect { |s| s.split.first }
order_columns.delete_if &:blank?
-
- # add the DISTINCT columns to the start of the ORDER BY clause
- order_by.replace "#{columns}, #{order_by}"
+ order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
# return a DISTINCT ON() clause that's distinct on the columns we want but includes
# all the required columns for the ORDER BY to work properly
sql = "DISTINCT ON (#{columns}) #{columns}, "
sql << order_columns * ', '
end
+
+ # ORDER BY clause for the passed order option.
+ #
+ # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
+ # by wrapping the sql as a sub-select and ordering in that query.
+ def add_order_by_for_association_limiting!(sql, options)
+ return sql if options[:order].blank?
+
+ order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
+ order.map! { |s| 'DESC' if s =~ /\bdesc$/i }
+ order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')
+
+ sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
+ end
private
BYTEA_COLUMN_TYPE_OID = 17