arel_extensions 2.3.3 → 2.5.0

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +92 -43
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +131 -5
  5. data/Makefile +48 -0
  6. data/NEWS.md +22 -0
  7. data/README.md +32 -5
  8. data/Rakefile +5 -3
  9. data/arel_extensions.gemspec +3 -5
  10. data/dev/arelx.dockerfile +13 -16
  11. data/dev/compose.yaml +26 -28
  12. data/gemfiles/rails5.gemfile +15 -8
  13. data/gemfiles/rails5_1_4.gemfile +11 -9
  14. data/gemfiles/rails5_2.gemfile +16 -9
  15. data/gemfiles/rails6.gemfile +13 -7
  16. data/gemfiles/rails6_1.gemfile +13 -7
  17. data/gemfiles/rails7.gemfile +15 -9
  18. data/gemfiles/rails7_1.gemfile +15 -8
  19. data/gemfiles/rails7_2.gemfile +12 -6
  20. data/gemfiles/rails8.gemfile +40 -0
  21. data/gemfiles/rails8_1.gemfile +41 -0
  22. data/gemspecs/arel_extensions-v1.gemspec +3 -5
  23. data/gemspecs/arel_extensions-v2.gemspec +3 -5
  24. data/lib/arel_extensions/aliases.rb +3 -3
  25. data/lib/arel_extensions/attributes.rb +2 -0
  26. data/lib/arel_extensions/boolean_functions.rb +9 -7
  27. data/lib/arel_extensions/common_sql_functions.rb +5 -3
  28. data/lib/arel_extensions/comparators.rb +6 -4
  29. data/lib/arel_extensions/constants.rb +13 -0
  30. data/lib/arel_extensions/date_duration.rb +2 -0
  31. data/lib/arel_extensions/helpers.rb +18 -19
  32. data/lib/arel_extensions/insert_manager.rb +5 -1
  33. data/lib/arel_extensions/math.rb +40 -44
  34. data/lib/arel_extensions/math_functions.rb +29 -31
  35. data/lib/arel_extensions/nodes/aggregate_function.rb +4 -4
  36. data/lib/arel_extensions/nodes/blank.rb +6 -4
  37. data/lib/arel_extensions/nodes/byte_size.rb +11 -0
  38. data/lib/arel_extensions/nodes/case.rb +16 -13
  39. data/lib/arel_extensions/nodes/cast.rb +3 -5
  40. data/lib/arel_extensions/nodes/char_length.rb +11 -0
  41. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  42. data/lib/arel_extensions/nodes/collate.rb +1 -1
  43. data/lib/arel_extensions/nodes/concat.rb +6 -6
  44. data/lib/arel_extensions/nodes/date_diff.rb +40 -49
  45. data/lib/arel_extensions/nodes/duration.rb +2 -2
  46. data/lib/arel_extensions/nodes/format.rb +2 -2
  47. data/lib/arel_extensions/nodes/formatted_date.rb +2 -2
  48. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  49. data/lib/arel_extensions/nodes/function.rb +7 -7
  50. data/lib/arel_extensions/nodes/is_null.rb +2 -0
  51. data/lib/arel_extensions/nodes/json.rb +27 -15
  52. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  53. data/lib/arel_extensions/nodes/locate.rb +1 -1
  54. data/lib/arel_extensions/nodes/matches.rb +2 -2
  55. data/lib/arel_extensions/nodes/power.rb +2 -2
  56. data/lib/arel_extensions/nodes/rand.rb +2 -2
  57. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  58. data/lib/arel_extensions/nodes/replace.rb +3 -3
  59. data/lib/arel_extensions/nodes/rollup.rb +4 -4
  60. data/lib/arel_extensions/nodes/round.rb +3 -3
  61. data/lib/arel_extensions/nodes/select.rb +1 -1
  62. data/lib/arel_extensions/nodes/std.rb +4 -4
  63. data/lib/arel_extensions/nodes/substring.rb +52 -2
  64. data/lib/arel_extensions/nodes/then.rb +1 -1
  65. data/lib/arel_extensions/nodes/trim.rb +2 -2
  66. data/lib/arel_extensions/nodes/union.rb +3 -3
  67. data/lib/arel_extensions/nodes/union_all.rb +3 -3
  68. data/lib/arel_extensions/nodes/wday.rb +2 -2
  69. data/lib/arel_extensions/null_functions.rb +5 -7
  70. data/lib/arel_extensions/predications.rb +23 -19
  71. data/lib/arel_extensions/string_functions.rb +37 -28
  72. data/lib/arel_extensions/version.rb +3 -1
  73. data/lib/arel_extensions/visitors/convert_format.rb +2 -2
  74. data/lib/arel_extensions/visitors/ibm_db.rb +5 -5
  75. data/lib/arel_extensions/visitors/mssql.rb +111 -97
  76. data/lib/arel_extensions/visitors/mysql.rb +101 -67
  77. data/lib/arel_extensions/visitors/oracle.rb +113 -103
  78. data/lib/arel_extensions/visitors/oracle12.rb +5 -6
  79. data/lib/arel_extensions/visitors/postgresql.rb +119 -92
  80. data/lib/arel_extensions/visitors/sqlite.rb +72 -64
  81. data/lib/arel_extensions/visitors/to_sql.rb +85 -75
  82. data/lib/arel_extensions/visitors.rb +7 -7
  83. data/lib/arel_extensions/warning.rb +5 -5
  84. data/lib/arel_extensions.rb +47 -31
  85. data/test/arelx_test_helper.rb +8 -6
  86. data/test/config_loader.rb +9 -0
  87. data/test/database.yml +8 -6
  88. data/test/real_db_test.rb +33 -33
  89. data/test/support/fake_record.rb +3 -1
  90. data/test/visitors/test_bulk_insert_oracle.rb +2 -2
  91. data/test/visitors/test_bulk_insert_sqlite.rb +2 -2
  92. data/test/visitors/test_to_sql.rb +2 -2
  93. data/test/with_ar/all_agnostic_test.rb +214 -32
  94. data/test/with_ar/insert_agnostic_test.rb +2 -2
  95. data/test/with_ar/test_bulk_sqlite.rb +2 -2
  96. data/test/with_ar/test_math_sqlite.rb +2 -2
  97. data/test/with_ar/test_string_mysql.rb +2 -2
  98. data/test/with_ar/test_string_sqlite.rb +2 -2
  99. data/version_v1.rb +3 -1
  100. data/version_v2.rb +3 -1
  101. metadata +9 -33
  102. data/bin/compose +0 -6
  103. data/gemfiles/rails3.gemfile +0 -20
  104. data/gemfiles/rails4_2.gemfile +0 -38
