arel 5.0.1.20140414130214 → 6.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/History.txt +9 -4
- data/Manifest.txt +9 -7
- data/README.markdown +85 -8
- data/Rakefile +1 -1
- data/arel.gemspec +15 -16
- data/lib/arel.rb +1 -12
- data/lib/arel/collectors/bind.rb +36 -0
- data/lib/arel/collectors/plain_string.rb +18 -0
- data/lib/arel/collectors/sql_string.rb +18 -0
- data/lib/arel/factory_methods.rb +1 -1
- data/lib/arel/insert_manager.rb +5 -1
- data/lib/arel/nodes.rb +41 -0
- data/lib/arel/nodes/and.rb +1 -5
- data/lib/arel/nodes/binary.rb +2 -0
- data/lib/arel/nodes/extract.rb +0 -2
- data/lib/arel/nodes/full_outer_join.rb +6 -0
- data/lib/arel/nodes/function.rb +0 -1
- data/lib/arel/nodes/insert_statement.rb +5 -2
- data/lib/arel/nodes/node.rb +5 -1
- data/lib/arel/nodes/right_outer_join.rb +6 -0
- data/lib/arel/nodes/window.rb +23 -5
- data/lib/arel/predications.rb +41 -33
- data/lib/arel/select_manager.rb +13 -37
- data/lib/arel/table.rb +13 -9
- data/lib/arel/tree_manager.rb +8 -2
- data/lib/arel/update_manager.rb +2 -2
- data/lib/arel/visitors.rb +0 -2
- data/lib/arel/visitors/bind_substitute.rb +9 -0
- data/lib/arel/visitors/bind_visitor.rb +10 -5
- data/lib/arel/visitors/depth_first.rb +60 -57
- data/lib/arel/visitors/dot.rb +84 -80
- data/lib/arel/visitors/ibm_db.rb +4 -2
- data/lib/arel/visitors/informix.rb +39 -21
- data/lib/arel/visitors/mssql.rb +41 -23
- data/lib/arel/visitors/mysql.rb +48 -22
- data/lib/arel/visitors/oracle.rb +33 -24
- data/lib/arel/visitors/postgresql.rb +15 -8
- data/lib/arel/visitors/reduce.rb +25 -0
- data/lib/arel/visitors/sqlite.rb +3 -2
- data/lib/arel/visitors/to_sql.rb +455 -248
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel/visitors/where_sql.rb +3 -2
- data/test/attributes/test_attribute.rb +12 -3
- data/test/collectors/test_bind_collector.rb +70 -0
- data/test/collectors/test_sql_string.rb +38 -0
- data/test/helper.rb +10 -1
- data/test/nodes/test_bin.rb +2 -2
- data/test/nodes/test_count.rb +0 -6
- data/test/nodes/test_equality.rb +1 -1
- data/test/nodes/test_grouping.rb +1 -1
- data/test/nodes/test_infix_operation.rb +1 -1
- data/test/nodes/test_select_core.rb +7 -7
- data/test/nodes/test_sql_literal.rb +10 -6
- data/test/nodes/test_window.rb +9 -3
- data/test/support/fake_record.rb +16 -4
- data/test/test_factory_methods.rb +1 -1
- data/test/test_insert_manager.rb +33 -4
- data/test/test_select_manager.rb +164 -92
- data/test/test_table.rb +49 -4
- data/test/visitors/test_bind_visitor.rb +18 -10
- data/test/visitors/test_depth_first.rb +12 -0
- data/test/visitors/test_dot.rb +4 -4
- data/test/visitors/test_ibm_db.rb +11 -5
- data/test/visitors/test_informix.rb +14 -8
- data/test/visitors/test_mssql.rb +12 -8
- data/test/visitors/test_mysql.rb +17 -12
- data/test/visitors/test_oracle.rb +25 -21
- data/test/visitors/test_postgres.rb +50 -12
- data/test/visitors/test_sqlite.rb +2 -2
- data/test/visitors/test_to_sql.rb +177 -81
- metadata +24 -19
- data/lib/arel/deprecated.rb +0 -4
- data/lib/arel/expression.rb +0 -5
- data/lib/arel/sql/engine.rb +0 -10
- data/lib/arel/sql_literal.rb +0 -4
- data/lib/arel/visitors/join_sql.rb +0 -19
- data/lib/arel/visitors/order_clauses.rb +0 -11
- data/test/visitors/test_join_sql.rb +0 -42
@@ -4,8 +4,14 @@ require 'support/fake_record'
|
|
4
4
|
|
5
5
|
module Arel
|
6
6
|
module Visitors
|
7
|
-
class TestBindVisitor <
|
8
|
-
|
7
|
+
class TestBindVisitor < Arel::Test
|
8
|
+
attr_reader :collector
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@collector = Collectors::SQLString.new
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
9
15
|
##
|
10
16
|
# Tests visit_Arel_Nodes_Assignment correctly
|
11
17
|
# substitutes binds with values from block
|
@@ -19,12 +25,16 @@ module Arel
|
|
19
25
|
}.new Table.engine.connection
|
20
26
|
|
21
27
|
assignment = um.ast.values[0]
|
22
|
-
actual = visitor.accept(assignment) {
|
23
|
-
|
28
|
+
actual = visitor.accept(assignment, collector) {
|
29
|
+
"replace"
|
30
|
+
}
|
31
|
+
assert actual
|
32
|
+
value = actual.value
|
33
|
+
assert_like "\"name\" = replace", value
|
24
34
|
end
|
25
35
|
|
26
36
|
def test_visitor_yields_on_binds
|
27
|
-
visitor = Class.new(Arel::Visitors::
|
37
|
+
visitor = Class.new(Arel::Visitors::ToSql) {
|
28
38
|
def initialize omg
|
29
39
|
end
|
30
40
|
|
@@ -33,12 +43,12 @@ module Arel
|
|
33
43
|
|
34
44
|
bp = Nodes::BindParam.new 'omg'
|
35
45
|
called = false
|
36
|
-
visitor.accept(bp) { called = true }
|
46
|
+
visitor.accept(bp, collector) { called = true }
|
37
47
|
assert called
|
38
48
|
end
|
39
49
|
|
40
50
|
def test_visitor_only_yields_on_binds
|
41
|
-
visitor = Class.new(Arel::Visitors::
|
51
|
+
visitor = Class.new(Arel::Visitors::ToSql) {
|
42
52
|
def initialize omg
|
43
53
|
end
|
44
54
|
|
@@ -48,9 +58,7 @@ module Arel
|
|
48
58
|
bp = Arel.sql 'omg'
|
49
59
|
called = false
|
50
60
|
|
51
|
-
|
52
|
-
visitor.accept(bp) { called = true }
|
53
|
-
}
|
61
|
+
visitor.accept(bp, collector) { called = true }
|
54
62
|
refute called
|
55
63
|
end
|
56
64
|
end
|
@@ -81,12 +81,24 @@ module Arel
|
|
81
81
|
assert_equal [:a, :b, join], @collector.calls
|
82
82
|
end
|
83
83
|
|
84
|
+
def test_full_outer_join
|
85
|
+
join = Nodes::FullOuterJoin.new :a, :b
|
86
|
+
@visitor.accept join
|
87
|
+
assert_equal [:a, :b, join], @collector.calls
|
88
|
+
end
|
89
|
+
|
84
90
|
def test_outer_join
|
85
91
|
join = Nodes::OuterJoin.new :a, :b
|
86
92
|
@visitor.accept join
|
87
93
|
assert_equal [:a, :b, join], @collector.calls
|
88
94
|
end
|
89
95
|
|
96
|
+
def test_right_outer_join
|
97
|
+
join = Nodes::RightOuterJoin.new :a, :b
|
98
|
+
@visitor.accept join
|
99
|
+
assert_equal [:a, :b, join], @collector.calls
|
100
|
+
end
|
101
|
+
|
90
102
|
[
|
91
103
|
Arel::Nodes::Assignment,
|
92
104
|
Arel::Nodes::Between,
|
data/test/visitors/test_dot.rb
CHANGED
@@ -17,13 +17,13 @@ module Arel
|
|
17
17
|
].each do |klass|
|
18
18
|
define_method("test_#{klass.name.gsub('::', '_')}") do
|
19
19
|
op = klass.new(:a, "z")
|
20
|
-
@visitor.accept op
|
20
|
+
@visitor.accept op, Collectors::PlainString.new
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_named_function
|
25
25
|
func = Nodes::NamedFunction.new 'omg', 'omg'
|
26
|
-
@visitor.accept func
|
26
|
+
@visitor.accept func, Collectors::PlainString.new
|
27
27
|
end
|
28
28
|
|
29
29
|
# unary ops
|
@@ -41,7 +41,7 @@ module Arel
|
|
41
41
|
].each do |klass|
|
42
42
|
define_method("test_#{klass.name.gsub('::', '_')}") do
|
43
43
|
op = klass.new(:a)
|
44
|
-
@visitor.accept op
|
44
|
+
@visitor.accept op, Collectors::PlainString.new
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -68,7 +68,7 @@ module Arel
|
|
68
68
|
].each do |klass|
|
69
69
|
define_method("test_#{klass.name.gsub('::', '_')}") do
|
70
70
|
binary = klass.new(:a, :b)
|
71
|
-
@visitor.accept binary
|
71
|
+
@visitor.accept binary, Collectors::PlainString.new
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -7,19 +7,25 @@ module Arel
|
|
7
7
|
@visitor = IBM_DB.new Table.engine.connection
|
8
8
|
end
|
9
9
|
|
10
|
+
def compile node
|
11
|
+
@visitor.accept(node, Collectors::SQLString.new).value
|
12
|
+
end
|
13
|
+
|
10
14
|
it 'uses FETCH FIRST n ROWS to limit results' do
|
11
15
|
stmt = Nodes::SelectStatement.new
|
12
16
|
stmt.limit = Nodes::Limit.new(1)
|
13
|
-
sql =
|
17
|
+
sql = compile(stmt)
|
14
18
|
sql.must_be_like "SELECT FETCH FIRST 1 ROWS ONLY"
|
15
19
|
end
|
16
20
|
|
17
21
|
it 'uses FETCH FIRST n ROWS in updates with a limit' do
|
22
|
+
table = Table.new(:users)
|
18
23
|
stmt = Nodes::UpdateStatement.new
|
19
|
-
stmt.
|
20
|
-
stmt.
|
21
|
-
|
22
|
-
sql
|
24
|
+
stmt.relation = table
|
25
|
+
stmt.limit = Nodes::Limit.new(Nodes.build_quoted(1))
|
26
|
+
stmt.key = table[:id]
|
27
|
+
sql = compile(stmt)
|
28
|
+
sql.must_be_like "UPDATE \"users\" WHERE \"users\".\"id\" IN (SELECT \"users\".\"id\" FROM \"users\" FETCH FIRST 1 ROWS ONLY)"
|
23
29
|
end
|
24
30
|
|
25
31
|
end
|
@@ -7,25 +7,31 @@ module Arel
|
|
7
7
|
@visitor = Informix.new Table.engine.connection
|
8
8
|
end
|
9
9
|
|
10
|
+
def compile node
|
11
|
+
@visitor.accept(node, Collectors::SQLString.new).value
|
12
|
+
end
|
13
|
+
|
10
14
|
it 'uses LIMIT n to limit results' do
|
11
15
|
stmt = Nodes::SelectStatement.new
|
12
16
|
stmt.limit = Nodes::Limit.new(1)
|
13
|
-
sql =
|
17
|
+
sql = compile(stmt)
|
14
18
|
sql.must_be_like "SELECT LIMIT 1"
|
15
19
|
end
|
16
20
|
|
17
21
|
it 'uses LIMIT n in updates with a limit' do
|
22
|
+
table = Table.new(:users)
|
18
23
|
stmt = Nodes::UpdateStatement.new
|
19
|
-
stmt.
|
20
|
-
stmt.
|
21
|
-
|
22
|
-
sql
|
24
|
+
stmt.relation = table
|
25
|
+
stmt.limit = Nodes::Limit.new(Nodes.build_quoted(1))
|
26
|
+
stmt.key = table[:id]
|
27
|
+
sql = compile(stmt)
|
28
|
+
sql.must_be_like "UPDATE \"users\" WHERE \"users\".\"id\" IN (SELECT LIMIT 1 \"users\".\"id\" FROM \"users\")"
|
23
29
|
end
|
24
30
|
|
25
31
|
it 'uses SKIP n to jump results' do
|
26
32
|
stmt = Nodes::SelectStatement.new
|
27
33
|
stmt.offset = Nodes::Offset.new(10)
|
28
|
-
sql =
|
34
|
+
sql = compile(stmt)
|
29
35
|
sql.must_be_like "SELECT SKIP 10"
|
30
36
|
end
|
31
37
|
|
@@ -33,7 +39,7 @@ module Arel
|
|
33
39
|
stmt = Nodes::SelectStatement.new
|
34
40
|
stmt.limit = Nodes::Limit.new(1)
|
35
41
|
stmt.offset = Nodes::Offset.new(1)
|
36
|
-
sql =
|
42
|
+
sql = compile(stmt)
|
37
43
|
sql.must_be_like "SELECT SKIP 1 LIMIT 1"
|
38
44
|
end
|
39
45
|
|
@@ -43,7 +49,7 @@ module Arel
|
|
43
49
|
core.source = Nodes::JoinSource.new(table, [table.create_join(Table.new(:comments))])
|
44
50
|
|
45
51
|
stmt = Nodes::SelectStatement.new([core])
|
46
|
-
sql =
|
52
|
+
sql = compile(stmt)
|
47
53
|
sql.must_be_like 'SELECT FROM "posts" INNER JOIN "comments"'
|
48
54
|
end
|
49
55
|
|
data/test/visitors/test_mssql.rb
CHANGED
@@ -8,9 +8,13 @@ module Arel
|
|
8
8
|
@table = Arel::Table.new "users"
|
9
9
|
end
|
10
10
|
|
11
|
+
def compile node
|
12
|
+
@visitor.accept(node, Collectors::SQLString.new).value
|
13
|
+
end
|
14
|
+
|
11
15
|
it 'should not modify query if no offset or limit' do
|
12
16
|
stmt = Nodes::SelectStatement.new
|
13
|
-
sql =
|
17
|
+
sql = compile(stmt)
|
14
18
|
sql.must_be_like "SELECT"
|
15
19
|
end
|
16
20
|
|
@@ -18,15 +22,15 @@ module Arel
|
|
18
22
|
stmt = Nodes::SelectStatement.new
|
19
23
|
stmt.cores.first.from = @table
|
20
24
|
stmt.limit = Nodes::Limit.new(10)
|
21
|
-
sql =
|
22
|
-
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY \"users\".\"id\") as _row_num FROM \"users\"
|
25
|
+
sql = compile(stmt)
|
26
|
+
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY \"users\".\"id\") as _row_num FROM \"users\") as _t WHERE _row_num BETWEEN 1 AND 10"
|
23
27
|
end
|
24
28
|
|
25
29
|
it 'should go over query ORDER BY if .order()' do
|
26
30
|
stmt = Nodes::SelectStatement.new
|
27
31
|
stmt.limit = Nodes::Limit.new(10)
|
28
32
|
stmt.orders << Nodes::SqlLiteral.new('order_by')
|
29
|
-
sql =
|
33
|
+
sql = compile(stmt)
|
30
34
|
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY order_by) as _row_num) as _t WHERE _row_num BETWEEN 1 AND 10"
|
31
35
|
end
|
32
36
|
|
@@ -34,7 +38,7 @@ module Arel
|
|
34
38
|
stmt = Nodes::SelectStatement.new
|
35
39
|
stmt.cores.first.groups << Nodes::SqlLiteral.new('group_by')
|
36
40
|
stmt.limit = Nodes::Limit.new(10)
|
37
|
-
sql =
|
41
|
+
sql = compile(stmt)
|
38
42
|
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY group_by) as _row_num GROUP BY group_by) as _t WHERE _row_num BETWEEN 1 AND 10"
|
39
43
|
end
|
40
44
|
|
@@ -42,14 +46,14 @@ module Arel
|
|
42
46
|
stmt = Nodes::SelectStatement.new
|
43
47
|
stmt.limit = Nodes::Limit.new(10)
|
44
48
|
stmt.offset = Nodes::Offset.new(20)
|
45
|
-
sql =
|
49
|
+
sql = compile(stmt)
|
46
50
|
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY ) as _row_num) as _t WHERE _row_num BETWEEN 21 AND 30"
|
47
51
|
end
|
48
52
|
|
49
53
|
it 'should use >= if only .offset' do
|
50
54
|
stmt = Nodes::SelectStatement.new
|
51
55
|
stmt.offset = Nodes::Offset.new(20)
|
52
|
-
sql =
|
56
|
+
sql = compile(stmt)
|
53
57
|
sql.must_be_like "SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY ) as _row_num) as _t WHERE _row_num >= 21"
|
54
58
|
end
|
55
59
|
|
@@ -57,7 +61,7 @@ module Arel
|
|
57
61
|
stmt = Nodes::SelectStatement.new
|
58
62
|
stmt.limit = Nodes::Limit.new(10)
|
59
63
|
stmt.cores.first.projections << Nodes::Count.new('*')
|
60
|
-
sql =
|
64
|
+
sql = compile(stmt)
|
61
65
|
sql.must_be_like "SELECT COUNT(1) as count_id FROM (SELECT _t.* FROM (SELECT ROW_NUMBER() OVER (ORDER BY ) as _row_num) as _t WHERE _row_num BETWEEN 1 AND 10) AS subquery"
|
62
66
|
end
|
63
67
|
|
data/test/visitors/test_mysql.rb
CHANGED
@@ -7,14 +7,18 @@ module Arel
|
|
7
7
|
@visitor = MySQL.new Table.engine.connection
|
8
8
|
end
|
9
9
|
|
10
|
+
def compile node
|
11
|
+
@visitor.accept(node, Collectors::SQLString.new).value
|
12
|
+
end
|
13
|
+
|
10
14
|
it 'squashes parenthesis on multiple unions' do
|
11
|
-
subnode = Nodes::Union.new 'left', 'right'
|
12
|
-
node = Nodes::Union.new subnode, 'topright'
|
13
|
-
assert_equal 1,
|
15
|
+
subnode = Nodes::Union.new Arel.sql('left'), Arel.sql('right')
|
16
|
+
node = Nodes::Union.new subnode, Arel.sql('topright')
|
17
|
+
assert_equal 1, compile(node).scan('(').length
|
14
18
|
|
15
|
-
subnode = Nodes::Union.new 'left', 'right'
|
16
|
-
node = Nodes::Union.new 'topleft', subnode
|
17
|
-
assert_equal 1,
|
19
|
+
subnode = Nodes::Union.new Arel.sql('left'), Arel.sql('right')
|
20
|
+
node = Nodes::Union.new Arel.sql('topleft'), subnode
|
21
|
+
assert_equal 1, compile(node).scan('(').length
|
18
22
|
end
|
19
23
|
|
20
24
|
###
|
@@ -23,31 +27,32 @@ module Arel
|
|
23
27
|
it 'defaults limit to 18446744073709551615' do
|
24
28
|
stmt = Nodes::SelectStatement.new
|
25
29
|
stmt.offset = Nodes::Offset.new(1)
|
26
|
-
sql =
|
30
|
+
sql = compile(stmt)
|
27
31
|
sql.must_be_like "SELECT FROM DUAL LIMIT 18446744073709551615 OFFSET 1"
|
28
32
|
end
|
29
33
|
|
30
34
|
it "should escape LIMIT" do
|
31
35
|
sc = Arel::Nodes::UpdateStatement.new
|
32
|
-
sc.
|
33
|
-
|
36
|
+
sc.relation = Table.new(:users)
|
37
|
+
sc.limit = Nodes::Limit.new(Nodes.build_quoted("omg"))
|
38
|
+
assert_equal("UPDATE \"users\" LIMIT 'omg'", compile(sc))
|
34
39
|
end
|
35
40
|
|
36
41
|
it 'uses DUAL for empty from' do
|
37
42
|
stmt = Nodes::SelectStatement.new
|
38
|
-
sql =
|
43
|
+
sql = compile(stmt)
|
39
44
|
sql.must_be_like "SELECT FROM DUAL"
|
40
45
|
end
|
41
46
|
|
42
47
|
describe 'locking' do
|
43
48
|
it 'defaults to FOR UPDATE when locking' do
|
44
49
|
node = Nodes::Lock.new(Arel.sql('FOR UPDATE'))
|
45
|
-
|
50
|
+
compile(node).must_be_like "FOR UPDATE"
|
46
51
|
end
|
47
52
|
|
48
53
|
it 'allows a custom string to be used as a lock' do
|
49
54
|
node = Nodes::Lock.new(Arel.sql('LOCK IN SHARE MODE'))
|
50
|
-
|
55
|
+
compile(node).must_be_like "LOCK IN SHARE MODE"
|
51
56
|
end
|
52
57
|
end
|
53
58
|
end
|
@@ -7,13 +7,17 @@ module Arel
|
|
7
7
|
@visitor = Oracle.new Table.engine.connection_pool
|
8
8
|
end
|
9
9
|
|
10
|
+
def compile node
|
11
|
+
@visitor.accept(node, Collectors::SQLString.new).value
|
12
|
+
end
|
13
|
+
|
10
14
|
it 'modifies order when there is distinct and first value' do
|
11
15
|
# *sigh*
|
12
16
|
select = "DISTINCT foo.id, FIRST_VALUE(projects.name) OVER (foo) AS alias_0__"
|
13
17
|
stmt = Nodes::SelectStatement.new
|
14
18
|
stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
|
15
19
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
16
|
-
sql =
|
20
|
+
sql = compile(stmt)
|
17
21
|
sql.must_be_like %{
|
18
22
|
SELECT #{select} ORDER BY alias_0__
|
19
23
|
}
|
@@ -26,8 +30,8 @@ module Arel
|
|
26
30
|
stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
|
27
31
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
28
32
|
|
29
|
-
sql =
|
30
|
-
sql2 =
|
33
|
+
sql = compile(stmt)
|
34
|
+
sql2 = compile(stmt)
|
31
35
|
sql.must_equal sql2
|
32
36
|
end
|
33
37
|
|
@@ -37,7 +41,7 @@ module Arel
|
|
37
41
|
stmt = Nodes::SelectStatement.new
|
38
42
|
stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
|
39
43
|
stmt.orders << Nodes::SqlLiteral.new('foo, bar')
|
40
|
-
sql =
|
44
|
+
sql = compile(stmt)
|
41
45
|
sql.must_be_like %{
|
42
46
|
SELECT #{select} ORDER BY alias_0__, alias_1__
|
43
47
|
}
|
@@ -49,7 +53,7 @@ module Arel
|
|
49
53
|
stmt = Nodes::SelectStatement.new
|
50
54
|
stmt.cores.first.projections << Nodes::SqlLiteral.new(select)
|
51
55
|
stmt.orders << Nodes::SqlLiteral.new('NVL(LOWER(bar, foo), foo) DESC, UPPER(baz)')
|
52
|
-
sql =
|
56
|
+
sql = compile(stmt)
|
53
57
|
sql.must_be_like %{
|
54
58
|
SELECT #{select} ORDER BY alias_0__ DESC, alias_1__
|
55
59
|
}
|
@@ -60,7 +64,7 @@ module Arel
|
|
60
64
|
it 'adds a rownum clause' do
|
61
65
|
stmt = Nodes::SelectStatement.new
|
62
66
|
stmt.limit = Nodes::Limit.new(10)
|
63
|
-
sql =
|
67
|
+
sql = compile stmt
|
64
68
|
sql.must_be_like %{ SELECT WHERE ROWNUM <= 10 }
|
65
69
|
end
|
66
70
|
|
@@ -68,8 +72,8 @@ module Arel
|
|
68
72
|
stmt = Nodes::SelectStatement.new
|
69
73
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
70
74
|
stmt.limit = Nodes::Limit.new(10)
|
71
|
-
sql =
|
72
|
-
sql2 =
|
75
|
+
sql = compile stmt
|
76
|
+
sql2 = compile stmt
|
73
77
|
sql.must_equal sql2
|
74
78
|
end
|
75
79
|
|
@@ -77,9 +81,9 @@ module Arel
|
|
77
81
|
stmt = Nodes::SelectStatement.new
|
78
82
|
stmt.orders << Nodes::SqlLiteral.new('foo')
|
79
83
|
stmt.limit = Nodes::Limit.new(10)
|
80
|
-
sql =
|
84
|
+
sql = compile stmt
|
81
85
|
sql.must_be_like %{
|
82
|
-
SELECT * FROM (SELECT ORDER BY foo) WHERE ROWNUM <= 10
|
86
|
+
SELECT * FROM (SELECT ORDER BY foo ) WHERE ROWNUM <= 10
|
83
87
|
}
|
84
88
|
end
|
85
89
|
|
@@ -88,21 +92,21 @@ module Arel
|
|
88
92
|
stmt.cores.first.set_quantifier = Arel::Nodes::Distinct.new
|
89
93
|
stmt.cores.first.projections << Nodes::SqlLiteral.new('id')
|
90
94
|
stmt.limit = Arel::Nodes::Limit.new(10)
|
91
|
-
sql =
|
95
|
+
sql = compile stmt
|
92
96
|
sql.must_be_like %{
|
93
|
-
SELECT * FROM (SELECT DISTINCT id) WHERE ROWNUM <= 10
|
97
|
+
SELECT * FROM (SELECT DISTINCT id ) WHERE ROWNUM <= 10
|
94
98
|
}
|
95
99
|
end
|
96
100
|
|
97
101
|
it 'creates a different subquery when there is an offset' do
|
98
102
|
stmt = Nodes::SelectStatement.new
|
99
|
-
stmt.limit = Nodes::Limit.new(10)
|
103
|
+
stmt.limit = Nodes::Limit.new(Nodes.build_quoted(10))
|
100
104
|
stmt.offset = Nodes::Offset.new(10)
|
101
|
-
sql =
|
105
|
+
sql = compile stmt
|
102
106
|
sql.must_be_like %{
|
103
107
|
SELECT * FROM (
|
104
108
|
SELECT raw_sql_.*, rownum raw_rnum_
|
105
|
-
FROM (SELECT) raw_sql_
|
109
|
+
FROM (SELECT ) raw_sql_
|
106
110
|
WHERE rownum <= 20
|
107
111
|
)
|
108
112
|
WHERE raw_rnum_ > 10
|
@@ -111,10 +115,10 @@ module Arel
|
|
111
115
|
|
112
116
|
it 'is idempotent with different subquery' do
|
113
117
|
stmt = Nodes::SelectStatement.new
|
114
|
-
stmt.limit = Nodes::Limit.new(10)
|
118
|
+
stmt.limit = Nodes::Limit.new(Nodes.build_quoted(10))
|
115
119
|
stmt.offset = Nodes::Offset.new(10)
|
116
|
-
sql =
|
117
|
-
sql2 =
|
120
|
+
sql = compile stmt
|
121
|
+
sql2 = compile stmt
|
118
122
|
sql.must_equal sql2
|
119
123
|
end
|
120
124
|
end
|
@@ -123,7 +127,7 @@ module Arel
|
|
123
127
|
it 'creates a select from subquery with rownum condition' do
|
124
128
|
stmt = Nodes::SelectStatement.new
|
125
129
|
stmt.offset = Nodes::Offset.new(10)
|
126
|
-
sql =
|
130
|
+
sql = compile stmt
|
127
131
|
sql.must_be_like %{
|
128
132
|
SELECT * FROM (
|
129
133
|
SELECT raw_sql_.*, rownum raw_rnum_
|
@@ -139,7 +143,7 @@ module Arel
|
|
139
143
|
it 'modified except to be minus' do
|
140
144
|
left = Nodes::SqlLiteral.new("SELECT * FROM users WHERE age > 10")
|
141
145
|
right = Nodes::SqlLiteral.new("SELECT * FROM users WHERE age > 20")
|
142
|
-
sql =
|
146
|
+
sql = compile Nodes::Except.new(left, right)
|
143
147
|
sql.must_be_like %{
|
144
148
|
( SELECT * FROM users WHERE age > 10 MINUS SELECT * FROM users WHERE age > 20 )
|
145
149
|
}
|
@@ -148,7 +152,7 @@ module Arel
|
|
148
152
|
describe 'locking' do
|
149
153
|
it 'defaults to FOR UPDATE when locking' do
|
150
154
|
node = Nodes::Lock.new(Arel.sql('FOR UPDATE'))
|
151
|
-
|
155
|
+
compile(node).must_be_like "FOR UPDATE"
|
152
156
|
end
|
153
157
|
end
|
154
158
|
end
|