arel_extensions 2.4.0 → 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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +131 -5
  4. data/Makefile +31 -1
  5. data/NEWS.md +15 -0
  6. data/README.md +11 -2
  7. data/Rakefile +5 -3
  8. data/arel_extensions.gemspec +3 -5
  9. data/gemfiles/rails5.gemfile +15 -8
  10. data/gemfiles/rails5_1_4.gemfile +11 -9
  11. data/gemfiles/rails5_2.gemfile +16 -9
  12. data/gemfiles/rails6.gemfile +13 -7
  13. data/gemfiles/rails6_1.gemfile +13 -7
  14. data/gemfiles/rails7.gemfile +15 -9
  15. data/gemfiles/rails7_1.gemfile +15 -8
  16. data/gemfiles/rails7_2.gemfile +12 -6
  17. data/gemfiles/rails8.gemfile +7 -7
  18. data/gemfiles/rails8_1.gemfile +4 -4
  19. data/gemspecs/arel_extensions-v1.gemspec +3 -5
  20. data/gemspecs/arel_extensions-v2.gemspec +3 -5
  21. data/lib/arel_extensions/aliases.rb +3 -3
  22. data/lib/arel_extensions/attributes.rb +2 -0
  23. data/lib/arel_extensions/boolean_functions.rb +9 -7
  24. data/lib/arel_extensions/common_sql_functions.rb +5 -3
  25. data/lib/arel_extensions/comparators.rb +6 -4
  26. data/lib/arel_extensions/date_duration.rb +2 -0
  27. data/lib/arel_extensions/helpers.rb +17 -17
  28. data/lib/arel_extensions/insert_manager.rb +5 -1
  29. data/lib/arel_extensions/math.rb +40 -44
  30. data/lib/arel_extensions/math_functions.rb +28 -30
  31. data/lib/arel_extensions/nodes/aggregate_function.rb +4 -4
  32. data/lib/arel_extensions/nodes/blank.rb +6 -4
  33. data/lib/arel_extensions/nodes/case.rb +15 -12
  34. data/lib/arel_extensions/nodes/cast.rb +3 -5
  35. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  36. data/lib/arel_extensions/nodes/collate.rb +1 -1
  37. data/lib/arel_extensions/nodes/concat.rb +6 -6
  38. data/lib/arel_extensions/nodes/date_diff.rb +40 -49
  39. data/lib/arel_extensions/nodes/duration.rb +2 -2
  40. data/lib/arel_extensions/nodes/format.rb +2 -2
  41. data/lib/arel_extensions/nodes/formatted_date.rb +2 -2
  42. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  43. data/lib/arel_extensions/nodes/function.rb +6 -4
  44. data/lib/arel_extensions/nodes/is_null.rb +2 -0
  45. data/lib/arel_extensions/nodes/json.rb +27 -15
  46. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  47. data/lib/arel_extensions/nodes/locate.rb +1 -1
  48. data/lib/arel_extensions/nodes/power.rb +2 -2
  49. data/lib/arel_extensions/nodes/rand.rb +2 -2
  50. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  51. data/lib/arel_extensions/nodes/replace.rb +3 -3
  52. data/lib/arel_extensions/nodes/rollup.rb +4 -4
  53. data/lib/arel_extensions/nodes/round.rb +3 -3
  54. data/lib/arel_extensions/nodes/select.rb +1 -1
  55. data/lib/arel_extensions/nodes/std.rb +4 -4
  56. data/lib/arel_extensions/nodes/substring.rb +52 -2
  57. data/lib/arel_extensions/nodes/then.rb +1 -1
  58. data/lib/arel_extensions/nodes/trim.rb +2 -2
  59. data/lib/arel_extensions/nodes/union.rb +3 -3
  60. data/lib/arel_extensions/nodes/union_all.rb +3 -3
  61. data/lib/arel_extensions/nodes/wday.rb +2 -2
  62. data/lib/arel_extensions/null_functions.rb +5 -7
  63. data/lib/arel_extensions/predications.rb +22 -18
  64. data/lib/arel_extensions/string_functions.rb +26 -27
  65. data/lib/arel_extensions/version.rb +3 -1
  66. data/lib/arel_extensions/visitors/convert_format.rb +2 -2
  67. data/lib/arel_extensions/visitors/ibm_db.rb +5 -5
  68. data/lib/arel_extensions/visitors/mssql.rb +91 -92
  69. data/lib/arel_extensions/visitors/mysql.rb +89 -69
  70. data/lib/arel_extensions/visitors/oracle.rb +100 -104
  71. data/lib/arel_extensions/visitors/oracle12.rb +5 -6
  72. data/lib/arel_extensions/visitors/postgresql.rb +107 -94
  73. data/lib/arel_extensions/visitors/sqlite.rb +57 -65
  74. data/lib/arel_extensions/visitors/to_sql.rb +84 -74
  75. data/lib/arel_extensions/visitors.rb +6 -6
  76. data/lib/arel_extensions/warning.rb +5 -5
  77. data/lib/arel_extensions.rb +34 -27
  78. data/test/real_db_test.rb +31 -31
  79. data/test/visitors/test_to_sql.rb +2 -2
  80. data/test/with_ar/all_agnostic_test.rb +149 -15
  81. data/version_v1.rb +3 -1
  82. data/version_v2.rb +3 -1
  83. metadata +2 -30
