aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/arel/visitors/oracle.rb15
-rw-r--r--test/visitors/test_oracle.rb16
2 files changed, 28 insertions, 3 deletions
diff --git a/lib/arel/visitors/oracle.rb b/lib/arel/visitors/oracle.rb
index 875b0e5b6a..4c79c4b038 100644
--- a/lib/arel/visitors/oracle.rb
+++ b/lib/arel/visitors/oracle.rb
@@ -26,11 +26,22 @@ module Arel
FROM ("
collector = super(o, collector)
- collector << ") raw_sql_
+
+ if offset.expr.is_a? Nodes::BindParam
+ offset_bind = nil
+ collector << ') raw_sql_ WHERE rownum <= ('
+ collector.add_bind(offset.expr) { |i| offset_bind = ":a#{i}" }
+ collector << ' + '
+ collector.add_bind(limit) { |i| ":a#{i}" }
+ collector << ") ) WHERE raw_rnum_ > #{offset_bind}"
+ return collector
+ else
+ collector << ") raw_sql_
WHERE rownum <= #{offset.expr.to_i + limit}
)
WHERE "
- return visit(offset, collector)
+ return visit(offset, collector)
+ end
end
if o.limit
diff --git a/test/visitors/test_oracle.rb b/test/visitors/test_oracle.rb
index e9ed9d76b3..4c22be5cbb 100644
--- a/test/visitors/test_oracle.rb
+++ b/test/visitors/test_oracle.rb
@@ -124,6 +124,21 @@ module Arel
}
end
+ it 'creates a subquery when there is limit and offset with BindParams' do
+ stmt = Nodes::SelectStatement.new
+ stmt.limit = Nodes::Limit.new(Nodes::BindParam.new)
+ stmt.offset = Nodes::Offset.new(Nodes::BindParam.new)
+ sql = compile stmt
+ sql.must_be_like %{
+ SELECT * FROM (
+ SELECT raw_sql_.*, rownum raw_rnum_
+ FROM (SELECT ) raw_sql_
+ WHERE rownum <= (:a1 + :a2)
+ )
+ WHERE raw_rnum_ > :a1
+ }
+ end
+
it 'is idempotent with different subquery' do
stmt = Nodes::SelectStatement.new
stmt.limit = Nodes::Limit.new(10)
@@ -148,7 +163,6 @@ module Arel
}
end
end
-
end
it 'modified except to be minus' do