arel_extensions 1.2.3 → 1.2.14
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 +5 -5
- data/.rubocop.yml +7 -4
- data/.travis.yml +59 -91
- data/Gemfile +2 -2
- data/README.md +17 -12
- data/Rakefile +38 -27
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +1 -1
- data/functions.html +3 -3
- data/gemfiles/rails4.gemfile +1 -1
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +14 -0
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions.rb +63 -19
- data/lib/arel_extensions/attributes.rb +0 -1
- data/lib/arel_extensions/boolean_functions.rb +38 -13
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/comparators.rb +4 -2
- data/lib/arel_extensions/insert_manager.rb +26 -24
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +10 -5
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
- data/lib/arel_extensions/nodes/case.rb +8 -4
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +2 -2
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +6 -13
- data/lib/arel_extensions/nodes/date_diff.rb +3 -5
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +8 -8
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
- data/lib/arel_extensions/nodes/function.rb +2 -0
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +4 -4
- data/lib/arel_extensions/nodes/power.rb +6 -5
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +24 -6
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +16 -15
- data/lib/arel_extensions/nodes/std.rb +19 -21
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/sum.rb +7 -0
- data/lib/arel_extensions/nodes/trim.rb +3 -3
- data/lib/arel_extensions/nodes/union.rb +2 -3
- data/lib/arel_extensions/nodes/union_all.rb +0 -1
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/predications.rb +35 -33
- data/lib/arel_extensions/set_functions.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +34 -12
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +14 -13
- data/lib/arel_extensions/visitors/mysql.rb +90 -36
- data/lib/arel_extensions/visitors/oracle.rb +16 -16
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +78 -32
- data/lib/arel_extensions/visitors/sqlite.rb +52 -44
- data/lib/arel_extensions/visitors/to_sql.rb +71 -58
- data/test/arelx_test_helper.rb +28 -0
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +4 -0
- data/test/test_comparators.rb +9 -8
- data/test/visitors/test_bulk_insert_oracle.rb +8 -7
- data/test/visitors/test_bulk_insert_sqlite.rb +9 -8
- data/test/visitors/test_bulk_insert_to_sql.rb +8 -10
- data/test/visitors/test_oracle.rb +41 -40
- data/test/visitors/test_to_sql.rb +367 -193
- data/test/with_ar/all_agnostic_test.rb +68 -35
- data/test/with_ar/insert_agnostic_test.rb +3 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -5
- data/test/with_ar/test_math_sqlite.rb +4 -4
- data/test/with_ar/test_string_mysql.rb +4 -6
- data/test/with_ar/test_string_sqlite.rb +3 -7
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +13 -7
- data/test/helper.rb +0 -18
@@ -1,7 +1,7 @@
|
|
1
1
|
#require 'oracle_visitor'
|
2
2
|
module ArelExtensions
|
3
3
|
module Visitors
|
4
|
-
Arel::Visitors::Oracle
|
4
|
+
class Arel::Visitors::Oracle
|
5
5
|
|
6
6
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
7
7
|
Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
@@ -131,14 +131,15 @@ module ArelExtensions
|
|
131
131
|
collector << "(LISTAGG("
|
132
132
|
collector = visit o.left, collector
|
133
133
|
collector << Arel::Visitors::Oracle::COMMA
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
collector =
|
135
|
+
if o.separator && o.separator != 'NULL'
|
136
|
+
visit o.separator, collector
|
137
|
+
else
|
138
|
+
visit Arel::Nodes.build_quoted(','), collector
|
139
|
+
end
|
139
140
|
collector << ") WITHIN GROUP (ORDER BY "
|
140
|
-
if !o.
|
141
|
-
o.
|
141
|
+
if !o.order.blank?
|
142
|
+
o.order.each_with_index do |order,i|
|
142
143
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
143
144
|
collector = visit order, collector
|
144
145
|
end
|
@@ -154,7 +155,7 @@ module ArelExtensions
|
|
154
155
|
o.expressions.each_with_index { |arg, i|
|
155
156
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
156
157
|
if i > 0 && o.left_node_type == :text
|
157
|
-
if arg == ''
|
158
|
+
if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
|
158
159
|
collector << "NULL"
|
159
160
|
else
|
160
161
|
collector << 'TO_CLOB('
|
@@ -466,14 +467,12 @@ module ArelExtensions
|
|
466
467
|
o.left.each_with_index do |row, idx| # values
|
467
468
|
collector << " UNION ALL " if idx != 0
|
468
469
|
collector << "(SELECT "
|
469
|
-
|
470
|
-
|
471
|
-
v.expressions.each_with_index { |value, i|
|
470
|
+
len = row.length - 1
|
471
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
472
472
|
case value
|
473
473
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
474
474
|
collector = visit value, collector
|
475
475
|
else
|
476
|
-
attr = v.columns[i]
|
477
476
|
collector << quote(value, attr && column_for(attr)).to_s
|
478
477
|
end
|
479
478
|
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
@@ -489,12 +488,13 @@ module ArelExtensions
|
|
489
488
|
o.left.each_with_index do |row, idx|
|
490
489
|
collector << " UNION ALL " if idx != 0
|
491
490
|
collector << "(SELECT "
|
492
|
-
|
493
|
-
|
494
|
-
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
491
|
+
len = row.length - 1
|
492
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
495
493
|
case value
|
496
494
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
497
495
|
collector = visit value, collector
|
496
|
+
when Integer
|
497
|
+
collector << value.to_s
|
498
498
|
else
|
499
499
|
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
500
500
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
Arel::Visitors::PostgreSQL
|
3
|
+
class Arel::Visitors::PostgreSQL
|
4
4
|
Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
5
5
|
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
|
6
6
|
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
@@ -83,23 +83,49 @@ module ArelExtensions
|
|
83
83
|
collector
|
84
84
|
end
|
85
85
|
|
86
|
+
def visit_Aggregate_For_AggregateFunction o, collector
|
87
|
+
if !o.order.blank? || !o.group.blank?
|
88
|
+
collector << " OVER ("
|
89
|
+
if !o.group.blank?
|
90
|
+
collector << " PARTITION BY "
|
91
|
+
o.group.each_with_index do |group, i|
|
92
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
93
|
+
visit group, collector
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if !o.order.blank?
|
97
|
+
collector << " ORDER BY "
|
98
|
+
o.order.each_with_index do |order, i|
|
99
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
100
|
+
visit order, collector
|
101
|
+
end
|
102
|
+
end
|
103
|
+
collector << ")"
|
104
|
+
end
|
105
|
+
collector
|
106
|
+
end
|
107
|
+
|
86
108
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
87
109
|
collector << "array_to_string(array_agg("
|
88
110
|
collector = visit o.left, collector
|
89
|
-
if !o.
|
90
|
-
collector <<
|
91
|
-
o.
|
111
|
+
if o.order && !o.order.blank?
|
112
|
+
collector << " ORDER BY"
|
113
|
+
o.order.each_with_index do |order, i|
|
92
114
|
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
93
|
-
collector
|
115
|
+
collector << " "
|
116
|
+
visit order, collector
|
94
117
|
end
|
95
118
|
end
|
96
119
|
collector << ")"
|
120
|
+
o.order = nil
|
121
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
97
122
|
collector << Arel::Visitors::PostgreSQL::COMMA
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
123
|
+
collector =
|
124
|
+
if o.separator && o.separator != 'NULL'
|
125
|
+
visit o.separator, collector
|
126
|
+
else
|
127
|
+
visit Arel::Nodes.build_quoted(','), collector
|
128
|
+
end
|
103
129
|
collector << ")"
|
104
130
|
collector
|
105
131
|
end
|
@@ -277,6 +303,22 @@ module ArelExtensions
|
|
277
303
|
collector
|
278
304
|
end
|
279
305
|
|
306
|
+
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
307
|
+
collector << "REGEXP_REPLACE("
|
308
|
+
visit o.left, collector
|
309
|
+
collector << Arel::Visitors::ToSql::COMMA
|
310
|
+
tab = o.pattern.inspect+ 'g' # Make it always global
|
311
|
+
pattern = tab.split('/')[1..-2].join('/')
|
312
|
+
flags = tab.split('/')[-1]
|
313
|
+
visit Arel::Nodes.build_quoted(pattern), collector
|
314
|
+
collector << Arel::Visitors::ToSql::COMMA
|
315
|
+
visit o.substitute, collector
|
316
|
+
collector << Arel::Visitors::ToSql::COMMA
|
317
|
+
visit Arel::Nodes.build_quoted(flags+"g"), collector
|
318
|
+
collector << ")"
|
319
|
+
collector
|
320
|
+
end
|
321
|
+
|
280
322
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
281
323
|
collector = visit o.expr, collector
|
282
324
|
collector << ' IS NULL'
|
@@ -293,6 +335,7 @@ module ArelExtensions
|
|
293
335
|
collector << "sum("
|
294
336
|
collector = visit o.expr, collector
|
295
337
|
collector << ")"
|
338
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
296
339
|
collector
|
297
340
|
end
|
298
341
|
|
@@ -345,27 +388,28 @@ module ArelExtensions
|
|
345
388
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
346
389
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
347
390
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
391
|
+
number =
|
392
|
+
if o.scientific_notation
|
393
|
+
ArelExtensions::Nodes::Concat.new([
|
394
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
395
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
396
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
397
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
398
|
+
])]),
|
399
|
+
o.type,
|
400
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
401
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
402
|
+
col.abs.log10.floor,
|
403
|
+
Arel::Nodes.build_quoted('FM'+nines_before)
|
404
|
+
])])
|
405
|
+
])
|
406
|
+
else
|
407
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
408
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
409
|
+
Arel::Nodes.build_quoted(col.abs),
|
410
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
411
|
+
])])
|
412
|
+
end
|
369
413
|
|
370
414
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
371
415
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -420,6 +464,7 @@ module ArelExtensions
|
|
420
464
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
421
465
|
visit o.left, collector
|
422
466
|
collector << ")"
|
467
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
423
468
|
collector
|
424
469
|
end
|
425
470
|
|
@@ -427,6 +472,7 @@ module ArelExtensions
|
|
427
472
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
428
473
|
visit o.left, collector
|
429
474
|
collector << ")"
|
475
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
430
476
|
collector
|
431
477
|
end
|
432
478
|
|
@@ -438,7 +484,7 @@ module ArelExtensions
|
|
438
484
|
if i != 0
|
439
485
|
collector << Arel::Visitors::MySQL::COMMA
|
440
486
|
end
|
441
|
-
collector
|
487
|
+
collector = visit v, collector
|
442
488
|
end
|
443
489
|
collector << '])'
|
444
490
|
when Hash
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
Arel::Visitors::SQLite
|
3
|
+
class Arel::Visitors::SQLite
|
4
4
|
Arel::Visitors::SQLite::DATE_MAPPING = {'d' => '%d', 'm' => '%m', 'w' => '%W', 'y' => '%Y', 'wd' => '%w', 'M' => '%M', 'h' => '%H', 'mn' => '%M', 's' => '%S'}
|
5
5
|
Arel::Visitors::SQLite::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
6
6
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
@@ -193,18 +193,28 @@ module ArelExtensions
|
|
193
193
|
collector
|
194
194
|
end
|
195
195
|
|
196
|
-
#
|
197
|
-
#
|
196
|
+
# CAST(
|
197
|
+
# CASE
|
198
|
+
# WHEN 3.42 >= 0 THEN CAST(3.42 AS INT)
|
199
|
+
# WHEN CAST(3.42 AS INT) = 3.42 THEN CAST(3.42 AS INT)
|
200
|
+
# ELSE CAST((3.42 - 1.0) AS INT)
|
201
|
+
# END
|
202
|
+
# AS FLOAT
|
203
|
+
# )
|
198
204
|
def visit_ArelExtensions_Nodes_Floor o, collector
|
199
|
-
collector << "CASE WHEN
|
205
|
+
collector << "CAST(CASE WHEN "
|
200
206
|
collector = visit o.left, collector
|
201
|
-
collector << "
|
207
|
+
collector << " >= 0 THEN CAST("
|
202
208
|
collector = visit o.left, collector
|
203
|
-
collector << ")
|
209
|
+
collector << " AS INT) WHEN CAST("
|
210
|
+
collector = visit o.left, collector
|
211
|
+
collector << " AS INT) = "
|
212
|
+
collector = visit o.left, collector
|
213
|
+
collector << " THEN CAST("
|
204
214
|
collector = visit o.left, collector
|
205
|
-
collector << ") ELSE
|
215
|
+
collector << " AS INT) ELSE CAST(("
|
206
216
|
collector = visit o.left, collector
|
207
|
-
collector << "
|
217
|
+
collector << " - 1.0) AS INT) END AS FLOAT)"
|
208
218
|
collector
|
209
219
|
end
|
210
220
|
|
@@ -225,9 +235,8 @@ module ArelExtensions
|
|
225
235
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
226
236
|
o.left.each_with_index do |row, idx|
|
227
237
|
collector << 'SELECT '
|
228
|
-
|
229
|
-
|
230
|
-
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
238
|
+
len = row.length - 1
|
239
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
231
240
|
case value
|
232
241
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
233
242
|
collector = visit value.as(attr.name), collector
|
@@ -248,12 +257,17 @@ module ArelExtensions
|
|
248
257
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
249
258
|
o.left.each_with_index do |row, idx|
|
250
259
|
collector << 'SELECT '
|
251
|
-
|
252
|
-
|
253
|
-
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
260
|
+
len = row.length - 1
|
261
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
254
262
|
case value
|
255
263
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
256
264
|
collector = visit value.as(attr.name), collector
|
265
|
+
when Integer
|
266
|
+
collector << value.to_s
|
267
|
+
if idx == 0
|
268
|
+
collector << " AS "
|
269
|
+
collector << quote(attr.name)
|
270
|
+
end
|
257
271
|
else
|
258
272
|
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
259
273
|
if idx == 0
|
@@ -270,32 +284,36 @@ module ArelExtensions
|
|
270
284
|
end
|
271
285
|
|
272
286
|
def visit_ArelExtensions_Nodes_Union o, collector
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
287
|
+
collector =
|
288
|
+
if o.left.is_a?(Arel::SelectManager)
|
289
|
+
visit o.left.ast, collector
|
290
|
+
else
|
291
|
+
visit o.left, collector
|
292
|
+
end
|
278
293
|
collector << " UNION "
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
294
|
+
collector =
|
295
|
+
if o.right.is_a?(Arel::SelectManager)
|
296
|
+
visit o.right.ast, collector
|
297
|
+
else
|
298
|
+
visit o.right, collector
|
299
|
+
end
|
284
300
|
collector
|
285
301
|
end
|
286
302
|
|
287
303
|
def visit_ArelExtensions_Nodes_UnionAll o, collector
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
304
|
+
collector =
|
305
|
+
if o.left.is_a?(Arel::SelectManager)
|
306
|
+
visit o.left.ast, collector
|
307
|
+
else
|
308
|
+
visit o.left, collector
|
309
|
+
end
|
293
310
|
collector << " UNION ALL "
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
311
|
+
collector =
|
312
|
+
if o.right.is_a?(Arel::SelectManager)
|
313
|
+
visit o.right.ast, collector
|
314
|
+
else
|
315
|
+
visit o.right, collector
|
316
|
+
end
|
299
317
|
collector
|
300
318
|
end
|
301
319
|
|
@@ -346,16 +364,6 @@ module ArelExtensions
|
|
346
364
|
collector
|
347
365
|
end
|
348
366
|
|
349
|
-
|
350
|
-
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
351
|
-
def visit_Arel_Nodes_SelectStatement o, collector
|
352
|
-
if !collector.value.blank? && o.limit.blank?
|
353
|
-
o = o.dup
|
354
|
-
o.orders = []
|
355
|
-
end
|
356
|
-
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
357
|
-
end
|
358
|
-
|
359
367
|
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
360
368
|
def visit_Arel_Nodes_As o, collector
|
361
369
|
if o.left.is_a?(Arel::Nodes::Binary)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
3
|
+
class Arel::Visitors::ToSql
|
4
|
+
Arel::Visitors::ToSql::COMMA = ', ' unless defined?(Arel::Visitors::ToSql::COMMA)
|
4
5
|
|
5
6
|
# Math Functions
|
6
7
|
def visit_ArelExtensions_Nodes_Abs o, collector
|
@@ -52,14 +53,14 @@ module ArelExtensions
|
|
52
53
|
collector << ")"
|
53
54
|
collector
|
54
55
|
end
|
55
|
-
|
56
|
+
|
56
57
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
57
58
|
collector << "LOG10("
|
58
59
|
collector = visit o.left, collector
|
59
60
|
collector << ")"
|
60
61
|
collector
|
61
62
|
end
|
62
|
-
|
63
|
+
|
63
64
|
def visit_ArelExtensions_Nodes_Power o, collector
|
64
65
|
collector << "POW("
|
65
66
|
o.expressions.each_with_index { |arg, i|
|
@@ -70,6 +71,13 @@ module ArelExtensions
|
|
70
71
|
collector
|
71
72
|
end
|
72
73
|
|
74
|
+
def visit_ArelExtensions_Nodes_Sum o, collector
|
75
|
+
collector << "SUM("
|
76
|
+
collector = visit o.expr, collector
|
77
|
+
collector << ")"
|
78
|
+
collector
|
79
|
+
end
|
80
|
+
|
73
81
|
# String functions
|
74
82
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
75
83
|
collector << "CONCAT("
|
@@ -84,9 +92,9 @@ module ArelExtensions
|
|
84
92
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
85
93
|
collector << "GROUP_CONCAT("
|
86
94
|
collector = visit o.left, collector
|
87
|
-
if o.
|
95
|
+
if o.separator && o.separator != 'NULL'
|
88
96
|
collector << Arel::Visitors::ToSql::COMMA
|
89
|
-
collector = visit o.
|
97
|
+
collector = visit o.separator, collector
|
90
98
|
end
|
91
99
|
collector << ")"
|
92
100
|
collector
|
@@ -127,14 +135,26 @@ module ArelExtensions
|
|
127
135
|
|
128
136
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
129
137
|
collector << "REPLACE("
|
130
|
-
o.
|
131
|
-
|
132
|
-
|
133
|
-
|
138
|
+
visit o.left, collector
|
139
|
+
collector << Arel::Visitors::ToSql::COMMA
|
140
|
+
visit o.pattern, collector
|
141
|
+
collector << Arel::Visitors::ToSql::COMMA
|
142
|
+
visit o.substitute, collector
|
134
143
|
collector << ")"
|
135
144
|
collector
|
136
145
|
end
|
137
|
-
|
146
|
+
|
147
|
+
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
148
|
+
collector << "REGEXP_REPLACE("
|
149
|
+
visit o.left, collector
|
150
|
+
collector << Arel::Visitors::ToSql::COMMA
|
151
|
+
visit Arel::Nodes.build_quoted(o.pattern.to_s), collector
|
152
|
+
collector << Arel::Visitors::ToSql::COMMA
|
153
|
+
visit o.substitute, collector
|
154
|
+
collector << ")"
|
155
|
+
collector
|
156
|
+
end
|
157
|
+
|
138
158
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
139
159
|
collector << "REPEAT("
|
140
160
|
o.expressions.each_with_index { |arg, i|
|
@@ -269,12 +289,12 @@ module ArelExtensions
|
|
269
289
|
as_attr = Arel::Nodes::SqlLiteral.new('int')
|
270
290
|
when :decimal, :float, :number
|
271
291
|
as_attr = Arel::Nodes::SqlLiteral.new('float')
|
272
|
-
when :datetime
|
292
|
+
when :datetime
|
273
293
|
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
274
294
|
when :time
|
275
295
|
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
276
|
-
when :binary
|
277
|
-
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
296
|
+
when :binary
|
297
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
278
298
|
else
|
279
299
|
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
280
300
|
end
|
@@ -305,7 +325,7 @@ module ArelExtensions
|
|
305
325
|
collector << ")"
|
306
326
|
collector
|
307
327
|
end
|
308
|
-
|
328
|
+
|
309
329
|
def visit_ArelExtensions_Nodes_DateSub o, collector
|
310
330
|
collector << "DATE_SUB("
|
311
331
|
collector = visit o.left, collector
|
@@ -384,7 +404,7 @@ module ArelExtensions
|
|
384
404
|
collector = visit o.left, collector
|
385
405
|
collector << ") THEN "
|
386
406
|
collector = visit o.right, collector
|
387
|
-
if o.expressions[2]
|
407
|
+
if o.expressions[2]
|
388
408
|
collector << " ELSE "
|
389
409
|
collector = visit o.expressions[2], collector
|
390
410
|
end
|
@@ -408,16 +428,15 @@ module ArelExtensions
|
|
408
428
|
row_nb = o.left.length
|
409
429
|
o.left.each_with_index do |row, idx|
|
410
430
|
collector << '('
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
431
|
+
len = row.length - 1
|
432
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
433
|
+
case value
|
434
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
435
|
+
collector = visit value, collector
|
436
|
+
else
|
437
|
+
collector << quote(value, attr && column_for(attr)).to_s
|
438
|
+
end
|
439
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
421
440
|
}
|
422
441
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
423
442
|
end
|
@@ -429,16 +448,17 @@ module ArelExtensions
|
|
429
448
|
row_nb = o.left.length
|
430
449
|
o.left.each_with_index do |row, idx|
|
431
450
|
collector << '('
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
451
|
+
len = row.length - 1
|
452
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
453
|
+
case value
|
454
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
455
|
+
collector = visit value, collector
|
456
|
+
when Integer
|
457
|
+
collector << value.to_s
|
458
|
+
else
|
459
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
460
|
+
end
|
461
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
442
462
|
}
|
443
463
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
444
464
|
end
|
@@ -452,7 +472,7 @@ module ArelExtensions
|
|
452
472
|
collector = visit o.right, collector
|
453
473
|
collector
|
454
474
|
end
|
455
|
-
|
475
|
+
|
456
476
|
def visit_ArelExtensions_Nodes_UnionAll o, collector
|
457
477
|
collector = visit o.left, collector
|
458
478
|
collector << " UNION ALL "
|
@@ -489,25 +509,25 @@ module ArelExtensions
|
|
489
509
|
visit Arel::Nodes.build_quoted(o.expr), collector
|
490
510
|
end
|
491
511
|
|
492
|
-
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
512
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
493
513
|
visit o.left, collector
|
494
514
|
end
|
495
|
-
|
496
|
-
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
515
|
+
|
516
|
+
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
497
517
|
def visit_Arel_Nodes_LessThan o, collector
|
498
518
|
collector = visit o.left, collector
|
499
519
|
collector << " < "
|
500
520
|
visit o.right, collector
|
501
521
|
end
|
502
|
-
|
503
|
-
def visit_ArelExtensions_Nodes_Std o, collector
|
522
|
+
|
523
|
+
def visit_ArelExtensions_Nodes_Std o, collector
|
504
524
|
collector << "STD("
|
505
525
|
visit o.left, collector
|
506
526
|
collector << ")"
|
507
527
|
collector
|
508
528
|
end
|
509
|
-
|
510
|
-
def visit_ArelExtensions_Nodes_Variance o, collector
|
529
|
+
|
530
|
+
def visit_ArelExtensions_Nodes_Variance o, collector
|
511
531
|
collector << "VARIANCE("
|
512
532
|
visit o.left, collector
|
513
533
|
collector << ")"
|
@@ -523,11 +543,13 @@ module ArelExtensions
|
|
523
543
|
collector
|
524
544
|
end
|
525
545
|
|
546
|
+
# Boolean logic.
|
547
|
+
|
526
548
|
alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
|
527
549
|
def visit_Arel_Nodes_And o, collector
|
528
550
|
case o.children.length
|
529
551
|
when 0
|
530
|
-
collector << '1=1' # but this should not happen
|
552
|
+
collector << '1 = 1' # but this should not happen
|
531
553
|
when 1
|
532
554
|
collector = visit o.children[0], collector
|
533
555
|
else
|
@@ -543,10 +565,11 @@ module ArelExtensions
|
|
543
565
|
collector
|
544
566
|
end
|
545
567
|
|
546
|
-
|
568
|
+
alias_method :old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or
|
569
|
+
def visit_Arel_Nodes_Or o, collector
|
547
570
|
case o.children.length
|
548
571
|
when 0
|
549
|
-
collector << '0
|
572
|
+
collector << '1 = 0' # but this should not happen
|
550
573
|
when 1
|
551
574
|
collector = visit o.children[0], collector
|
552
575
|
else
|
@@ -562,16 +585,6 @@ module ArelExtensions
|
|
562
585
|
collector
|
563
586
|
end
|
564
587
|
|
565
|
-
alias_method :old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or
|
566
|
-
def visit_Arel_Nodes_Or o, collector
|
567
|
-
collector << '('
|
568
|
-
collector = visit o.left, collector
|
569
|
-
collector << ') OR ('
|
570
|
-
collector = visit o.right, collector
|
571
|
-
collector << ')'
|
572
|
-
collector
|
573
|
-
end
|
574
|
-
|
575
588
|
def visit_ArelExtensions_Nodes_Json o,collector
|
576
589
|
case o.dict
|
577
590
|
when Array
|
@@ -611,7 +624,7 @@ module ArelExtensions
|
|
611
624
|
|
612
625
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
613
626
|
if o.as_array
|
614
|
-
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ',o.orders) : o.dict.group_concat(', ')) + ']'
|
627
|
+
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ', order: Array(o.orders)) : o.dict.group_concat(', ')).coalesce('') + ']'
|
615
628
|
collector = visit res, collector
|
616
629
|
else
|
617
630
|
res = Arel::Nodes.build_quoted('{')
|
@@ -626,7 +639,7 @@ module ArelExtensions
|
|
626
639
|
else
|
627
640
|
kv += v
|
628
641
|
end
|
629
|
-
res = res + kv.group_concat(', ',orders)
|
642
|
+
res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
|
630
643
|
end
|
631
644
|
res = res + '}'
|
632
645
|
collector = visit res, collector
|