@@ -18,7 +18,7 @@ module ArelExtensions
18
18
  }.freeze
19
19
 
20
20
  # String functions
21
- def visit_ArelExtensions_Nodes_ByteSize o, collector
21
+ def visit_ArelExtensions_Nodes_ByteSize(o, collector)
22
22
  # sqlite 3.43.0 (2023-08-24) introduced `octet_length`, but we still support older versions.
23
23
  # https://sqlite.org/changes.html
24
24
  collector << 'length(CAST('
@@ -27,14 +27,14 @@ module ArelExtensions
27
27
  collector
28
28
  end
29
29
 
30
- def visit_ArelExtensions_Nodes_CharLength o, collector
30
+ def visit_ArelExtensions_Nodes_CharLength(o, collector)
31
31
  collector << 'length('
32
32
  collector = visit o.expr.coalesce(''), collector
33
33
  collector << ')'
34
34
  collector
35
35
  end
36
36
 
37
- def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
37
+ def visit_ArelExtensions_Nodes_IMatches(o, collector) # insensitive on ASCII
38
38
  collector = visit o.left.ci_collate, collector
39
39
  collector << ' LIKE '
40
40
  collector = visit o.right.ci_collate, collector
@@ -46,7 +46,7 @@ module ArelExtensions
46
46
  end
47
47
  end
48
48
 
49
- def visit_ArelExtensions_Nodes_AiMatches o, collector
49
+ def visit_ArelExtensions_Nodes_AiMatches(o, collector)
50
50
  collector = visit o.left.ai_collate, collector
51
51
  collector << ' LIKE '
52
52
  collector = visit o.right.ai_collate, collector
@@ -58,7 +58,7 @@ module ArelExtensions
58
58
  end
59
59
  end
60
60
 
61
- def visit_ArelExtensions_Nodes_AiIMatches o, collector
61
+ def visit_ArelExtensions_Nodes_AiIMatches(o, collector)
62
62
  collector = visit o.left.collate(true, true), collector
63
63
  collector << ' LIKE '
64
64
  collector = visit o.right.collate(true, true), collector
@@ -70,7 +70,7 @@ module ArelExtensions
70
70
  end
71
71
  end
72
72
 
73
- def visit_ArelExtensions_Nodes_SMatches o, collector
73
+ def visit_ArelExtensions_Nodes_SMatches(o, collector)
74
74
  collector = visit o.left.collate, collector
75
75
  collector << ' LIKE '
76
76
  collector = visit o.right.collate, collector
@@ -82,7 +82,7 @@ module ArelExtensions
82
82
  end
83
83
  end
84
84
 
85
- def visit_ArelExtensions_Nodes_Collate o, collector
85
+ def visit_ArelExtensions_Nodes_Collate(o, collector)
86
86
  if o.ai
