2010-10-18 19:54:50 -04:00
|
|
|
require 'helper'
|
2010-09-24 12:41:48 -04:00
|
|
|
|
|
|
|
module Arel
|
|
|
|
module Visitors
|
|
|
|
describe 'the oracle visitor' do
|
|
|
|
before do
|
|
|
|
@visitor = Oracle.new Table.engine
|
|
|
|
end
|
|
|
|
|
2010-09-24 14:17:17 -04:00
|
|
|
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)
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{
|
2010-09-24 14:17:17 -04:00
|
|
|
SELECT #{select} ORDER BY alias_0__
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2010-09-24 16:56:37 -04:00
|
|
|
it 'is idempotent with crazy query' 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)
|
|
|
|
sql2 = @visitor.accept(stmt)
|
2010-10-18 19:36:49 -04:00
|
|
|
sql.must_equal sql2
|
2010-09-24 16:56:37 -04:00
|
|
|
end
|
|
|
|
|
2010-09-24 18:09:26 -04:00
|
|
|
it 'splits orders with commas' 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, bar')
|
|
|
|
sql = @visitor.accept(stmt)
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{
|
2010-09-24 18:09:26 -04:00
|
|
|
SELECT #{select} ORDER BY alias_0__, alias_1__
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2010-11-16 05:45:29 -05:00
|
|
|
it 'splits orders with commas and function calls' 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('NVL(LOWER(bar, foo), foo) DESC, UPPER(baz)')
|
|
|
|
sql = @visitor.accept(stmt)
|
|
|
|
sql.must_be_like %{
|
|
|
|
SELECT #{select} ORDER BY alias_0__ DESC, alias_1__
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2010-09-24 12:41:48 -04:00
|
|
|
describe 'Nodes::SelectStatement' do
|
|
|
|
describe 'limit' do
|
|
|
|
it 'adds a rownum clause' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.limit = 10
|
|
|
|
sql = @visitor.accept stmt
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{ SELECT WHERE ROWNUM <= 10 }
|
2010-09-24 12:41:48 -04:00
|
|
|
end
|
2010-09-24 13:09:21 -04:00
|
|
|
|
2010-09-24 16:56:37 -04:00
|
|
|
it 'is idempotent' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
|
|
|
stmt.limit = 10
|
|
|
|
sql = @visitor.accept stmt
|
|
|
|
sql2 = @visitor.accept stmt
|
2010-10-18 19:36:49 -04:00
|
|
|
sql.must_equal sql2
|
2010-09-24 16:56:37 -04:00
|
|
|
end
|
|
|
|
|
2010-09-24 13:09:21 -04:00
|
|
|
it 'creates a subquery when there is order_by' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
|
|
|
stmt.limit = 10
|
|
|
|
sql = @visitor.accept stmt
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{
|
2010-09-24 13:09:21 -04:00
|
|
|
SELECT * FROM (SELECT ORDER BY foo) WHERE ROWNUM <= 10
|
|
|
|
}
|
|
|
|
end
|
2010-09-24 13:24:31 -04:00
|
|
|
|
2010-09-29 06:10:17 -04:00
|
|
|
it 'creates a subquery when there is DISTINCT' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.cores.first.projections << Nodes::SqlLiteral.new('DISTINCT id')
|
|
|
|
stmt.limit = 10
|
|
|
|
sql = @visitor.accept stmt
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{
|
2010-09-29 06:10:17 -04:00
|
|
|
SELECT * FROM (SELECT DISTINCT id) WHERE ROWNUM <= 10
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2010-09-24 13:24:31 -04:00
|
|
|
it 'creates a different subquery when there is an offset' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.limit = 10
|
|
|
|
stmt.offset = Nodes::Offset.new(10)
|
|
|
|
sql = @visitor.accept stmt
|
2010-10-18 18:41:21 -04:00
|
|
|
sql.must_be_like %{
|
2010-09-24 13:24:31 -04:00
|
|
|
SELECT * FROM (
|
|
|
|
SELECT raw_sql_.*, rownum raw_rnum_
|
|
|
|
FROM (SELECT ) raw_sql_
|
|
|
|
WHERE rownum <= 20
|
|
|
|
)
|
|
|
|
WHERE raw_rnum_ > 10
|
|
|
|
}
|
|
|
|
end
|
2010-09-24 16:56:37 -04:00
|
|
|
|
|
|
|
it 'is idempotent with different subquery' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.limit = 10
|
|
|
|
stmt.offset = Nodes::Offset.new(10)
|
|
|
|
sql = @visitor.accept stmt
|
|
|
|
sql2 = @visitor.accept stmt
|
2010-10-18 19:36:49 -04:00
|
|
|
sql.must_equal sql2
|
2010-09-24 16:56:37 -04:00
|
|
|
end
|
2010-09-24 12:41:48 -04:00
|
|
|
end
|
2010-10-21 04:22:48 -04:00
|
|
|
|
|
|
|
describe 'only offset' do
|
|
|
|
it 'creates a select from subquery with rownum condition' do
|
|
|
|
stmt = Nodes::SelectStatement.new
|
|
|
|
stmt.offset = Nodes::Offset.new(10)
|
|
|
|
sql = @visitor.accept stmt
|
|
|
|
sql.must_be_like %{
|
|
|
|
SELECT * FROM (
|
|
|
|
SELECT raw_sql_.*, rownum raw_rnum_
|
|
|
|
FROM (SELECT ) raw_sql_
|
|
|
|
)
|
|
|
|
WHERE raw_rnum_ > 10
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-24 12:41:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|