diff options
Diffstat (limited to 'lib/arel/visitors/postgresql.rb')
-rw-r--r-- | lib/arel/visitors/postgresql.rb | 27 |
1 files changed, 27 insertions, 0 deletions
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 |