87
87
  collector = visit o.expressions.first, collector
88
88
  collector << ' COLLATE NOACCENTS'
@@ -96,7 +96,7 @@ module ArelExtensions
96
96
  collector
97
97
  end
98
98
 
99
- def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
99
+ def visit_ArelExtensions_Nodes_IDoesNotMatch(o, collector)
100
100
  collector = visit o.left.lower, collector
101
101
  collector << ' NOT LIKE '
102
102
  collector = visit o.right.lower(o.right), collector
@@ -109,7 +109,7 @@ module ArelExtensions
109
109
  end
110
110
 
111
111
  # Date operations
112
- def visit_ArelExtensions_Nodes_DateAdd o, collector
112
+ def visit_ArelExtensions_Nodes_DateAdd(o, collector)
113
113
  collector << 'date('
114
114
  collector = visit o.expressions.first, collector
115
115
  collector << COMMA
@@ -118,7 +118,7 @@ module ArelExtensions
118
118
  collector
119
119
  end
120
120
 
121
- def visit_ArelExtensions_Nodes_DateDiff o, collector
121
+ def visit_ArelExtensions_Nodes_DateDiff(o, collector)
122
122
  case o.left_node_type
123
123
  when :ruby_time, :datetime, :time
124
124
  collector << "strftime('%s', "
@@ -135,14 +135,14 @@ module ArelExtensions
135
135
  collector
136
136
  end
137
137
 
138
- def visit_ArelExtensions_Nodes_Duration o, collector
138
+ def visit_ArelExtensions_Nodes_Duration(o, collector)
139
139
  collector << "strftime('#{DATE_MAPPING[o.left]}'#{COMMA}"
140
140
  collector = visit o.right, collector
141
141
  collector << ')'
142
142
  collector
143
143
  end
144
144
 
145
- def visit_ArelExtensions_Nodes_Locate o, collector
145
+ def visit_ArelExtensions_Nodes_Locate(o, collector)
146
146
  collector << 'instr('
147
147
  collector = visit o.expr, collector
148
148
  collector << COMMA
@@ -151,7 +151,7 @@ module ArelExtensions
151
151
  collector
152
152
  end
153
153
 
154
- def visit_ArelExtensions_Nodes_Concat o, collector
154
+ def visit_ArelExtensions_Nodes_Concat(o, collector)
155
155
  collector << '('