@@ -5,7 +5,7 @@ module ArelExtensions
5
5
 
6
6
  # Escape properly the string expression expr.
7
7
  # Take care of escaping.
8
- def make_json_string expr
8
+ def make_json_string(expr)
9
9
  Arel.quoted('"') \
10
10
  + expr
11
11
  .coalesce('')
@@ -24,7 +24,7 @@ module ArelExtensions
24
24
  end
25
25
 
26
26
  # Math Functions
27
- def visit_ArelExtensions_Nodes_Abs o, collector
27
+ def visit_ArelExtensions_Nodes_Abs(o, collector)
28
28
  collector << 'ABS('
29
29
  o.expressions.each_with_index { |arg, i|
30
30
  collector << COMMA if i != 0
@@ -34,7 +34,7 @@ module ArelExtensions
34
34
  collector
35
35
  end
36
36
 
37
- def visit_ArelExtensions_Nodes_Ceil o, collector
37
+ def visit_ArelExtensions_Nodes_Ceil(o, collector)
38
38
  collector << 'CEIL('
39
39
  o.expressions.each_with_index { |arg, i|
40
40
  collector << COMMA if i != 0
@@ -44,7 +44,7 @@ module ArelExtensions
44
44
  collector
45
45
  end
46
46
 
47
- def visit_ArelExtensions_Nodes_Floor o, collector
47
+ def visit_ArelExtensions_Nodes_Floor(o, collector)
48
48
  collector << 'FLOOR('
49
49
  o.expressions.each_with_index { |arg, i|
50
50
  collector << COMMA if i != 0
@@ -54,7 +54,7 @@ module ArelExtensions
54
54
  collector
55
55
  end
56
56
 
57
- def visit_ArelExtensions_Nodes_Rand o, collector
57
+ def visit_ArelExtensions_Nodes_Rand(o, collector)
58
58
  collector << 'RAND('
59
59
  o.expressions.each_with_index { |arg, i|
60
60
  collector << COMMA if i != 0
@@ -64,7 +64,7 @@ module ArelExtensions
64
64
  collector
65
65
  end
66
66
 
67
- def visit_ArelExtensions_Nodes_Round o, collector
67
+ def visit_ArelExtensions_Nodes_Round(o, collector)
68
68
  collector << 'ROUND('
69
69
  o.expressions.each_with_index { |arg, i|
70
70
  collector << COMMA if i != 0
@@ -74,14 +74,14 @@ module ArelExtensions
74
74
  collector
75
75
  end
76
76
 
77
- def visit_ArelExtensions_Nodes_Log10 o, collector
77
+ def visit_ArelExtensions_Nodes_Log10(o, collector)
78
78
  collector << 'LOG10('
79
79
  collector = visit o.left, collector
80
80
  collector << ')'
81
81
  collector
82
82
  end
83
83
 
84
- def visit_ArelExtensions_Nodes_Power o, collector
84
+ def visit_ArelExtensions_Nodes_Power(o, collector)
85
85
  collector << 'POW('
86
86
  o.expressions.each_with_index { |arg, i|
87
87
  collector << COMMA if i != 0
@@ -91,7 +91,7 @@ module ArelExtensions
91
91
  collector
92
92
  end
93
93
 
94
- def visit_ArelExtensions_Nodes_Sum o, collector
94
+ def visit_ArelExtensions_Nodes_Sum(o, collector)
95
95
  collector << 'SUM('
96
96
  collector = visit o.expr, collector
97
97
  collector << ')'
@@ -99,7 +99,7 @@ module ArelExtensions
99
99
  end
100
100
 
101
101
  # String functions
102
- def visit_ArelExtensions_Nodes_Concat o, collector
102
+ def visit_ArelExtensions_Nodes_Concat(o, collector)
103
103
  collector << 'CONCAT('
104
104
  o.expressions.each_with_index { |arg, i|
105
105
  collector << COMMA if i != 0
@@ -109,7 +109,7 @@ module ArelExtensions
109
109
  collector
110
110
  end
111
111
 
112
- def visit_ArelExtensions_Nodes_GroupConcat o, collector
112
+ def visit_ArelExtensions_Nodes_GroupConcat(o, collector)
113
113
  collector << 'GROUP_CONCAT('
114
114
  collector = visit o.left, collector
115
115
  sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
@@ -121,7 +121,7 @@ module ArelExtensions
121
121
  collector
122
122
  end
123
123
 
124
- def visit_ArelExtensions_Nodes_MD5 o, collector
124
+ def visit_ArelExtensions_Nodes_MD5(o, collector)
125
125
  collector << 'MD5('
126
126
  collector = visit o.left, collector
127
127
  collector << ')'
@@ -135,7 +135,7 @@ module ArelExtensions
135
135
  collector
136
136
  end
137
137
 
138
- def visit_ArelExtensions_Nodes_Locate o, collector
138
+ def visit_ArelExtensions_Nodes_Locate(o, collector)
139
139
  collector << 'LOCATE('
140
140
  collector = visit o.right, collector
141
141
  collector << COMMA
@@ -144,7 +144,9 @@ module ArelExtensions
144
144
  collector
145
145
  end
146
146
 
147
- def visit_ArelExtensions_Nodes_Substring o, collector
147
+ def visit_ArelExtensions_Nodes_Substring(o, collector)
148
+ return visit(o.range_substring_node, collector) if o.range?
149
+
148
150
  collector << 'SUBSTRING('
149
151
  o.expressions.each_with_index { |arg, i|
150
152
  collector << COMMA if i != 0
@@ -154,7 +156,7 @@ module ArelExtensions
154
156
  collector
155
157
  end
156
158
 
157
- def visit_ArelExtensions_Nodes_Replace o, collector
159
+ def visit_ArelExtensions_Nodes_Replace(o, collector)
158
160
  collector << 'REPLACE('
159
161
  visit o.left, collector
160
162
  collector << COMMA
@@ -165,7 +167,7 @@ module ArelExtensions
165
167
  collector
166
168
  end
167
169
 
168
- def visit_ArelExtensions_Nodes_RegexpReplace o, collector
170
+ def visit_ArelExtensions_Nodes_RegexpReplace(o, collector)
169
171
  collector << 'REGEXP_REPLACE('
170
172
  visit o.left, collector
171
173
  collector << COMMA
@@ -176,7 +178,7 @@ module ArelExtensions
176
178
  collector
177
179
  end
178
180
 
179
- def visit_ArelExtensions_Nodes_Repeat o, collector
181
+ def visit_ArelExtensions_Nodes_Repeat(o, collector)
180
182
  collector << 'REPEAT('
181
183
  o.expressions.each_with_index { |arg, i|
182
184
  collector << COMMA if i != 0
@@ -186,7 +188,7 @@ module ArelExtensions
186
188
  collector
187
189
  end
188
190
 
189
- def visit_ArelExtensions_Nodes_FindInSet o, collector
191
+ def visit_ArelExtensions_Nodes_FindInSet(o, collector)
190
192
  collector << 'FIND_IN_SET('
191
193
  o.expressions.each_with_index { |arg, i|
192
194
  collector << COMMA if i != 0
@@ -196,7 +198,7 @@ module ArelExtensions
196
198
  collector
197
199
  end
198
200
 
199
- def visit_ArelExtensions_Nodes_Soundex o, collector
201
+ def visit_ArelExtensions_Nodes_Soundex(o, collector)
200
202
  collector << 'SOUNDEX('
201
203
  o.expressions.each_with_index { |arg, i|
202
204
  collector << COMMA if i != 0
@@ -206,7 +208,7 @@ module ArelExtensions
206
208
  collector
207
209
  end
208
210
 
209
- def visit_ArelExtensions_Nodes_Downcase o, collector
211
+ def visit_ArelExtensions_Nodes_Downcase(o, collector)
210
212
  collector << 'LOWER('
211
213
  o.expressions.each_with_index { |arg, i|
212
214
  collector << COMMA if i != 0
@@ -216,7 +218,7 @@ module ArelExtensions
216
218
  collector
217
219
  end
218
220
 
219
- def visit_ArelExtensions_Nodes_Upcase o, collector
221
+ def visit_ArelExtensions_Nodes_Upcase(o, collector)
220
222
  collector << 'UPPER('
221
223
  o.expressions.each_with_index { |arg, i|
222
224
  collector << COMMA if i != 0
@@ -226,7 +228,7 @@ module ArelExtensions
226
228
  collector
227
229
  end
228
230
 
229
- def visit_ArelExtensions_Nodes_Trim o, collector
231
+ def visit_ArelExtensions_Nodes_Trim(o, collector)
230
232
  collector << 'TRIM('
231
233
  o.expressions.each_with_index { |arg, i|
232
234
  collector << COMMA if i != 0
@@ -236,7 +238,7 @@ module ArelExtensions
236
238
  collector
237
239
  end
238
240
 
239
- def visit_ArelExtensions_Nodes_Ltrim o, collector
241
+ def visit_ArelExtensions_Nodes_Ltrim(o, collector)
240
242
  collector << 'LTRIM('
241
243
  o.expressions.each_with_index { |arg, i|
242
244
  collector << COMMA if i != 0
@@ -246,7 +248,7 @@ module ArelExtensions
246
248
  collector
247
249
  end
248
250
 
249
- def visit_ArelExtensions_Nodes_Rtrim o, collector
251
+ def visit_ArelExtensions_Nodes_Rtrim(o, collector)
250
252
  collector << 'RTRIM('
251
253
  o.expressions.each_with_index { |arg, i|
252
254
  collector << COMMA if i != 0
@@ -256,7 +258,7 @@ module ArelExtensions
256
258
  collector
257
259
  end
258
260
 
259
- def visit_ArelExtensions_Nodes_Blank o, collector
261
+ def visit_ArelExtensions_Nodes_Blank(o, collector)
260
262
  # visit o.left.coalesce('').trim.length.eq(0), collector
261
263
  collector << 'LENGTH(TRIM(COALESCE('
262
264
  collector = visit o.expr, collector
@@ -266,7 +268,7 @@ module ArelExtensions
266
268
  collector
267
269
  end
268
270
 
269
- def visit_ArelExtensions_Nodes_NotBlank o, collector
271
+ def visit_ArelExtensions_Nodes_NotBlank(o, collector)
270
272
  # visit o.left.coalesce('').trim.length.gt(0), collector
271
273
  collector << 'LENGTH(TRIM(COALESCE('
272
274
  collector = visit o.expr, collector
@@ -276,7 +278,7 @@ module ArelExtensions
276
278
  collector
277
279
  end
278
280
 
279
- def visit_ArelExtensions_Nodes_Format o, collector
281
+ def visit_ArelExtensions_Nodes_Format(o, collector)
280
282
  case o.col_type
281
283
  when :date, :datetime, :time
282
284
  collector << 'STRFTIME('
@@ -296,7 +298,7 @@ module ArelExtensions
296
298
  collector
297
299
  end
298
300
 
299
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
301
+ def visit_ArelExtensions_Nodes_FormattedDate(o, collector)
300
302
  case o.col_type
301
303
  when :date, :datetime, :time
302
304
  collector << 'STRFTIME('
@@ -318,7 +320,7 @@ module ArelExtensions
318
320
 
319
321
  # comparators
320
322
 
321
- def visit_ArelExtensions_Nodes_Cast o, collector
323
+ def visit_ArelExtensions_Nodes_Cast(o, collector)
322
324
  as_attr =
323
325
  case o.as_attr
324
326
  when :binary then 'binary'
@@ -339,7 +341,7 @@ module ArelExtensions
339
341
  collector
340
342
  end
341
343
 
342
- def visit_ArelExtensions_Nodes_Coalesce o, collector
344
+ def visit_ArelExtensions_Nodes_Coalesce(o, collector)
343
345
  collector << 'COALESCE('
344
346
  o.expressions.each_with_index { |arg, i|
345
347
  collector << COMMA if i != 0
@@ -349,9 +351,9 @@ module ArelExtensions
349
351
  collector
350
352
  end
351
353
 
352
- def visit_ArelExtensions_Nodes_DateDiff o, collector
354
+ def visit_ArelExtensions_Nodes_DateDiff(o, collector)
353
355
  collector <<
354
- if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
356
+ if %i[ruby_time datetime time].include?(o.left_node_type)
355
357
  'TIMEDIFF('
356
358
  else
357
359
  'DATEDIFF('
@@ -363,7 +365,7 @@ module ArelExtensions
363
365
  collector
364
366
  end
365
367
 
366
- def visit_ArelExtensions_Nodes_DateSub o, collector
368
+ def visit_ArelExtensions_Nodes_DateSub(o, collector)
367
369
  collector << 'DATE_SUB('
368
370
  collector = visit o.left, collector
369
371
  collector << COMMA
@@ -374,7 +376,7 @@ module ArelExtensions
374
376
 
375
377
  # override
376
378
  remove_method(:visit_Arel_Nodes_As) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_As)
377
- def visit_Arel_Nodes_As o, collector
379
+ def visit_Arel_Nodes_As(o, collector)
378
380
  if o.left.respond_to?(:alias)
379
381
  o.left.alias = nil
380
382
  end
@@ -386,27 +388,24 @@ module ArelExtensions
386
388
  collector = visit o.left, collector
387
389
  end
388
390
  collector << ' AS '
389
- collector = visit o.right, collector
390
- collector
391
+ visit o.right, collector
391
392
  end
392
393
 
393
394
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_Regexp)
394
- def visit_Arel_Nodes_Regexp o, collector
395
+ def visit_Arel_Nodes_Regexp(o, collector)
395
396
  collector = visit o.left, collector
396
397
  collector << ' REGEXP '
397
- collector = visit o.right, collector
398
- collector
398
+ visit o.right, collector
399
399
  end
400
400
 
401
401
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_NotRegexp)
402
- def visit_Arel_Nodes_NotRegexp o, collector
402
+ def visit_Arel_Nodes_NotRegexp(o, collector)
403
403
  collector = visit o.left, collector
404
404
  collector << ' NOT REGEXP '
405
- collector = visit o.right, collector
406
- collector
405
+ visit o.right, collector
407
406
  end
408
407
 
409
- def visit_ArelExtensions_Nodes_IMatches o, collector
408
+ def visit_ArelExtensions_Nodes_IMatches(o, collector)
410
409
  collector = infix_value o, collector, ' ILIKE '
411
410
  if o.escape
412
411
  collector << ' ESCAPE '
@@ -416,7 +415,7 @@ module ArelExtensions
416
415
  end
417
416
  end
418
417
 
419
- def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
418
+ def visit_ArelExtensions_Nodes_IDoesNotMatch(o, collector)
420
419
  collector = infix_value o, collector, ' NOT ILIKE '
421
420
  if o.escape
422
421
  collector << ' ESCAPE '
@@ -425,21 +424,21 @@ module ArelExtensions
425
424
  collector
426
425
  end
427
426
 
428
- def visit_ArelExtensions_Nodes_IsNull o, collector
427
+ def visit_ArelExtensions_Nodes_IsNull(o, collector)
429
428
  collector << 'ISNULL('
430
429
  collector = visit o.expr, collector
431
430
  collector << ')'
432
431
  collector
433
432
  end
434
433
 
435
- def visit_ArelExtensions_Nodes_IsNotNull o, collector
434
+ def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
436
435
  collector << 'NOT ISNULL('
437
436
  collector = visit o.expr, collector
438
437
  collector << ')'
439
438
  collector
440
439
  end
441
440
 
442
- def visit_ArelExtensions_Nodes_Then o, collector
441
+ def visit_ArelExtensions_Nodes_Then(o, collector)
443
442
  collector << 'CASE WHEN ('
444
443
  collector = visit o.left, collector
445
444
  collector << ') THEN '
@@ -453,7 +452,7 @@ module ArelExtensions
453
452
  end
454
453
 
455
454
  # Date operations
456
- def visit_ArelExtensions_Nodes_DateAdd o, collector
455
+ def visit_ArelExtensions_Nodes_DateAdd(o, collector)
457
456
  collector << 'DATE_ADD('
458
457
  collector = visit o.left, collector
459
458
  collector << COMMA
@@ -462,8 +461,8 @@ module ArelExtensions
462
461
  collector
463
462
  end
464
463
 
465
- if Arel::VERSION.to_i < 7
466
- def visit_ArelExtensions_InsertManager_BulkValues o, collector
464
+ if AREL_VERSION < V7
465
+ def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
467
466
  collector << 'VALUES '
468
467
  row_nb = o.left.length
469
468
  o.left.each_with_index do |row, idx|
@@ -483,7 +482,7 @@ module ArelExtensions
483
482
  collector
484
483
  end
485
484
  else
486
- def visit_ArelExtensions_InsertManager_BulkValues o, collector
485
+ def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
487
486
  collector << 'VALUES '
488
487
  row_nb = o.left.length
489
488
  o.left.each_with_index do |row, idx|
@@ -506,21 +505,19 @@ module ArelExtensions
506
505
  end
507
506
  end
508
507
 
509
- def visit_ArelExtensions_Nodes_Union o, collector
508
+ def visit_ArelExtensions_Nodes_Union(o, collector)
510
509
  collector = visit o.left, collector
511
510
  collector << ' UNION '
512
- collector = visit o.right, collector
513
- collector
511
+ visit o.right, collector
514
512
  end
515
513
 
516
- def visit_ArelExtensions_Nodes_UnionAll o, collector
514
+ def visit_ArelExtensions_Nodes_UnionAll(o, collector)
517
515
  collector = visit o.left, collector
518
516
  collector << ' UNION ALL '
519
- collector = visit o.right, collector
520
- collector
517
+ visit o.right, collector
521
518
  end
522
519
 
523
- def visit_ArelExtensions_Nodes_Case o, collector
520
+ def visit_ArelExtensions_Nodes_Case(o, collector)
524
521
  collector << 'CASE '
525
522
  if o.case
526
523
  visit o.case, collector
@@ -537,44 +534,44 @@ module ArelExtensions
537
534
  collector << 'END'
538
535
  end
539
536
 
540
- def visit_ArelExtensions_Nodes_Case_When o, collector
537
+ def visit_ArelExtensions_Nodes_Case_When(o, collector)
541
538
  collector << 'WHEN '
542
539
  visit Arel.quoted(o.left), collector
543
540
  collector << ' THEN '
544
541
  visit Arel.quoted(o.right), collector
545
542
  end
546
543
 
547
- def visit_ArelExtensions_Nodes_Case_Else o, collector
544
+ def visit_ArelExtensions_Nodes_Case_Else(o, collector)
548
545
  collector << 'ELSE '
549
546
  visit Arel.quoted(o.expr), collector
550
547
  end
551
548
 
552
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
549
+ def visit_ArelExtensions_Nodes_FormattedNumber(o, collector)
553
550
  visit o.left, collector
554
551
  end
555
552
 
556
553
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
557
- def visit_Arel_Nodes_LessThan o, collector
554
+ def visit_Arel_Nodes_LessThan(o, collector)
558
555
  collector = visit o.left, collector
559
556
  collector << ' < '
560
557
  visit o.right, collector
561
558
  end
562
559
 
563
- def visit_ArelExtensions_Nodes_Std o, collector
560
+ def visit_ArelExtensions_Nodes_Std(o, collector)
564
561
  collector << 'STD('
565
562
  visit o.left, collector
566
563
  collector << ')'
567
564
  collector
568
565
  end
569
566
 
570
- def visit_ArelExtensions_Nodes_Variance o, collector
567
+ def visit_ArelExtensions_Nodes_Variance(o, collector)
571
568
  collector << 'VARIANCE('
572
569
  visit o.left, collector
573
570
  collector << ')'
574
571
  collector
575
572
  end
576
573
 
577
- def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
574
+ def visit_ArelExtensions_Nodes_LevenshteinDistance(o, collector)
578
575
  collector << 'LEVENSHTEIN_DISTANCE('
579
576
  collector = visit o.left, collector
580
577
  collector << COMMA
@@ -585,8 +582,8 @@ module ArelExtensions
585
582
 
586
583
  # Boolean logic.
587
584
 
588
- alias_method(:old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And) rescue nil
589
- def visit_Arel_Nodes_And o, collector
585
+ alias old_visit_Arel_Nodes_And visit_Arel_Nodes_And rescue nil
586
+ def visit_Arel_Nodes_And(o, collector)
590
587
  case o.children.length
591
588
  when 0
592
589
  collector << '1 = 1' # but this should not happen
@@ -605,8 +602,8 @@ module ArelExtensions
605
602
  collector
606
603
  end
607
604
 
608
- alias_method(:old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or) rescue nil
609
- def visit_Arel_Nodes_Or o, collector
605
+ alias old_visit_Arel_Nodes_Or visit_Arel_Nodes_Or rescue nil
606
+ def visit_Arel_Nodes_Or(o, collector)
610
607
  case o.children.length
611
608
  when 0
612
609
  collector << '1 = 0' # but this should not happen
@@ -627,6 +624,19 @@ module ArelExtensions
627
624
 
628
625
  def json_value(o, v)
629
626
  case o.type_of_node(v)
627
+ when :numeric
628
+ # A bare numeric literal (e.g. `{ col => 1 }`) is never NULL, so it is
629
+ # emitted as-is rather than run through `is_null`/`coalesce`.
630
+ Arel.quoted(v)
631
+ when :boolean
632
+ # A literal boolean is never NULL: emit the JSON token directly.
633
+ # A boolean column is null-checked and rendered as true/false. `eq(true)` rather than the
634
+ # bare column, because T-SQL (mssql) requires a proper boolean predicate in WHEN.
635
+ if o.boolean_literal?(v)
636
+ Arel.quoted((v.is_a?(Arel::Nodes::Quoted) ? v.expr : v).to_s)
637
+ else
638
+ Arel.when(v.is_null).then(make_json_null).else(Arel.when(v.eq(true)).then('true').else('false'))
639
+ end
630
640
  when :string
631
641
  Arel.when(v.is_null).then(make_json_null).else(make_json_string(v))
632
642
  when :date
@@ -645,7 +655,7 @@ module ArelExtensions
645
655
  end
646
656
  end
647
657
 
648
- def visit_ArelExtensions_Nodes_Json o, collector
658
+ def visit_ArelExtensions_Nodes_Json(o, collector)
649
659
  case o.dict
650
660
  when Array
651
661
  res = Arel.quoted('[')
@@ -669,12 +679,12 @@ module ArelExtensions
669
679
  res += '}'
670
680
  collector = visit res, collector
671
681
  else
672
- collector = visit o.dict, collector
682
+ collector = visit(o.boolean_literal?(o.dict) ? Arel.quoted(o.dict.expr.to_s) : o.dict, collector)
673
683
  end
674
684
  collector
675
685
  end
676
686
 
677
- def visit_ArelExtensions_Nodes_JsonGroup o, collector
687
+ def visit_ArelExtensions_Nodes_JsonGroup(o, collector)
678
688
  if o.as_array
679
689
  res =
680
690
  Arel.quoted('[') \
@@ -686,13 +696,13 @@ module ArelExtensions
686
696
  orders = o.orders || o.dict.keys
687
697
  o.dict.each.with_index do |(k, v), i|
688
698
  if i != 0
689
- res = res + ', '
699
+ res += ', '
690
700
  end
691
701
  kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
692
702
  kv += json_value(o, v)
693
- res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
703
+ res += kv.group_concat(', ', order: Array(orders)).coalesce('')
694
704
  end
695
- res = res + '}'
705
+ res += '}'
696
706
  collector = visit res, collector
697
707
  end
698
708
  collector
@@ -14,7 +14,7 @@ if RUBY_PLATFORM == 'java' \
14
14
  warn 'arel/visitors/sqlserver not found: MSSQL might not work correctly.'
15
15
  end
16
16
  elsif RUBY_PLATFORM != 'java' \
17
- && Arel::VERSION.to_i < 10 \
17
+ && ArelExtensions::AREL_VERSION < ArelExtensions::V10 \
18
18
  && Gem::Specification.find { |g| g.name == 'activerecord-sqlserver-adapter' }
19
19
  begin
20
20
  require 'arel_sqlserver'
@@ -43,8 +43,8 @@ end
43
43
 
44
44
  if defined?(Arel::Visitors::DepthFirst)
45
45
  class Arel::Visitors::DepthFirst
46
- def visit_Arel_SelectManager o
47
- visit o.ast
46
+ def visit_Arel_SelectManager(o)
47
+ visit o.ast
48
48
  end
49
49
  end
50
50
  end
@@ -53,8 +53,8 @@ if defined?(Arel::Visitors::MSSQL)
53
53
  class Arel::Visitors::MSSQL
54
54
  include ArelExtensions::Visitors::MSSQL
55
55
 
56
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement)
57
- def visit_Arel_Nodes_SelectStatement o, collector
56
+ alias old_visit_Arel_Nodes_SelectStatement visit_Arel_Nodes_SelectStatement
57
+ def visit_Arel_Nodes_SelectStatement(o, collector)
58
58
  if !collector.value.blank? && o.limit.blank? && o.offset.blank?
59
59
  o = o.dup
60
60
  o.orders = []
@@ -90,8 +90,8 @@ if defined?(Arel::Visitors::SQLServer)
90
90
  # It might be something different, but this is the first thing we should
91
91
  # investigate.
92
92
 
93
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
94
- def visit_Arel_Nodes_SelectStatement o, collector
93
+ alias old_visit_Arel_Nodes_SelectStatement visit_Arel_Nodes_SelectStatement rescue nil
94
+ def visit_Arel_Nodes_SelectStatement(o, collector)
95
95
  if !collector.value.blank? && o.limit.blank? && o.offset.blank?
96
96
  o = o.dup
97
97
  o.orders = []
@@ -1,11 +1,11 @@
1
1
  module ArelExtensions
2
2
  class RubyDeprecator
3
3
  if RUBY_VERSION.split('.')[0].to_i < 3
4
- def warn msg
4
+ def warn(msg)
5
5
  Kernel.warn(msg)
6
6
  end
7
7
  else
8
- def warn msg
8
+ def warn(msg)
9
9
  Kernel.warn(msg, category: :deprecated)
10
10
  end
11
11
  end
@@ -26,14 +26,14 @@ module ArelExtensions
26
26
  major, minor = Gem::Version.create(ArelExtensions::VERSION).segments
27
27
  ActiveSupport::Deprecation.new("#{major}.#{minor}", 'arel_extensions')
28
28
  else
29
- RubyDeprecator::new
29
+ RubyDeprecator.new
30
30
  end
31
31
  end
32
32
 
33
33
  module Warning
34
- def deprecated msg, what: nil
34
+ def deprecated(msg, what: nil)
35
35
  kaller = caller(2..2).first
36
- return if /lib\/(:?arel(?:_extensions)?|active_record)\// =~ kaller && ENV['AREL_EXTENSIONS_IN_TEST'] != '1'
36
+ return if %r{lib/(:?arel(?:_extensions)?|active_record)/} =~ kaller && ENV['AREL_EXTENSIONS_IN_TEST'] != '1'
37
37
 
38
38
  what = caller_locations(1, 1).first.label if what.nil?
39
39
  ArelExtensions.deprecator.warn "#{kaller}: `#{what}` is now deprecated. #{msg}"