aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-07-14 10:19:28 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2015-07-14 10:19:28 -0700
commit935796f4fd7d75950db87156d6540028a9044fdf (patch)
tree6b762a2ee2bbef21c58c696f25acd83de0381662 /lib/arel
parent76694a9b9994428838a81746a37e26f698aa4c67 (diff)
parent0e1427e917a4e47dce9f02ad9309600073622c73 (diff)
downloadrails-935796f4fd7d75950db87156d6540028a9044fdf.tar.gz
rails-935796f4fd7d75950db87156d6540028a9044fdf.tar.bz2
rails-935796f4fd7d75950db87156d6540028a9044fdf.zip
Merge pull request #337 from yahonda/support_oracle12_top_n_2
Support Oracle 12c top-N query
Diffstat (limited to 'lib/arel')
-rw-r--r--lib/arel/visitors.rb1
-rw-r--r--lib/arel/visitors/oracle12.rb53
-rw-r--r--lib/arel/visitors/to_sql.rb8
3 files changed, 60 insertions, 2 deletions
diff --git a/lib/arel/visitors.rb b/lib/arel/visitors.rb
index 4a8d254ba7..f492ca2d9d 100644
--- a/lib/arel/visitors.rb
+++ b/lib/arel/visitors.rb
@@ -6,6 +6,7 @@ require 'arel/visitors/postgresql'
require 'arel/visitors/mysql'
require 'arel/visitors/mssql'
require 'arel/visitors/oracle'
+require 'arel/visitors/oracle12'
require 'arel/visitors/where_sql'
require 'arel/visitors/dot'
require 'arel/visitors/ibm_db'
diff --git a/lib/arel/visitors/oracle12.rb b/lib/arel/visitors/oracle12.rb
new file mode 100644
index 0000000000..4a42343c9b
--- /dev/null
+++ b/lib/arel/visitors/oracle12.rb
@@ -0,0 +1,53 @@
+module Arel
+ module Visitors
+ class Oracle12 < Arel::Visitors::ToSql
+ private
+
+ def visit_Arel_Nodes_SelectStatement o, collector
+ # Oracle does not allow LIMIT clause with select for update
+ if o.limit && o.lock
+ o = o.dup
+ o.limit = []
+ end
+
+ super
+ end
+
+ def visit_Arel_Nodes_SelectOptions o, collector
+ collector = maybe_visit o.offset, collector
+ collector = maybe_visit o.limit, collector
+ collector = maybe_visit o.lock, collector
+ end
+
+ def visit_Arel_Nodes_Limit o, collector
+ collector << "FETCH FIRST "
+ collector = visit o.expr, collector
+ collector << " ROWS ONLY"
+ end
+
+ def visit_Arel_Nodes_Offset o, collector
+ collector << "OFFSET "
+ visit o.expr, collector
+ collector << " ROWS"
+ end
+
+ def visit_Arel_Nodes_Except o, collector
+ collector << "( "
+ collector = infix_value o, collector, " MINUS "
+ collector << " )"
+ end
+
+ def visit_Arel_Nodes_UpdateStatement o, collector
+ # Oracle does not allow ORDER BY/LIMIT in UPDATEs.
+ if o.orders.any? && o.limit.nil?
+ # However, there is no harm in silently eating the ORDER BY clause if no LIMIT has been provided,
+ # otherwise let the user deal with the error
+ o = o.dup
+ o.orders = []
+ end
+
+ super
+ end
+ end
+ end
+end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 6f72fdfb0e..f2f9d20f21 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -219,11 +219,15 @@ module Arel
}
end
+ visit_Arel_Nodes_SelectOptions(o, collector)
+
+ collector
+ end
+
+ def visit_Arel_Nodes_SelectOptions o, collector
collector = maybe_visit o.limit, collector
collector = maybe_visit o.offset, collector
collector = maybe_visit o.lock, collector
-
- collector
end
def visit_Arel_Nodes_SelectCore o, collector