156
156
  o.expressions.each_with_index { |arg, i|
157
157
  collector = visit arg, collector
@@ -161,7 +161,9 @@ module ArelExtensions
161
161
  collector
162
162
  end
163
163
 
164
- def visit_ArelExtensions_Nodes_Substring o, collector
164
+ def visit_ArelExtensions_Nodes_Substring(o, collector)
165
+ return visit(o.range_substring_node, collector) if o.range?
166
+
165
167
  collector << 'SUBSTR('
166
168
  o.expressions.each_with_index { |arg, i|
167
169
  collector << COMMA if i != 0
@@ -171,21 +173,21 @@ module ArelExtensions
171
173
  collector
172
174
  end
173
175
 
174
- def visit_ArelExtensions_Nodes_IsNull o, collector
176
+ def visit_ArelExtensions_Nodes_IsNull(o, collector)
175
177
  collector = visit o.expr, collector
176
178
  collector << ' IS NULL'
177
179
  collector
178
180
  end
179
181
 
180
- def visit_ArelExtensions_Nodes_IsNotNull o, collector
182
+ def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
181
183
  collector = visit o.expr, collector
182
- collector << ' IS NOT NULL'
183
- collector
184
+ collector << ' IS NOT NULL'
185
+ collector
184
186
  end
185
187
 
186
- def visit_ArelExtensions_Nodes_Rand o, collector
188
+ def visit_ArelExtensions_Nodes_Rand(o, collector)
187
189
  collector << 'RANDOM('
188
- if o.left != nil && o.right != nil
190
+ if !o.left.nil? && !o.right.nil?
189
191
  collector = visit o.left, collector
190
192
  collector << COMMA
191
193
  collector = visit o.right, collector
@@ -194,21 +196,19 @@ module ArelExtensions
194
196
  collector
195
197
  end
196
198
 
197
- def visit_Arel_Nodes_Regexp o, collector
199
+ def visit_Arel_Nodes_Regexp(o, collector)
198
200
  collector = visit o.left, collector
199
201
  collector << ' REGEXP'
200
- collector = visit o.right, collector
201
- collector
202
+ visit o.right, collector
202
203
  end
203
204
 
204
- def visit_Arel_Nodes_NotRegexp o, collector
205
+ def visit_Arel_Nodes_NotRegexp(o, collector)
205
206
  collector = visit o.left, collector
206
207
  collector << ' NOT REGEXP '
207
- collector = visit o.right, collector
208
- collector
208
+ visit o.right, collector
209
209
  end
210
210
 
211
- def visit_ArelExtensions_Nodes_Wday o, collector
211
+ def visit_ArelExtensions_Nodes_Wday(o, collector)
212
212
  collector << "STRFTIME('%w',"
213
213
  collector = visit o.date, collector
214
214
  collector << ')'
@@ -223,7 +223,7 @@ module ArelExtensions
223
223
  # END
224
224
  # AS FLOAT
225
225
  # )
226
- def visit_ArelExtensions_Nodes_Floor o, collector
226
+ def visit_ArelExtensions_Nodes_Floor(o, collector)
227
227
  collector << 'CAST(CASE WHEN '
228
228
  collector = visit o.left, collector
229
229
  collector << ' >= 0 THEN CAST('
@@ -240,7 +240,7 @@ module ArelExtensions
240
240
  collector
241
241
  end
242
242
 
243
- def visit_ArelExtensions_Nodes_Ceil o, collector
243
+ def visit_ArelExtensions_Nodes_Ceil(o, collector)
244
244
  collector << 'CASE WHEN ROUND('
245
245
  collector = visit o.left, collector
246
246
  collector << ', 1) > ROUND('
@@ -254,7 +254,7 @@ module ArelExtensions
254
254
  end
255
255
 
256
256
  if AREL_VERSION < V7
257
- def visit_ArelExtensions_InsertManager_BulkValues o, collector
257
+ def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
258
258
  o.left.each_with_index do |row, idx|
259
259
  collector << 'SELECT '
260
260
  len = row.length - 1
@@ -269,14 +269,14 @@ module ArelExtensions
269
269
  collector << quote(attr.name)
270
270
  end
271
271
  end
272
- collector << COMMA unless i == len
272
+ collector << COMMA unless i == len
273
273
  }
274
274
  collector << ' UNION ALL ' unless idx == o.left.length - 1
275
275
  end
276
276
  collector
277
277
  end
278
278
  else
279
- def visit_ArelExtensions_InsertManager_BulkValues o, collector
279
+ def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
280
280
  o.left.each_with_index do |row, idx|
281
281
  collector << 'SELECT '
282
282
  len = row.length - 1
@@ -297,7 +297,7 @@ module ArelExtensions
297
297
  collector << quote(attr.name)
298
298
  end
299
299
  end
300
- collector << COMMA unless i == len
300
+ collector << COMMA unless i == len
301
301
  }
302
302
  collector << ' UNION ALL ' unless idx == o.left.length - 1
303
303
  end
@@ -305,7 +305,7 @@ module ArelExtensions
305
305
  end
306
306
  end
307
307
 
308
- def visit_ArelExtensions_Nodes_Union o, collector
308
+ def visit_ArelExtensions_Nodes_Union(o, collector)
309
309
  collector =
310
310
  if o.left.is_a?(Arel::SelectManager)
311
311
  visit o.left.ast, collector
@@ -313,16 +313,14 @@ module ArelExtensions
313
313
  visit o.left, collector
314
314
  end
315
315
  collector << ' UNION '
