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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +131 -5
- data/Makefile +31 -1
- data/NEWS.md +15 -0
- data/README.md +11 -2
- data/Rakefile +5 -3
- data/arel_extensions.gemspec +3 -5
- data/gemfiles/rails5.gemfile +15 -8
- data/gemfiles/rails5_1_4.gemfile +11 -9
- data/gemfiles/rails5_2.gemfile +16 -9
- data/gemfiles/rails6.gemfile +13 -7
- data/gemfiles/rails6_1.gemfile +13 -7
- data/gemfiles/rails7.gemfile +15 -9
- data/gemfiles/rails7_1.gemfile +15 -8
- data/gemfiles/rails7_2.gemfile +12 -6
- data/gemfiles/rails8.gemfile +7 -7
- data/gemfiles/rails8_1.gemfile +4 -4
- data/gemspecs/arel_extensions-v1.gemspec +3 -5
- data/gemspecs/arel_extensions-v2.gemspec +3 -5
- data/lib/arel_extensions/aliases.rb +3 -3
- data/lib/arel_extensions/attributes.rb +2 -0
- data/lib/arel_extensions/boolean_functions.rb +9 -7
- data/lib/arel_extensions/common_sql_functions.rb +5 -3
- data/lib/arel_extensions/comparators.rb +6 -4
- data/lib/arel_extensions/date_duration.rb +2 -0
- data/lib/arel_extensions/helpers.rb +17 -17
- data/lib/arel_extensions/insert_manager.rb +5 -1
- data/lib/arel_extensions/math.rb +40 -44
- data/lib/arel_extensions/math_functions.rb +28 -30
- data/lib/arel_extensions/nodes/aggregate_function.rb +4 -4
- data/lib/arel_extensions/nodes/blank.rb +6 -4
- data/lib/arel_extensions/nodes/case.rb +15 -12
- data/lib/arel_extensions/nodes/cast.rb +3 -5
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +6 -6
- data/lib/arel_extensions/nodes/date_diff.rb +40 -49
- data/lib/arel_extensions/nodes/duration.rb +2 -2
- data/lib/arel_extensions/nodes/format.rb +2 -2
- data/lib/arel_extensions/nodes/formatted_date.rb +2 -2
- data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
- data/lib/arel_extensions/nodes/function.rb +6 -4
- data/lib/arel_extensions/nodes/is_null.rb +2 -0
- data/lib/arel_extensions/nodes/json.rb +27 -15
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/power.rb +2 -2
- data/lib/arel_extensions/nodes/rand.rb +2 -2
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +3 -3
- data/lib/arel_extensions/nodes/rollup.rb +4 -4
- data/lib/arel_extensions/nodes/round.rb +3 -3
- data/lib/arel_extensions/nodes/select.rb +1 -1
- data/lib/arel_extensions/nodes/std.rb +4 -4
- data/lib/arel_extensions/nodes/substring.rb +52 -2
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +3 -3
- data/lib/arel_extensions/nodes/union_all.rb +3 -3
- data/lib/arel_extensions/nodes/wday.rb +2 -2
- data/lib/arel_extensions/null_functions.rb +5 -7
- data/lib/arel_extensions/predications.rb +22 -18
- data/lib/arel_extensions/string_functions.rb +26 -27
- data/lib/arel_extensions/version.rb +3 -1
- data/lib/arel_extensions/visitors/convert_format.rb +2 -2
- data/lib/arel_extensions/visitors/ibm_db.rb +5 -5
- data/lib/arel_extensions/visitors/mssql.rb +91 -92
- data/lib/arel_extensions/visitors/mysql.rb +89 -69
- data/lib/arel_extensions/visitors/oracle.rb +100 -104
- data/lib/arel_extensions/visitors/oracle12.rb +5 -6
- data/lib/arel_extensions/visitors/postgresql.rb +107 -94
- data/lib/arel_extensions/visitors/sqlite.rb +57 -65
- data/lib/arel_extensions/visitors/to_sql.rb +84 -74
- data/lib/arel_extensions/visitors.rb +6 -6
- data/lib/arel_extensions/warning.rb +5 -5
- data/lib/arel_extensions.rb +34 -27
- data/test/real_db_test.rb +31 -31
- data/test/visitors/test_to_sql.rb +2 -2
- data/test/with_ar/all_agnostic_test.rb +149 -15
- data/version_v1.rb +3 -1
- data/version_v2.rb +3 -1
- metadata +2 -30
|
@@ -18,7 +18,7 @@ module ArelExtensions
|
|
|
18
18
|
}.freeze
|
|
19
19
|
|
|
20
20
|
# String functions
|
|
21
|
-
def visit_ArelExtensions_Nodes_ByteSize
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
182
|
+
def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
|
|
181
183
|
collector = visit o.expr, collector
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
collector << ' IS NOT NULL'
|
|
185
|
+
collector
|
|
184
186
|
end
|
|
185
187
|
|
|
186
|
-
def visit_ArelExtensions_Nodes_Rand
|
|
188
|
+
def visit_ArelExtensions_Nodes_Rand(o, collector)
|
|
187
189
|
collector << 'RANDOM('
|
|
188
|
-
if o.left
|
|
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
|
|
199
|
+
def visit_Arel_Nodes_Regexp(o, collector)
|
|
198
200
|
collector = visit o.left, collector
|
|
199
201
|
collector << ' REGEXP'
|
|
200
|
-
|
|
201
|
-
collector
|
|
202
|
+
visit o.right, collector
|
|
202
203
|
end
|
|
203
204
|
|
|
204
|
-
def visit_Arel_Nodes_NotRegexp
|
|
205
|
+
def visit_Arel_Nodes_NotRegexp(o, collector)
|
|
205
206
|
collector = visit o.left, collector
|
|
206
207
|
collector << ' NOT REGEXP '
|
|
207
|
-
|
|
208
|
-
collector
|
|
208
|
+
visit o.right, collector
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
def visit_ArelExtensions_Nodes_Wday
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
|
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
|
|
354
|
+
def visit_Arel_Nodes_GreaterThanOrEqual(o, collector)
|
|
359
355
|
collector = visit get_time_converted(o.left), collector
|
|
360
356
|
collector << ' >= '
|
|
361
|
-
|
|
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
|
|
361
|
+
def visit_Arel_Nodes_GreaterThan(o, collector)
|
|
367
362
|
collector = visit get_time_converted(o.left), collector
|
|
368
363
|
collector << ' > '
|
|
369
|
-
|
|
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
|
|
368
|
+
def visit_Arel_Nodes_LessThanOrEqual(o, collector)
|
|
375
369
|
collector = visit get_time_converted(o.left), collector
|
|
376
370
|
collector << ' <= '
|
|
377
|
-
|
|
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
|
|
375
|
+
def visit_Arel_Nodes_LessThan(o, collector)
|
|
383
376
|
collector = visit get_time_converted(o.left), collector
|
|
384
377
|
collector << ' < '
|
|
385
|
-
|
|
386
|
-
collector
|
|
378
|
+
visit get_time_converted(o.right), collector
|
|
387
379
|
end
|
|
388
380
|
|
|
389
|
-
|
|
390
|
-
def visit_Arel_Nodes_As
|
|
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
|
|
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
|