arel 4.0.0 → 4.0.1
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 +7 -0
- data/History.txt +15 -3
- data/Manifest.txt +1 -0
- data/README.markdown +71 -34
- data/Rakefile +1 -0
- data/arel.gemspec +16 -15
- data/lib/arel.rb +1 -1
- data/lib/arel/nodes/and.rb +1 -0
- data/lib/arel/nodes/binary.rb +1 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/insert_statement.rb +1 -0
- data/lib/arel/nodes/node.rb +10 -0
- data/lib/arel/nodes/select_core.rb +1 -0
- data/lib/arel/nodes/select_statement.rb +1 -0
- data/lib/arel/nodes/unary.rb +1 -0
- data/lib/arel/table.rb +4 -1
- data/lib/arel/visitors/bind_visitor.rb +4 -4
- data/lib/arel/visitors/depth_first.rb +56 -56
- data/lib/arel/visitors/dot.rb +75 -75
- data/lib/arel/visitors/ibm_db.rb +2 -2
- data/lib/arel/visitors/informix.rb +17 -17
- data/lib/arel/visitors/join_sql.rb +2 -2
- data/lib/arel/visitors/mssql.rb +12 -12
- data/lib/arel/visitors/mysql.rb +15 -15
- data/lib/arel/visitors/oracle.rb +19 -19
- data/lib/arel/visitors/order_clauses.rb +2 -2
- data/lib/arel/visitors/postgresql.rb +6 -6
- data/lib/arel/visitors/sqlite.rb +2 -2
- data/lib/arel/visitors/to_sql.rb +172 -168
- data/lib/arel/visitors/visitor.rb +8 -5
- data/lib/arel/visitors/where_sql.rb +2 -2
- data/test/test_update_manager.rb +1 -0
- data/test/visitors/test_dispatch_contamination.rb +22 -0
- data/test/visitors/test_oracle.rb +2 -1
- data/test/visitors/test_to_sql.rb +1 -1
- metadata +18 -27
data/lib/arel/visitors/dot.rb
CHANGED
@@ -28,41 +28,41 @@ module Arel
|
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
|
-
def visit_Arel_Nodes_Ordering o
|
32
|
-
visit_edge o, "expr"
|
31
|
+
def visit_Arel_Nodes_Ordering o, a
|
32
|
+
visit_edge o, a, "expr"
|
33
33
|
end
|
34
34
|
|
35
|
-
def visit_Arel_Nodes_TableAlias o
|
36
|
-
visit_edge o, "name"
|
37
|
-
visit_edge o, "relation"
|
35
|
+
def visit_Arel_Nodes_TableAlias o, a
|
36
|
+
visit_edge o, a, "name"
|
37
|
+
visit_edge o, a, "relation"
|
38
38
|
end
|
39
39
|
|
40
|
-
def visit_Arel_Nodes_Count o
|
41
|
-
visit_edge o, "expressions"
|
42
|
-
visit_edge o, "distinct"
|
40
|
+
def visit_Arel_Nodes_Count o, a
|
41
|
+
visit_edge o, a, "expressions"
|
42
|
+
visit_edge o, a, "distinct"
|
43
43
|
end
|
44
44
|
|
45
|
-
def visit_Arel_Nodes_Values o
|
46
|
-
visit_edge o, "expressions"
|
45
|
+
def visit_Arel_Nodes_Values o, a
|
46
|
+
visit_edge o, a, "expressions"
|
47
47
|
end
|
48
48
|
|
49
|
-
def visit_Arel_Nodes_StringJoin o
|
50
|
-
visit_edge o, "left"
|
49
|
+
def visit_Arel_Nodes_StringJoin o, a
|
50
|
+
visit_edge o, a, "left"
|
51
51
|
end
|
52
52
|
|
53
|
-
def visit_Arel_Nodes_InnerJoin o
|
54
|
-
visit_edge o, "left"
|
55
|
-
visit_edge o, "right"
|
53
|
+
def visit_Arel_Nodes_InnerJoin o, a
|
54
|
+
visit_edge o, a, "left"
|
55
|
+
visit_edge o, a, "right"
|
56
56
|
end
|
57
57
|
alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
|
58
58
|
|
59
|
-
def visit_Arel_Nodes_DeleteStatement o
|
60
|
-
visit_edge o, "relation"
|
61
|
-
visit_edge o, "wheres"
|
59
|
+
def visit_Arel_Nodes_DeleteStatement o, a
|
60
|
+
visit_edge o, a, "relation"
|
61
|
+
visit_edge o, a, "wheres"
|
62
62
|
end
|
63
63
|
|
64
|
-
def unary o
|
65
|
-
visit_edge o, "expr"
|
64
|
+
def unary o, a
|
65
|
+
visit_edge o, a, "expr"
|
66
66
|
end
|
67
67
|
alias :visit_Arel_Nodes_Group :unary
|
68
68
|
alias :visit_Arel_Nodes_Grouping :unary
|
@@ -78,23 +78,23 @@ module Arel
|
|
78
78
|
alias :visit_Arel_Nodes_Rows :unary
|
79
79
|
alias :visit_Arel_Nodes_Range :unary
|
80
80
|
|
81
|
-
def window o
|
82
|
-
visit_edge o, "orders"
|
83
|
-
visit_edge o, "framing"
|
81
|
+
def window o, a
|
82
|
+
visit_edge o, a, "orders"
|
83
|
+
visit_edge o, a, "framing"
|
84
84
|
end
|
85
85
|
alias :visit_Arel_Nodes_Window :window
|
86
86
|
|
87
|
-
def named_window o
|
88
|
-
visit_edge o, "orders"
|
89
|
-
visit_edge o, "framing"
|
90
|
-
visit_edge o, "name"
|
87
|
+
def named_window o, a
|
88
|
+
visit_edge o, a, "orders"
|
89
|
+
visit_edge o, a, "framing"
|
90
|
+
visit_edge o, a, "name"
|
91
91
|
end
|
92
92
|
alias :visit_Arel_Nodes_NamedWindow :named_window
|
93
93
|
|
94
|
-
def function o
|
95
|
-
visit_edge o, "expressions"
|
96
|
-
visit_edge o, "distinct"
|
97
|
-
visit_edge o, "alias"
|
94
|
+
def function o, a
|
95
|
+
visit_edge o, a, "expressions"
|
96
|
+
visit_edge o, a, "distinct"
|
97
|
+
visit_edge o, a, "alias"
|
98
98
|
end
|
99
99
|
alias :visit_Arel_Nodes_Exists :function
|
100
100
|
alias :visit_Arel_Nodes_Min :function
|
@@ -102,52 +102,52 @@ module Arel
|
|
102
102
|
alias :visit_Arel_Nodes_Avg :function
|
103
103
|
alias :visit_Arel_Nodes_Sum :function
|
104
104
|
|
105
|
-
def extract o
|
106
|
-
visit_edge o, "expressions"
|
107
|
-
visit_edge o, "alias"
|
105
|
+
def extract o, a
|
106
|
+
visit_edge o, a, "expressions"
|
107
|
+
visit_edge o, a, "alias"
|
108
108
|
end
|
109
109
|
alias :visit_Arel_Nodes_Extract :extract
|
110
110
|
|
111
|
-
def visit_Arel_Nodes_NamedFunction o
|
112
|
-
visit_edge o, "name"
|
113
|
-
visit_edge o, "expressions"
|
114
|
-
visit_edge o, "distinct"
|
115
|
-
visit_edge o, "alias"
|
111
|
+
def visit_Arel_Nodes_NamedFunction o, a
|
112
|
+
visit_edge o, a, "name"
|
113
|
+
visit_edge o, a, "expressions"
|
114
|
+
visit_edge o, a, "distinct"
|
115
|
+
visit_edge o, a, "alias"
|
116
116
|
end
|
117
117
|
|
118
|
-
def visit_Arel_Nodes_InsertStatement o
|
119
|
-
visit_edge o, "relation"
|
120
|
-
visit_edge o, "columns"
|
121
|
-
visit_edge o, "values"
|
118
|
+
def visit_Arel_Nodes_InsertStatement o, a
|
119
|
+
visit_edge o, a, "relation"
|
120
|
+
visit_edge o, a, "columns"
|
121
|
+
visit_edge o, a, "values"
|
122
122
|
end
|
123
123
|
|
124
|
-
def visit_Arel_Nodes_SelectCore o
|
125
|
-
visit_edge o, "source"
|
126
|
-
visit_edge o, "projections"
|
127
|
-
visit_edge o, "wheres"
|
128
|
-
visit_edge o, "windows"
|
124
|
+
def visit_Arel_Nodes_SelectCore o, a
|
125
|
+
visit_edge o, a, "source"
|
126
|
+
visit_edge o, a, "projections"
|
127
|
+
visit_edge o, a, "wheres"
|
128
|
+
visit_edge o, a, "windows"
|
129
129
|
end
|
130
130
|
|
131
|
-
def visit_Arel_Nodes_SelectStatement o
|
132
|
-
visit_edge o, "cores"
|
133
|
-
visit_edge o, "limit"
|
134
|
-
visit_edge o, "orders"
|
135
|
-
visit_edge o, "offset"
|
131
|
+
def visit_Arel_Nodes_SelectStatement o, a
|
132
|
+
visit_edge o, a, "cores"
|
133
|
+
visit_edge o, a, "limit"
|
134
|
+
visit_edge o, a, "orders"
|
135
|
+
visit_edge o, a, "offset"
|
136
136
|
end
|
137
137
|
|
138
|
-
def visit_Arel_Nodes_UpdateStatement o
|
139
|
-
visit_edge o, "relation"
|
140
|
-
visit_edge o, "wheres"
|
141
|
-
visit_edge o, "values"
|
138
|
+
def visit_Arel_Nodes_UpdateStatement o, a
|
139
|
+
visit_edge o, a, "relation"
|
140
|
+
visit_edge o, a, "wheres"
|
141
|
+
visit_edge o, a, "values"
|
142
142
|
end
|
143
143
|
|
144
|
-
def visit_Arel_Table o
|
145
|
-
visit_edge o, "name"
|
144
|
+
def visit_Arel_Table o, a
|
145
|
+
visit_edge o, a, "name"
|
146
146
|
end
|
147
147
|
|
148
|
-
def visit_Arel_Attribute o
|
149
|
-
visit_edge o, "relation"
|
150
|
-
visit_edge o, "name"
|
148
|
+
def visit_Arel_Attribute o, a
|
149
|
+
visit_edge o, a, "relation"
|
150
|
+
visit_edge o, a, "name"
|
151
151
|
end
|
152
152
|
alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
|
153
153
|
alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
|
@@ -156,16 +156,16 @@ module Arel
|
|
156
156
|
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
|
157
157
|
alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
|
158
158
|
|
159
|
-
def nary o
|
159
|
+
def nary o, a
|
160
160
|
o.children.each_with_index do |x,i|
|
161
|
-
edge(i) { visit x }
|
161
|
+
edge(i) { visit x, a }
|
162
162
|
end
|
163
163
|
end
|
164
164
|
alias :visit_Arel_Nodes_And :nary
|
165
165
|
|
166
|
-
def binary o
|
167
|
-
visit_edge o, "left"
|
168
|
-
visit_edge o, "right"
|
166
|
+
def binary o, a
|
167
|
+
visit_edge o, a, "left"
|
168
|
+
visit_edge o, a, "right"
|
169
169
|
end
|
170
170
|
alias :visit_Arel_Nodes_As :binary
|
171
171
|
alias :visit_Arel_Nodes_Assignment :binary
|
@@ -184,7 +184,7 @@ module Arel
|
|
184
184
|
alias :visit_Arel_Nodes_Or :binary
|
185
185
|
alias :visit_Arel_Nodes_Over :binary
|
186
186
|
|
187
|
-
def visit_String o
|
187
|
+
def visit_String o, a
|
188
188
|
@node_stack.last.fields << o
|
189
189
|
end
|
190
190
|
alias :visit_Time :visit_String
|
@@ -201,23 +201,23 @@ module Arel
|
|
201
201
|
alias :visit_Symbol :visit_String
|
202
202
|
alias :visit_Arel_Nodes_SqlLiteral :visit_String
|
203
203
|
|
204
|
-
def visit_Hash o
|
204
|
+
def visit_Hash o, a
|
205
205
|
o.each_with_index do |pair, i|
|
206
|
-
edge("pair_#{i}") { visit pair }
|
206
|
+
edge("pair_#{i}") { visit pair, a }
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
-
def visit_Array o
|
210
|
+
def visit_Array o, a
|
211
211
|
o.each_with_index do |x,i|
|
212
|
-
edge(i) { visit x }
|
212
|
+
edge(i) { visit x, a }
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
-
def visit_edge o, method
|
217
|
-
edge(method) { visit o.send(method) }
|
216
|
+
def visit_edge o, a, method
|
217
|
+
edge(method) { visit o.send(method), a }
|
218
218
|
end
|
219
219
|
|
220
|
-
def visit o
|
220
|
+
def visit o, a = nil
|
221
221
|
if node = @seen[o.object_id]
|
222
222
|
@edge_stack.last.to = node
|
223
223
|
return
|
data/lib/arel/visitors/ibm_db.rb
CHANGED
@@ -2,32 +2,32 @@ module Arel
|
|
2
2
|
module Visitors
|
3
3
|
class Informix < Arel::Visitors::ToSql
|
4
4
|
private
|
5
|
-
def visit_Arel_Nodes_SelectStatement o
|
5
|
+
def visit_Arel_Nodes_SelectStatement o, a
|
6
6
|
[
|
7
7
|
"SELECT",
|
8
|
-
(visit(o.offset) if o.offset),
|
9
|
-
(visit(o.limit) if o.limit),
|
10
|
-
o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
11
|
-
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
12
|
-
(visit(o.lock) if o.lock),
|
8
|
+
(visit(o.offset, a) if o.offset),
|
9
|
+
(visit(o.limit, a) if o.limit),
|
10
|
+
o.cores.map { |x| visit_Arel_Nodes_SelectCore x, a }.join,
|
11
|
+
("ORDER BY #{o.orders.map { |x| visit x, a }.join(', ')}" unless o.orders.empty?),
|
12
|
+
(visit(o.lock, a) if o.lock),
|
13
13
|
].compact.join ' '
|
14
14
|
end
|
15
|
-
def visit_Arel_Nodes_SelectCore o
|
15
|
+
def visit_Arel_Nodes_SelectCore o, a
|
16
16
|
[
|
17
|
-
"#{o.projections.map { |x| visit x }.join ', '}",
|
18
|
-
("FROM #{visit(o.source)}" if o.source && !o.source.empty?),
|
19
|
-
("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
|
20
|
-
("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
|
21
|
-
(visit(o.having) if o.having),
|
17
|
+
"#{o.projections.map { |x| visit x, a }.join ', '}",
|
18
|
+
("FROM #{visit(o.source, a)}" if o.source && !o.source.empty?),
|
19
|
+
("WHERE #{o.wheres.map { |x| visit x, a }.join ' AND ' }" unless o.wheres.empty?),
|
20
|
+
("GROUP BY #{o.groups.map { |x| visit x, a }.join ', ' }" unless o.groups.empty?),
|
21
|
+
(visit(o.having, a) if o.having),
|
22
22
|
].compact.join ' '
|
23
23
|
end
|
24
|
-
def visit_Arel_Nodes_Offset o
|
25
|
-
"SKIP #{visit o.expr}"
|
24
|
+
def visit_Arel_Nodes_Offset o, a
|
25
|
+
"SKIP #{visit o.expr, a}"
|
26
26
|
end
|
27
|
-
def visit_Arel_Nodes_Limit o
|
28
|
-
"LIMIT #{visit o.expr}"
|
27
|
+
def visit_Arel_Nodes_Limit o, a
|
28
|
+
"LIMIT #{visit o.expr, a}"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
end
|
32
|
+
end
|
33
33
|
|
data/lib/arel/visitors/mssql.rb
CHANGED
@@ -6,20 +6,20 @@ module Arel
|
|
6
6
|
# `top` wouldn't really work here. I.e. User.select("distinct first_name").limit(10) would generate
|
7
7
|
# "select top 10 distinct first_name from users", which is invalid query! it should be
|
8
8
|
# "select distinct top 10 first_name from users"
|
9
|
-
def visit_Arel_Nodes_Top o
|
9
|
+
def visit_Arel_Nodes_Top o, a
|
10
10
|
""
|
11
11
|
end
|
12
12
|
|
13
|
-
def visit_Arel_Nodes_SelectStatement o
|
13
|
+
def visit_Arel_Nodes_SelectStatement o, a
|
14
14
|
if !o.limit && !o.offset
|
15
|
-
return super o
|
15
|
+
return super o, a
|
16
16
|
end
|
17
17
|
|
18
|
-
select_order_by = "ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?
|
18
|
+
select_order_by = "ORDER BY #{o.orders.map { |x| visit x, a }.join(', ')}" unless o.orders.empty?
|
19
19
|
|
20
20
|
is_select_count = false
|
21
21
|
sql = o.cores.map { |x|
|
22
|
-
core_order_by = select_order_by || determine_order_by(x)
|
22
|
+
core_order_by = select_order_by || determine_order_by(x, a)
|
23
23
|
if select_count? x
|
24
24
|
x.projections = [row_num_literal(core_order_by)]
|
25
25
|
is_select_count = true
|
@@ -27,7 +27,7 @@ module Arel
|
|
27
27
|
x.projections << row_num_literal(core_order_by)
|
28
28
|
end
|
29
29
|
|
30
|
-
visit_Arel_Nodes_SelectCore x
|
30
|
+
visit_Arel_Nodes_SelectCore x, a
|
31
31
|
}.join
|
32
32
|
|
33
33
|
sql = "SELECT _t.* FROM (#{sql}) as _t WHERE #{get_offset_limit_clause(o)}"
|
@@ -46,11 +46,11 @@ module Arel
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def determine_order_by x
|
49
|
+
def determine_order_by x, a
|
50
50
|
unless x.groups.empty?
|
51
|
-
"ORDER BY #{x.groups.map { |g| visit g }.join ', ' }"
|
51
|
+
"ORDER BY #{x.groups.map { |g| visit g, a }.join ', ' }"
|
52
52
|
else
|
53
|
-
"ORDER BY #{find_left_table_pk(x.froms)}"
|
53
|
+
"ORDER BY #{find_left_table_pk(x.froms, a)}"
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -64,9 +64,9 @@ module Arel
|
|
64
64
|
|
65
65
|
# fixme raise exception of there is no pk?
|
66
66
|
# fixme!! Table.primary_key will be depricated. What is the replacement??
|
67
|
-
def find_left_table_pk o
|
68
|
-
return visit o.primary_key if o.instance_of? Arel::Table
|
69
|
-
find_left_table_pk o.left if o.kind_of? Arel::Nodes::Join
|
67
|
+
def find_left_table_pk o, a
|
68
|
+
return visit o.primary_key, a if o.instance_of? Arel::Table
|
69
|
+
find_left_table_pk o.left, a if o.kind_of? Arel::Nodes::Join
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
data/lib/arel/visitors/mysql.rb
CHANGED
@@ -2,19 +2,19 @@ module Arel
|
|
2
2
|
module Visitors
|
3
3
|
class MySQL < Arel::Visitors::ToSql
|
4
4
|
private
|
5
|
-
def visit_Arel_Nodes_Union o, suppress_parens = false
|
5
|
+
def visit_Arel_Nodes_Union o, a, suppress_parens = false
|
6
6
|
left_result = case o.left
|
7
7
|
when Arel::Nodes::Union
|
8
|
-
visit_Arel_Nodes_Union o.left, true
|
8
|
+
visit_Arel_Nodes_Union o.left, a, true
|
9
9
|
else
|
10
|
-
visit o.left
|
10
|
+
visit o.left, a
|
11
11
|
end
|
12
12
|
|
13
13
|
right_result = case o.right
|
14
14
|
when Arel::Nodes::Union
|
15
|
-
visit_Arel_Nodes_Union o.right, true
|
15
|
+
visit_Arel_Nodes_Union o.right, a, true
|
16
16
|
else
|
17
|
-
visit o.right
|
17
|
+
visit o.right, a
|
18
18
|
end
|
19
19
|
|
20
20
|
if suppress_parens
|
@@ -24,30 +24,30 @@ module Arel
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def visit_Arel_Nodes_Bin o
|
28
|
-
"BINARY #{visit o.expr}"
|
27
|
+
def visit_Arel_Nodes_Bin o, a
|
28
|
+
"BINARY #{visit o.expr, a}"
|
29
29
|
end
|
30
30
|
|
31
31
|
###
|
32
32
|
# :'(
|
33
33
|
# http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
|
34
|
-
def visit_Arel_Nodes_SelectStatement o
|
34
|
+
def visit_Arel_Nodes_SelectStatement o, a
|
35
35
|
o.limit = Arel::Nodes::Limit.new(18446744073709551615) if o.offset && !o.limit
|
36
36
|
super
|
37
37
|
end
|
38
38
|
|
39
|
-
def visit_Arel_Nodes_SelectCore o
|
39
|
+
def visit_Arel_Nodes_SelectCore o, a
|
40
40
|
o.froms ||= Arel.sql('DUAL')
|
41
41
|
super
|
42
42
|
end
|
43
43
|
|
44
|
-
def visit_Arel_Nodes_UpdateStatement o
|
44
|
+
def visit_Arel_Nodes_UpdateStatement o, a
|
45
45
|
[
|
46
|
-
"UPDATE #{visit o.relation}",
|
47
|
-
("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
|
48
|
-
("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?),
|
49
|
-
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
50
|
-
(visit(o.limit) if o.limit),
|
46
|
+
"UPDATE #{visit o.relation, a}",
|
47
|
+
("SET #{o.values.map { |value| visit value, a }.join ', '}" unless o.values.empty?),
|
48
|
+
("WHERE #{o.wheres.map { |x| visit x, a }.join ' AND '}" unless o.wheres.empty?),
|
49
|
+
("ORDER BY #{o.orders.map { |x| visit x, a }.join(', ')}" unless o.orders.empty?),
|
50
|
+
(visit(o.limit, a) if o.limit),
|
51
51
|
].compact.join ' '
|
52
52
|
end
|
53
53
|
|
data/lib/arel/visitors/oracle.rb
CHANGED
@@ -3,12 +3,12 @@ module Arel
|
|
3
3
|
class Oracle < Arel::Visitors::ToSql
|
4
4
|
private
|
5
5
|
|
6
|
-
def visit_Arel_Nodes_SelectStatement o
|
7
|
-
o = order_hacks(o)
|
6
|
+
def visit_Arel_Nodes_SelectStatement o, a
|
7
|
+
o = order_hacks(o, a)
|
8
8
|
|
9
9
|
# if need to select first records without ORDER BY and GROUP BY and without DISTINCT
|
10
10
|
# then can use simple ROWNUM in WHERE clause
|
11
|
-
if o.limit && o.orders.empty? && !o.offset && o.cores.first.
|
11
|
+
if o.limit && o.orders.empty? && !o.offset && o.cores.first.set_quantifier.class.to_s !~ /Distinct/
|
12
12
|
o.cores.last.wheres.push Nodes::LessThanOrEqual.new(
|
13
13
|
Nodes::SqlLiteral.new('ROWNUM'), o.limit.expr
|
14
14
|
)
|
@@ -20,53 +20,53 @@ module Arel
|
|
20
20
|
limit = o.limit.expr.to_i
|
21
21
|
offset = o.offset
|
22
22
|
o.offset = nil
|
23
|
-
sql = super(o)
|
23
|
+
sql = super(o, a)
|
24
24
|
return <<-eosql
|
25
25
|
SELECT * FROM (
|
26
26
|
SELECT raw_sql_.*, rownum raw_rnum_
|
27
27
|
FROM (#{sql}) raw_sql_
|
28
28
|
WHERE rownum <= #{offset.expr.to_i + limit}
|
29
29
|
)
|
30
|
-
WHERE #{visit offset}
|
30
|
+
WHERE #{visit offset, a}
|
31
31
|
eosql
|
32
32
|
end
|
33
33
|
|
34
34
|
if o.limit
|
35
35
|
o = o.dup
|
36
36
|
limit = o.limit.expr
|
37
|
-
return "SELECT * FROM (#{super(o)}) WHERE ROWNUM <= #{visit limit}"
|
37
|
+
return "SELECT * FROM (#{super(o, a)}) WHERE ROWNUM <= #{visit limit, a}"
|
38
38
|
end
|
39
39
|
|
40
40
|
if o.offset
|
41
41
|
o = o.dup
|
42
42
|
offset = o.offset
|
43
43
|
o.offset = nil
|
44
|
-
sql = super(o)
|
44
|
+
sql = super(o, a)
|
45
45
|
return <<-eosql
|
46
46
|
SELECT * FROM (
|
47
47
|
SELECT raw_sql_.*, rownum raw_rnum_
|
48
48
|
FROM (#{sql}) raw_sql_
|
49
49
|
)
|
50
|
-
WHERE #{visit offset}
|
50
|
+
WHERE #{visit offset, a}
|
51
51
|
eosql
|
52
52
|
end
|
53
53
|
|
54
54
|
super
|
55
55
|
end
|
56
56
|
|
57
|
-
def visit_Arel_Nodes_Limit o
|
57
|
+
def visit_Arel_Nodes_Limit o, a
|
58
58
|
end
|
59
59
|
|
60
|
-
def visit_Arel_Nodes_Offset o
|
61
|
-
"raw_rnum_ > #{visit o.expr}"
|
60
|
+
def visit_Arel_Nodes_Offset o, a
|
61
|
+
"raw_rnum_ > #{visit o.expr, a}"
|
62
62
|
end
|
63
63
|
|
64
|
-
def visit_Arel_Nodes_Except o
|
65
|
-
"( #{visit o.left} MINUS #{visit o.right} )"
|
64
|
+
def visit_Arel_Nodes_Except o, a
|
65
|
+
"( #{visit o.left, a} MINUS #{visit o.right, a} )"
|
66
66
|
end
|
67
67
|
|
68
|
-
def visit_Arel_Nodes_UpdateStatement o
|
69
|
-
# Oracle does not allow ORDER BY/LIMIT in UPDATEs.
|
68
|
+
def visit_Arel_Nodes_UpdateStatement o, a
|
69
|
+
# Oracle does not allow ORDER BY/LIMIT in UPDATEs.
|
70
70
|
if o.orders.any? && o.limit.nil?
|
71
71
|
# However, there is no harm in silently eating the ORDER BY clause if no LIMIT has been provided,
|
72
72
|
# otherwise let the user deal with the error
|
@@ -79,19 +79,19 @@ module Arel
|
|
79
79
|
|
80
80
|
###
|
81
81
|
# Hacks for the order clauses specific to Oracle
|
82
|
-
def order_hacks o
|
82
|
+
def order_hacks o, a
|
83
83
|
return o if o.orders.empty?
|
84
84
|
return o unless o.cores.any? do |core|
|
85
85
|
core.projections.any? do |projection|
|
86
|
-
/
|
86
|
+
/FIRST_VALUE/ === projection
|
87
87
|
end
|
88
88
|
end
|
89
89
|
# Previous version with join and split broke ORDER BY clause
|
90
90
|
# if it contained functions with several arguments (separated by ',').
|
91
91
|
#
|
92
|
-
# orders = o.orders.map { |x| visit x }.join(', ').split(',')
|
92
|
+
# orders = o.orders.map { |x| visit x, a }.join(', ').split(',')
|
93
93
|
orders = o.orders.map do |x|
|
94
|
-
string = visit x
|
94
|
+
string = visit x, a
|
95
95
|
if string.include?(',')
|
96
96
|
split_order_string(string)
|
97
97
|
else
|