316
- collector =
317
- if o.right.is_a?(Arel::SelectManager)
318
- visit o.right.ast, collector
319
- else
320
- visit o.right, collector
321
- end
322
- collector
316
+ if o.right.is_a?(Arel::SelectManager)
317
+ visit o.right.ast, collector
318
+ else
319
+ visit o.right, collector
320
+ end
323
321
  end
324
322
 
325
- def visit_ArelExtensions_Nodes_UnionAll o, collector
323
+ def visit_ArelExtensions_Nodes_UnionAll(o, collector)
326
324
  collector =
327
325
  if o.left.is_a?(Arel::SelectManager)
328
326
  visit o.left.ast, collector
@@ -330,16 +328,14 @@ module ArelExtensions
330
328
  visit o.left, collector
331
329
  end
332
330
  collector << ' UNION ALL '
333
- collector =
334
- if o.right.is_a?(Arel::SelectManager)
335
- visit o.right.ast, collector
336
- else
337
- visit o.right, collector
338
- end
339
- collector
331
+ if o.right.is_a?(Arel::SelectManager)
332
+ visit o.right.ast, collector
333
+ else
334
+ visit o.right, collector
335
+ end
340
336
  end
341
337
 
342
- def get_time_converted element
338
+ def get_time_converted(element)
343
339
  if element.is_a?(Time)
344
340
  Arel::Nodes::NamedFunction.new('STRFTIME', [element, '%H:%M:%S'])
345
341
  elsif element.is_a?(Arel::Attributes::Attribute)
@@ -355,39 +351,35 @@ module ArelExtensions
355
351
  end
356
352
 
357
353
  remove_method(:visit_Arel_Nodes_GreaterThanOrEqual) rescue nil
358
- def visit_Arel_Nodes_GreaterThanOrEqual o, collector
354
+ def visit_Arel_Nodes_GreaterThanOrEqual(o, collector)
359
355
  collector = visit get_time_converted(o.left), collector
360
356
  collector << ' >= '
361
- collector = visit get_time_converted(o.right), collector
362
- collector
357
+ visit get_time_converted(o.right), collector
363
358
  end
364
359
 
365
360
  remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
366
- def visit_Arel_Nodes_GreaterThan o, collector
361
+ def visit_Arel_Nodes_GreaterThan(o, collector)
367
362
  collector = visit get_time_converted(o.left), collector
368
363
  collector << ' > '
369
- collector = visit get_time_converted(o.right), collector
370
- collector
364
+ visit get_time_converted(o.right), collector
371
365
  end
372
366
 
373
367
  remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
374
- def visit_Arel_Nodes_LessThanOrEqual o, collector
368
+ def visit_Arel_Nodes_LessThanOrEqual(o, collector)
375
369
  collector = visit get_time_converted(o.left), collector
376
370
  collector << ' <= '
377
- collector = visit get_time_converted(o.right), collector
378
- collector
371
+ visit get_time_converted(o.right), collector
379
372
  end
380
373
 
381
374
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
382
- def visit_Arel_Nodes_LessThan o, collector
375
+ def visit_Arel_Nodes_LessThan(o, collector)
383
376
  collector = visit get_time_converted(o.left), collector
384
377
  collector << ' < '
385
- collector = visit get_time_converted(o.right), collector
386
- collector
378
+ visit get_time_converted(o.right), collector
387
379
  end
388
380
 
389
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
390
- def visit_Arel_Nodes_As o, collector
381
+ alias old_visit_Arel_Nodes_As visit_Arel_Nodes_As rescue nil
382
+ def visit_Arel_Nodes_As(o, collector)
391
383
  if o.left.is_a?(Arel::Nodes::Binary)
392
384
  collector << '('
393
385
  collector = visit o.left, collector
@@ -402,7 +394,7 @@ module ArelExtensions
402
394
  collector
403
395
  end
404
396
 
405
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
397
+ def visit_ArelExtensions_Nodes_FormattedNumber(o, collector)
406
398
  format = Arel::Nodes::NamedFunction.new('printf', [Arel.quoted(o.original_string), o.left])
407
399
  locale_map = NUMBER_COMMA_MAPPING[o.locale]
408
400
  if locale_map