aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-09-23 13:07:48 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2010-09-23 13:38:56 -0700
commit9e9e5906754abfb168faba7d265719b5e613624f (patch)
tree7fc38375a38048a211cfdf19c41afeb9d136432b
parentaa4c957fa1a0f9ec26727800b80316c991b4a1d6 (diff)
downloadrails-9e9e5906754abfb168faba7d265719b5e613624f.tar.gz
rails-9e9e5906754abfb168faba7d265719b5e613624f.tar.bz2
rails-9e9e5906754abfb168faba7d265719b5e613624f.zip
adding a select statment visitor
-rw-r--r--lib/arel/nodes/select_statement.rb3
-rw-r--r--lib/arel/visitors/postgresql.rb27
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/arel/nodes/select_statement.rb b/lib/arel/nodes/select_statement.rb
index 637ba5d1d0..371fd7bf21 100644
--- a/lib/arel/nodes/select_statement.rb
+++ b/lib/arel/nodes/select_statement.rb
@@ -14,7 +14,8 @@ module Arel
def initialize_copy other
super
- @cores = @cores.map { |x| x.clone }
+ @cores = @cores.map { |x| x.clone }
+ @orders = @orders.map { |x| x.clone }
end
end
end
diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb
index 93535f4488..5f0b23a11e 100644
--- a/lib/arel/visitors/postgresql.rb
+++ b/lib/arel/visitors/postgresql.rb
@@ -1,6 +1,33 @@
module Arel
module Visitors
class PostgreSQL < Arel::Visitors::ToSql
+ private
+ def visit_Arel_Nodes_SelectStatement o
+ if !o.orders.empty? && using_distinct_on?(o)
+ subquery = o.dup
+ subquery.orders = []
+ subquery.limit = nil
+ subquery.offset = nil
+
+ sql = super(subquery)
+ [
+ "SELECT * FROM (#{sql}) AS id_list",
+ "ORDER BY #{o.orders.map { |x| visit x }.join(', ')}",
+ ("LIMIT #{o.limit}" if o.limit),
+ (visit(o.offset) if o.offset),
+ ].compact.join ' '
+ else
+ super
+ end
+ end
+
+ def using_distinct_on?(o)
+ o.cores.any? do |core|
+ core.projections.any? do |projection|
+ /DISTINCT ON/ === projection
+ end
+ end
+ end
end
end
end