From f381da2738ec8c2aac3c34fead32688ea7b08d74 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 24 Sep 2010 11:17:17 -0700 Subject: [PATCH] adding more oracle hacks --- lib/arel/visitors/oracle.rb | 19 +++++++++++++++++++ spec/arel/visitors/oracle_spec.rb | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/arel/visitors/oracle.rb b/lib/arel/visitors/oracle.rb index c3af68cc36..46a3ad4c78 100644 --- a/lib/arel/visitors/oracle.rb +++ b/lib/arel/visitors/oracle.rb @@ -4,6 +4,8 @@ class Oracle < Arel::Visitors::ToSql private def visit_Arel_Nodes_SelectStatement o + order_hacks(o) + if o.limit && o.orders.empty? && !o.offset o.cores.last.wheres.push Nodes::LessThanOrEqual.new( Nodes::SqlLiteral.new('ROWNUM'), o.limit @@ -40,6 +42,23 @@ def visit_Arel_Nodes_SelectStatement o def visit_Arel_Nodes_Offset o "raw_rnum_ > #{visit o.value}" end + + ### + # Hacks for the order clauses specific to Oracle + def order_hacks o + return if o.orders.empty? + return unless o.cores.any? do |core| + core.projections.any? do |projection| + /DISTINCT.*FIRST_VALUE/ === projection + end + end + orders = o.orders + o.orders = [] + orders.each_with_index do |order, i| + o.orders << + Nodes::SqlLiteral.new("alias_#{i}__ #{'DESC' if /\bdesc$/i === order}") + end + end end end end diff --git a/spec/arel/visitors/oracle_spec.rb b/spec/arel/visitors/oracle_spec.rb index 07ac352893..0995ea6bf2 100644 --- a/spec/arel/visitors/oracle_spec.rb +++ b/spec/arel/visitors/oracle_spec.rb @@ -7,6 +7,18 @@ module Visitors @visitor = Oracle.new Table.engine end + it 'modifies order when there is distinct and first value' do + # *sigh* + select = "DISTINCT foo.id, FIRST_VALUE(projects.name) OVER (foo) AS alias_0__" + stmt = Nodes::SelectStatement.new + stmt.cores.first.projections << Nodes::SqlLiteral.new(select) + stmt.orders << Nodes::SqlLiteral.new('foo') + sql = @visitor.accept(stmt) + sql.should be_like %{ + SELECT #{select} ORDER BY alias_0__ + } + end + describe 'Nodes::SelectStatement' do describe 'limit' do it 'adds a rownum clause' do -- GitLab