arel 5.0.1.20140414130214 → 6.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|