aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2010-02-16 10:08:27 -0300
committerEmilio Tagua <miloops@gmail.com>2010-02-16 10:08:27 -0300
commitbfc8bdf667cf22395938c206f44ab089b4873347 (patch)
treeac43739476b102efed4649087cc8c955f1d830e4 /lib
parent6e9cf0cb4390f1d210edbecc660290aaea6b4d72 (diff)
downloadrails-bfc8bdf667cf22395938c206f44ab089b4873347.tar.gz
rails-bfc8bdf667cf22395938c206f44ab089b4873347.tar.bz2
rails-bfc8bdf667cf22395938c206f44ab089b4873347.zip
Move using_distinct_on? to PostgreSQL compiler. Extract order tweaking
to a new method.
Diffstat (limited to 'lib')
-rw-r--r--lib/arel/engines/sql/compilers/postgresql_compiler.rb17
-rw-r--r--lib/arel/engines/sql/relations/compiler.rb4
2 files changed, 12 insertions, 9 deletions
diff --git a/lib/arel/engines/sql/compilers/postgresql_compiler.rb b/lib/arel/engines/sql/compilers/postgresql_compiler.rb
index c3360b53a5..809485bb4d 100644
--- a/lib/arel/engines/sql/compilers/postgresql_compiler.rb
+++ b/lib/arel/engines/sql/compilers/postgresql_compiler.rb
@@ -4,10 +4,6 @@ module Arel
def select_sql
if !orders.blank? && using_distinct_on?
- # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
- # by wrapping the +sql+ string as a sub-select and ordering in that query.
- order = order_clauses.join(', ').split(',').map { |s| s.strip }.reject(&:blank?)
- order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{'DESC' if s =~ /\bdesc$/i}" }.join(', ')
query = build_query \
"SELECT #{select_clauses.kind_of?(::Array) ? select_clauses.join("") : select_clauses.to_s}",
@@ -20,7 +16,7 @@ module Arel
build_query \
"SELECT * FROM (#{query}) AS id_list",
- "ORDER BY #{order}",
+ "ORDER BY #{aliased_orders(order_clauses)}",
("LIMIT #{taken}" unless taken.blank? ),
("OFFSET #{skipped}" unless skipped.blank? )
@@ -28,6 +24,17 @@ module Arel
super
end
end
+
+ def using_distinct_on?
+ select_clauses.any? { |x| x =~ /DISTINCT ON/ }
+ end
+
+ def aliased_orders(orders)
+ # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
+ # by wrapping the +sql+ string as a sub-select and ordering in that query.
+ order = orders.join(', ').split(/,/).map { |s| s.strip }.reject(&:blank?)
+ order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{'DESC' if s =~ /\bdesc$/i}" }.join(', ')
+ end
end
end
end
diff --git a/lib/arel/engines/sql/relations/compiler.rb b/lib/arel/engines/sql/relations/compiler.rb
index 6026fc126f..b85d227705 100644
--- a/lib/arel/engines/sql/relations/compiler.rb
+++ b/lib/arel/engines/sql/relations/compiler.rb
@@ -53,10 +53,6 @@ module Arel
def order_clauses
orders.collect { |o| o.to_sql(Sql::OrderClause.new(relation)) }
end
-
- def using_distinct_on?
- select_clauses.any? { |x| x =~ /DISTINCT ON/ }
- end
end
end