arel_extensions 2.0.1 → 2.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -4
- data/.travis.yml +59 -91
- data/Gemfile +14 -19
- data/README.md +17 -12
- data/Rakefile +38 -27
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +2 -2
- 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 +15 -13
- 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 +43 -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 +89 -39
- data/lib/arel_extensions/visitors/oracle.rb +15 -15
- 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 +61 -53
- data/lib/arel_extensions/visitors/to_sql.rb +93 -73
- data/test/arelx_test_helper.rb +28 -0
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +1 -1
- 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 +14 -7
- data/test/helper.rb +0 -18
@@ -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("
|
204
210
|
collector = visit o.left, collector
|
205
|
-
collector << ")
|
211
|
+
collector << " AS INT) = "
|
206
212
|
collector = visit o.left, collector
|
207
|
-
collector << "
|
213
|
+
collector << " THEN CAST("
|
214
|
+
collector = visit o.left, collector
|
215
|
+
collector << " AS INT) ELSE CAST(("
|
216
|
+
collector = visit o.left, 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
|
@@ -249,19 +258,24 @@ module ArelExtensions
|
|
249
258
|
o.left.each_with_index do |row, idx|
|
250
259
|
collector << 'SELECT '
|
251
260
|
len = row.length - 1
|
252
|
-
row.each_with_index { |value, i|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
261
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
262
|
+
case value
|
263
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
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
|
271
|
+
else
|
272
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
273
|
+
if idx == 0
|
274
|
+
collector << " AS "
|
275
|
+
collector << quote(attr.name)
|
276
|
+
end
|
262
277
|
end
|
263
|
-
|
264
|
-
collector << Arel::Visitors::SQLite::COMMA unless i == len
|
278
|
+
collector << Arel::Visitors::SQLite::COMMA unless i == len
|
265
279
|
}
|
266
280
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
267
281
|
end
|
@@ -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,7 +1,7 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
|
-
Arel::Visitors::ToSql::COMMA =
|
3
|
+
class Arel::Visitors::ToSql
|
4
|
+
Arel::Visitors::ToSql::COMMA = ', ' unless defined?(Arel::Visitors::ToSql::COMMA)
|
5
5
|
|
6
6
|
# Math Functions
|
7
7
|
def visit_ArelExtensions_Nodes_Abs o, collector
|
@@ -53,14 +53,14 @@ module ArelExtensions
|
|
53
53
|
collector << ")"
|
54
54
|
collector
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
58
58
|
collector << "LOG10("
|
59
59
|
collector = visit o.left, collector
|
60
60
|
collector << ")"
|
61
61
|
collector
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def visit_ArelExtensions_Nodes_Power o, collector
|
65
65
|
collector << "POW("
|
66
66
|
o.expressions.each_with_index { |arg, i|
|
@@ -71,6 +71,13 @@ module ArelExtensions
|
|
71
71
|
collector
|
72
72
|
end
|
73
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
|
+
|
74
81
|
# String functions
|
75
82
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
76
83
|
collector << "CONCAT("
|
@@ -85,9 +92,9 @@ module ArelExtensions
|
|
85
92
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
86
93
|
collector << "GROUP_CONCAT("
|
87
94
|
collector = visit o.left, collector
|
88
|
-
if o.
|
95
|
+
if o.separator && o.separator != 'NULL'
|
89
96
|
collector << Arel::Visitors::ToSql::COMMA
|
90
|
-
collector = visit o.
|
97
|
+
collector = visit o.separator, collector
|
91
98
|
end
|
92
99
|
collector << ")"
|
93
100
|
collector
|
@@ -128,14 +135,26 @@ module ArelExtensions
|
|
128
135
|
|
129
136
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
130
137
|
collector << "REPLACE("
|
131
|
-
o.
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
143
|
+
collector << ")"
|
144
|
+
collector
|
145
|
+
end
|
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
|
135
154
|
collector << ")"
|
136
155
|
collector
|
137
156
|
end
|
138
|
-
|
157
|
+
|
139
158
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
140
159
|
collector << "REPEAT("
|
141
160
|
o.expressions.each_with_index { |arg, i|
|
@@ -270,12 +289,12 @@ module ArelExtensions
|
|
270
289
|
as_attr = Arel::Nodes::SqlLiteral.new('int')
|
271
290
|
when :decimal, :float, :number
|
272
291
|
as_attr = Arel::Nodes::SqlLiteral.new('float')
|
273
|
-
when :datetime
|
292
|
+
when :datetime
|
274
293
|
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
275
294
|
when :time
|
276
295
|
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
277
|
-
when :binary
|
278
|
-
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
296
|
+
when :binary
|
297
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
279
298
|
else
|
280
299
|
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
281
300
|
end
|
@@ -306,7 +325,7 @@ module ArelExtensions
|
|
306
325
|
collector << ")"
|
307
326
|
collector
|
308
327
|
end
|
309
|
-
|
328
|
+
|
310
329
|
def visit_ArelExtensions_Nodes_DateSub o, collector
|
311
330
|
collector << "DATE_SUB("
|
312
331
|
collector = visit o.left, collector
|
@@ -385,7 +404,7 @@ module ArelExtensions
|
|
385
404
|
collector = visit o.left, collector
|
386
405
|
collector << ") THEN "
|
387
406
|
collector = visit o.right, collector
|
388
|
-
if o.expressions[2]
|
407
|
+
if o.expressions[2]
|
389
408
|
collector << " ELSE "
|
390
409
|
collector = visit o.expressions[2], collector
|
391
410
|
end
|
@@ -409,16 +428,15 @@ module ArelExtensions
|
|
409
428
|
row_nb = o.left.length
|
410
429
|
o.left.each_with_index do |row, idx|
|
411
430
|
collector << '('
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
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
|
422
440
|
}
|
423
441
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
424
442
|
end
|
@@ -431,15 +449,16 @@ module ArelExtensions
|
|
431
449
|
o.left.each_with_index do |row, idx|
|
432
450
|
collector << '('
|
433
451
|
len = row.length - 1
|
434
|
-
row.each_with_index { |value, i|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
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
|
443
462
|
}
|
444
463
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
445
464
|
end
|
@@ -453,7 +472,7 @@ module ArelExtensions
|
|
453
472
|
collector = visit o.right, collector
|
454
473
|
collector
|
455
474
|
end
|
456
|
-
|
475
|
+
|
457
476
|
def visit_ArelExtensions_Nodes_UnionAll o, collector
|
458
477
|
collector = visit o.left, collector
|
459
478
|
collector << " UNION ALL "
|
@@ -490,25 +509,25 @@ module ArelExtensions
|
|
490
509
|
visit Arel::Nodes.build_quoted(o.expr), collector
|
491
510
|
end
|
492
511
|
|
493
|
-
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
512
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
494
513
|
visit o.left, collector
|
495
514
|
end
|
496
|
-
|
497
|
-
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
515
|
+
|
516
|
+
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
498
517
|
def visit_Arel_Nodes_LessThan o, collector
|
499
518
|
collector = visit o.left, collector
|
500
519
|
collector << " < "
|
501
520
|
visit o.right, collector
|
502
521
|
end
|
503
|
-
|
504
|
-
def visit_ArelExtensions_Nodes_Std o, collector
|
522
|
+
|
523
|
+
def visit_ArelExtensions_Nodes_Std o, collector
|
505
524
|
collector << "STD("
|
506
525
|
visit o.left, collector
|
507
526
|
collector << ")"
|
508
527
|
collector
|
509
528
|
end
|
510
|
-
|
511
|
-
def visit_ArelExtensions_Nodes_Variance o, collector
|
529
|
+
|
530
|
+
def visit_ArelExtensions_Nodes_Variance o, collector
|
512
531
|
collector << "VARIANCE("
|
513
532
|
visit o.left, collector
|
514
533
|
collector << ")"
|
@@ -524,11 +543,13 @@ module ArelExtensions
|
|
524
543
|
collector
|
525
544
|
end
|
526
545
|
|
546
|
+
# Boolean logic.
|
547
|
+
|
527
548
|
alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
|
528
549
|
def visit_Arel_Nodes_And o, collector
|
529
550
|
case o.children.length
|
530
551
|
when 0
|
531
|
-
collector << '1=1' # but this should not happen
|
552
|
+
collector << '1 = 1' # but this should not happen
|
532
553
|
when 1
|
533
554
|
collector = visit o.children[0], collector
|
534
555
|
else
|
@@ -544,10 +565,11 @@ module ArelExtensions
|
|
544
565
|
collector
|
545
566
|
end
|
546
567
|
|
547
|
-
|
568
|
+
alias_method :old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or
|
569
|
+
def visit_Arel_Nodes_Or o, collector
|
548
570
|
case o.children.length
|
549
571
|
when 0
|
550
|
-
collector << '0
|
572
|
+
collector << '1 = 0' # but this should not happen
|
551
573
|
when 1
|
552
574
|
collector = visit o.children[0], collector
|
553
575
|
else
|
@@ -563,14 +585,24 @@ module ArelExtensions
|
|
563
585
|
collector
|
564
586
|
end
|
565
587
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
588
|
+
def json_value(o,v)
|
589
|
+
case o.type_of_node(v)
|
590
|
+
when :string
|
591
|
+
Arel.when(v.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + v.replace('\\','\\\\').replace('"','\"') + '"')
|
592
|
+
when :date
|
593
|
+
s = v.format('%Y-%m-%d')
|
594
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
595
|
+
when :datetime
|
596
|
+
s = v.format('%Y-%m-%dT%H:%M:%S')
|
597
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
598
|
+
when :time
|
599
|
+
s = v.format('%H:%M:%S')
|
600
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
601
|
+
when :nil
|
602
|
+
Arel::Nodes.build_quoted("null")
|
603
|
+
else
|
604
|
+
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce("null")
|
605
|
+
end
|
574
606
|
end
|
575
607
|
|
576
608
|
def visit_ArelExtensions_Nodes_Json o,collector
|
@@ -581,11 +613,7 @@ module ArelExtensions
|
|
581
613
|
if i != 0
|
582
614
|
res += ', '
|
583
615
|
end
|
584
|
-
|
585
|
-
res = res + '"' + v + '"'
|
586
|
-
else
|
587
|
-
res += v
|
588
|
-
end
|
616
|
+
res += json_value(o,v)
|
589
617
|
end
|
590
618
|
res += ']'
|
591
619
|
collector = visit res, collector
|
@@ -595,12 +623,8 @@ module ArelExtensions
|
|
595
623
|
if i != 0
|
596
624
|
res += ', '
|
597
625
|
end
|
598
|
-
res += Arel::Nodes.build_quoted('"')+k + '": '
|
599
|
-
|
600
|
-
res = res + '"' + v + '"'
|
601
|
-
else
|
602
|
-
res += v
|
603
|
-
end
|
626
|
+
res += Arel::Nodes.build_quoted('"') + ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("").replace('\\','\\\\').replace('"','\"') + '": '
|
627
|
+
res += json_value(o,v)
|
604
628
|
end
|
605
629
|
res += '}'
|
606
630
|
collector = visit res, collector
|
@@ -612,7 +636,7 @@ module ArelExtensions
|
|
612
636
|
|
613
637
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
614
638
|
if o.as_array
|
615
|
-
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ',o.orders) : o.dict.group_concat(', ')) + ']'
|
639
|
+
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ', order: Array(o.orders)) : o.dict.group_concat(', ')).coalesce('') + ']'
|
616
640
|
collector = visit res, collector
|
617
641
|
else
|
618
642
|
res = Arel::Nodes.build_quoted('{')
|
@@ -621,13 +645,9 @@ module ArelExtensions
|
|
621
645
|
if i != 0
|
622
646
|
res = res + ', '
|
623
647
|
end
|
624
|
-
kv = Arel::Nodes.build_quoted('"')+k + '": '
|
625
|
-
|
626
|
-
|
627
|
-
else
|
628
|
-
kv += v
|
629
|
-
end
|
630
|
-
res = res + kv.group_concat(', ',orders)
|
648
|
+
kv = Arel::Nodes.build_quoted('"') + ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("").replace('\\','\\\\').replace('"','\"') + '": '
|
649
|
+
kv += json_value(o,v)
|
650
|
+
res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
|
631
651
|
end
|
632
652
|
res = res + '}'
|
633
653
|
collector = visit res, collector
|