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
@@ -1,13 +1,12 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
-
5
4
  MSSQL_CLASS_NAMES = %i[MSSQL SQLServer].freeze
6
5
 
7
6
  mssql_class =
8
7
  Arel::Visitors
9
8
  .constants
10
- .select { |c| Arel::Visitors.const_get(c).is_a?(Class) }
9
+ .select { |c| Arel::Visitors.const_get(c).is_a?(Class) }
11
10
  .find { |c| MSSQL_CLASS_NAMES.include?(c) }
12
11
 
13
12
  # This guard is necessary because:
@@ -47,7 +46,7 @@ module ArelExtensions
47
46
  Regexp.new(
48
47
  LOADED_VISITOR::DATE_FORMAT_DIRECTIVES
49
48
  .keys
50
- .map{|k| Regexp.escape(k)}
49
+ .map { |k| Regexp.escape(k) }
51
50
  .join('|')
52
51
  ).freeze
53
52
 
@@ -59,7 +58,7 @@ module ArelExtensions
59
58
  'MM-DD-YYYY' => 110,
60
59
  'YYYY/MM/DD' => 111,
61
60
  'DD-MM-YYYY' => 105,
62
- 'DD-MM-YY' => 5,
61
+ 'DD-MM-YY' => 5,
63
62
  'DD.MM.YYYY' => 104,
64
63
  'YYYY-MM-DDTHH:MM:SS:MMM' => 126
65
64
  }.freeze
@@ -76,7 +75,7 @@ module ArelExtensions
76
75
  # The following is adapted from
77
76
  # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
78
77
  #
79
- if RUBY_PLATFORM == 'java' && Arel::VERSION.to_i <= 6
78
+ if RUBY_PLATFORM == 'java' && AREL_VERSION <= V6
80
79
  def quote_string(s)
81
80
  s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
82
81
  end
@@ -89,15 +88,15 @@ module ArelExtensions
89
88
  if value.acts_like?(:time)
90
89
  if (ActiveRecord.respond_to?(:default_timezone) && ActiveRecord.default_timezone == :utc) || ActiveRecord::Base.default_timezone == :utc
91
90
  value = value.getutc if value.respond_to?(:getutc) && !value.utc?
92
- else
93
- value = value.getlocal if value.respond_to?(:getlocal)
91
+ elsif value.respond_to?(:getlocal)
92
+ value = value.getlocal
94
93
  end
95
94
  end
96
95
  # new versions of AR use `to_fs`, but we want max compatibility, and we're
97
96
  # not going to write it over and over, so it's fine like that.
98
97
  result = value.to_formatted_s(:db)
99
98
  if value.respond_to?(:usec) && value.usec > 0
100
- result << '.' << sprintf('%06d', value.usec)
99
+ result << '.' << format('%06d', value.usec)
101
100
  else
102
101
  result
103
102
  end
@@ -113,10 +112,10 @@ module ArelExtensions
113
112
 
114
113
  def quoted_time(value) # :nodoc:
115
114
  value = value.change(year: 2000, month: 1, day: 1)
116
- quoted_date(value).sub(/\A\d{4}-\d{2}-\d{2} /, "")
115
+ quoted_date(value).sub(/\A\d{4}-\d{2}-\d{2} /, '')
117
116
  end
118
117
 
119
- def quote value, column = nil
118
+ def quote(value, _column = nil)
120
119
  case value
121
120
  when Arel::Nodes::SqlLiteral
122
121
  value
@@ -133,7 +132,7 @@ module ArelExtensions
133
132
  value.to_s('F')
134
133
  when Numeric, ActiveSupport::Duration
135
134
  value.to_s
136
- when Arel::VERSION.to_i > 6 && ActiveRecord::Type::Time::Value
135
+ when AREL_VERSION > V6 && ActiveRecord::Type::Time::Value
137
136
  "'#{quoted_time(value)}'"
138
137
  when Date, Time
139
138
  "'#{quoted_date(value)}'"
@@ -145,8 +144,8 @@ module ArelExtensions
145
144
  end
146
145
  end
147
146
 
148
- alias_method(:old_primary_Key_From_Table, :primary_Key_From_Table) rescue nil
149
- def primary_Key_From_Table t
147
+ alias old_primary_Key_From_Table primary_Key_From_Table rescue nil
148
+ def primary_Key_From_Table(t)
150
149
  return unless t
151
150
 
152
151
  column_name = @connection.schema_cache.primary_keys(t.name) ||
@@ -155,48 +154,48 @@ module ArelExtensions
155
154
  end
156
155
 
157
156
  # Math Functions
158
- def visit_ArelExtensions_Nodes_Ceil o, collector
157
+ def visit_ArelExtensions_Nodes_Ceil(o, collector)
159
158
  collector << 'CEILING('
160
159
  collector = visit o.expr, collector
161
160
  collector << ')'
162
161
  collector
163
162
  end
164
163
 
165
- def visit_ArelExtensions_Nodes_Log10 o, collector
164
+ def visit_ArelExtensions_Nodes_Log10(o, collector)
166
165
  collector << 'LOG10('
167
- o.expressions.each_with_index { |arg, i|
168
- collector << Arel::Visitors::ToSql::COMMA if i != 0
169
- collector = visit arg, collector
170
- }
171
- collector << ')'
172
- collector
166
+ o.expressions.each_with_index { |arg, i|
167
+ collector << LOADED_VISITOR::COMMA if i != 0
168
+ collector = visit arg, collector
169
+ }
170
+ collector << ')'
171
+ collector
173
172
  end
174
173
 
175
- def visit_ArelExtensions_Nodes_Power o, collector
174
+ def visit_ArelExtensions_Nodes_Power(o, collector)
176
175
  collector << 'POWER('
177
176
  o.expressions.each_with_index { |arg, i|
178
- collector << Arel::Visitors::ToSql::COMMA if i != 0
177
+ collector << LOADED_VISITOR::COMMA if i != 0
179
178
  collector = visit arg, collector
180
179
  }
181
180
  collector << ')'
182
181
  collector
183
182
  end
184
183
 
185
- def visit_ArelExtensions_Nodes_IsNull o, collector
184
+ def visit_ArelExtensions_Nodes_IsNull(o, collector)
186
185
  collector << '('
187
186
  collector = visit o.expr, collector
188
187
  collector << ' IS NULL)'
189
188
  collector
190
189
  end
191
190
 
192
- def visit_ArelExtensions_Nodes_IsNotNull o, collector
191
+ def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
193
192
  collector << '('
194
- collector = visit o.expr, collector
195
- collector << ' IS NOT NULL)'
196
- collector
193
+ collector = visit o.expr, collector
194
+ collector << ' IS NOT NULL)'
195
+ collector
197
196
  end
198
197
 
199
- def visit_ArelExtensions_Nodes_Concat o, collector
198
+ def visit_ArelExtensions_Nodes_Concat(o, collector)
200
199
  collector << 'CONCAT('
201
200
  o.expressions.each_with_index { |arg, i|
202
201
  collector << LOADED_VISITOR::COMMA if i != 0
@@ -206,25 +205,23 @@ module ArelExtensions
206
205
  collector
207
206
  end
208
207
 
209
- def visit_ArelExtensions_Nodes_Repeat o, collector
208
+ def visit_ArelExtensions_Nodes_Repeat(o, collector)
210
209
  collector << 'REPLICATE('
211
210
  o.expressions.each_with_index { |arg, i|
212
- collector << Arel::Visitors::ToSql::COMMA if i != 0
211
+ collector << LOADED_VISITOR::COMMA if i != 0
213
212
  collector = visit arg, collector
214
213
  }
215
214
  collector << ')'
216
215
  collector
217
216
  end
218
217
 
219
-
220
-
221
- def visit_ArelExtensions_Nodes_DateDiff o, collector
218
+ def visit_ArelExtensions_Nodes_DateDiff(o, collector)
222
219
  case o.right_node_type
223
220
  when :ruby_date, :ruby_time, :date, :datetime, :time
224
221
  collector << case o.left_node_type
225
- when :ruby_time, :datetime, :time then 'DATEDIFF(second'
226
- else 'DATEDIFF(day'
227
- end
222
+ when :ruby_time, :datetime, :time then 'DATEDIFF(second'
223
+ else 'DATEDIFF(day'
224
+ end
228
225
  collector << LOADED_VISITOR::COMMA
229
226
  collector = visit o.right, collector
230
227
  collector << LOADED_VISITOR::COMMA
@@ -246,7 +243,7 @@ module ArelExtensions
246
243
  collector
247
244
  end
248
245
 
249
- def visit_ArelExtensions_Nodes_DateAdd o, collector
246
+ def visit_ArelExtensions_Nodes_DateAdd(o, collector)
250
247
  collector << 'DATEADD('
251
248
  collector = visit o.mssql_datepart(o.right), collector
252
249
  collector << LOADED_VISITOR::COMMA
@@ -257,7 +254,7 @@ module ArelExtensions
257
254
  collector
258
255
  end
259
256
 
260
- def visit_ArelExtensions_Nodes_Duration o, collector
257
+ def visit_ArelExtensions_Nodes_Duration(o, collector)
261
258
  if o.with_interval && o.left.end_with?('i')
262
259
  collector = visit o.right, collector
263
260
  else
@@ -274,7 +271,24 @@ module ArelExtensions
274
271
  collector
275
272
  end
276
273
 
277
- def visit_ArelExtensions_Nodes_Length o, collector
274
+ def visit_ArelExtensions_Nodes_ByteSize(o, collector)
275
+ collector << 'DATALENGTH(CAST('
276
+ collector = visit o.expr.coalesce(''), collector
277
+ collector << ' AS VARCHAR(MAX)))'
278
+ collector
279
+ end
280
+
281
+ def visit_ArelExtensions_Nodes_CharLength(o, collector)
282
+ # According to the docs https://learn.microsoft.com/en-us/sql/t-sql/functions/len-transact-sql?view=sql-server-ver17
283
+ # LEN doesn't take into account the trailing white space, and that's why
284
+ # we need to do acrobatics.
285
+ collector << 'LEN('
286
+ collector = visit o.expr.coalesce(''), collector
287
+ collector << " + 'x') - 1"
288
+ collector
289
+ end
290
+
291
+ def visit_ArelExtensions_Nodes_Length(o, collector)
278
292
  if o.bytewise
279
293
  collector << '(DATALENGTH('
280
294
  collector = visit o.expr, collector
@@ -290,7 +304,7 @@ module ArelExtensions
290
304
  end
291
305
  end
292
306
 
293
- def visit_ArelExtensions_Nodes_Round o, collector
307
+ def visit_ArelExtensions_Nodes_Round(o, collector)
294
308
  collector << 'ROUND('
295
309
  o.expressions.each_with_index { |arg, i|
296
310
  collector << LOADED_VISITOR::COMMA if i != 0
@@ -304,7 +318,7 @@ module ArelExtensions
304
318
  collector
305
319
  end
306
320
 
307
- def visit_ArelExtensions_Nodes_Locate o, collector
321
+ def visit_ArelExtensions_Nodes_Locate(o, collector)
308
322
  collector << 'CHARINDEX('
309
323
  collector = visit o.right, collector
310
324
  collector << LOADED_VISITOR::COMMA
@@ -313,7 +327,9 @@ module ArelExtensions
313
327
  collector
314
328
  end
315
329
 
316
- def visit_ArelExtensions_Nodes_Substring o, collector
330
+ def visit_ArelExtensions_Nodes_Substring(o, collector)
331
+ return visit(o.range_substring_node, collector) if o.range?
332
+
317
333
  collector << 'SUBSTRING('
318
334
  collector = visit o.expressions[0], collector
319
335
  collector << LOADED_VISITOR::COMMA
@@ -324,24 +340,24 @@ module ArelExtensions
324
340
  collector
325
341
  end
326
342
 
327
- def visit_ArelExtensions_Nodes_Trim o, collector
343
+ def visit_ArelExtensions_Nodes_Trim(o, collector)
328
344
  # NOTE: in MSSQL's `blank`, o.right is the space char so we need to
329
345
  # account for it.
330
346
  if o.right && !/\A\s\Z/.match(o.right.expr)
331
347
  collector << 'dbo.TrimChar('
332
348
  collector = visit o.left, collector
333
- collector << Arel::Visitors::MSSQL::COMMA
349
+ collector << LOADED_VISITOR::COMMA
334
350
  collector = visit o.right, collector
335
351
  collector << ')'
336
352
  else
337
- collector << "LTRIM(RTRIM("
353
+ collector << 'LTRIM(RTRIM('
338
354
  collector = visit o.left, collector
339
- collector << "))"
355
+ collector << '))'
340
356
  end
341
357
  collector
342
358
  end
343
359
 
344
- def visit_ArelExtensions_Nodes_Ltrim o, collector
360
+ def visit_ArelExtensions_Nodes_Ltrim(o, collector)
345
361
  if o.right
346
362
  collector << 'REPLACE(REPLACE(LTRIM(REPLACE(REPLACE('
347
363
  collector = visit o.left, collector
@@ -358,7 +374,7 @@ module ArelExtensions
358
374
  collector
359
375
  end
360
376
 
361
- def visit_ArelExtensions_Nodes_Rtrim o, collector
377
+ def visit_ArelExtensions_Nodes_Rtrim(o, collector)
362
378
  if o.right
363
379
  collector << 'REPLACE(REPLACE(RTRIM(REPLACE(REPLACE('
364
380
  collector = visit o.left, collector
@@ -375,20 +391,20 @@ module ArelExtensions
375
391
  collector
376
392
  end
377
393
 
378
- def visit_ArelExtensions_Nodes_Blank o, collector
394
+ def visit_ArelExtensions_Nodes_Blank(o, collector)
379
395
  visit o.expr.coalesce('').trim.length.eq(0), collector
380
396
  end
381
397
 
382
- def visit_ArelExtensions_Nodes_NotBlank o, collector
398
+ def visit_ArelExtensions_Nodes_NotBlank(o, collector)
383
399
  visit o.expr.coalesce('').trim.length.gt(0), collector
384
400
  end
385
401
 
386
- def visit_ArelExtensions_Nodes_Format o, collector
402
+ def visit_ArelExtensions_Nodes_Format(o, collector)
387
403
  visit_ArelExtensions_Nodes_FormattedDate o, collector
388
404
  end
389
405
 
390
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
391
- f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, LOADED_VISITOR::DATE_FORMAT_DIRECTIVES)
406
+ def visit_ArelExtensions_Nodes_FormattedDate(o, collector)
407
+ f = ArelExtensions::Visitors.strftime_to_format(o.iso_format, LOADED_VISITOR::DATE_FORMAT_DIRECTIVES)
392
408
  if fmt = LOADED_VISITOR::DATE_CONVERT_FORMATS[f]
393
409
  collector << "CONVERT(VARCHAR(#{f.length})"
394
410
  collector << LOADED_VISITOR::COMMA
@@ -420,8 +436,7 @@ module ArelExtensions
420
436
  while !s.eos?
421
437
  collector << sep
422
438
  sep = ' + '
423
- case
424
- when s.scan(LOADED_VISITOR::DATE_FORMAT_REGEX)
439
+ if s.scan(LOADED_VISITOR::DATE_FORMAT_REGEX)
425
440
  dir = LOADED_VISITOR::DATE_FORMAT_DIRECTIVES[s.matched]
426
441
  fmt = LOADED_VISITOR::DATE_FORMAT_FORMAT[dir]
427
442
  date_name = LOADED_VISITOR::DATE_NAME.include?(s.matched)
@@ -439,7 +454,8 @@ module ArelExtensions
439
454
  collector = visit o.left, collector
440
455
  case o.time_zone
441
456
  when Hash
442
- src_tz, dst_tz = o.time_zone.first.first, o.time_zone.first.second
457
+ src_tz = o.time_zone.first.first
458
+ dst_tz = o.time_zone.first.second
443
459
  collector << ') AT TIME ZONE '
444
460
  collector = visit Arel.quoted(src_tz), collector
445
461
  collector << ' AT TIME ZONE '
@@ -452,9 +468,9 @@ module ArelExtensions
452
468
  collector << ')' if !fmt && !date_name
453
469
  collector << LOADED_VISITOR::COMMA << "'#{fmt}')" if fmt
454
470
  collector << '))'
455
- when s.scan(/^%%/)
471
+ elsif s.scan(/^%%/)
456
472
  collector = visit Arel.quoted('%'), collector
457
- when s.scan(/[^%]+|./)
473
+ elsif s.scan(/[^%]+|./)
458
474
  collector = visit Arel.quoted(s.matched), collector
459
475
  end
460
476
  end
@@ -463,7 +479,7 @@ module ArelExtensions
463
479
  end
464
480
  end
465
481
 
466
- def visit_ArelExtensions_Nodes_Replace o, collector
482
+ def visit_ArelExtensions_Nodes_Replace(o, collector)
467
483
  collector << 'REPLACE('
468
484
  o.expressions.each_with_index { |arg, i|
469
485
  collector << LOADED_VISITOR::COMMA if i != 0
@@ -473,7 +489,7 @@ module ArelExtensions
473
489
  collector
474
490
  end
475
491
 
476
- def visit_ArelExtensions_Nodes_FindInSet o, collector
492
+ def visit_ArelExtensions_Nodes_FindInSet(o, collector)
477
493
  collector << 'dbo.FIND_IN_SET('
478
494
  o.expressions.each_with_index { |arg, i|
479
495
  collector << LOADED_VISITOR::COMMA if i != 0
@@ -484,7 +500,7 @@ module ArelExtensions
484
500
  end
485
501
 
486
502
  # TODO; manage case insensitivity
487
- def visit_ArelExtensions_Nodes_IMatches o, collector
503
+ def visit_ArelExtensions_Nodes_IMatches(o, collector)
488
504
  collector = visit o.left.ci_collate, collector
489
505
  collector << ' LIKE '
490
506
  collector = visit o.right.ci_collate, collector
@@ -497,7 +513,7 @@ module ArelExtensions
497
513
  end
498
514
 
499
515
  # TODO; manage case insensitivity
500
- def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
516
+ def visit_ArelExtensions_Nodes_IDoesNotMatch(o, collector)
501
517
  collector = visit o.left.ci_collate, collector
502
518
  collector << ' NOT LIKE '
503
519
  collector = visit o.right.ci_collate, collector
@@ -509,7 +525,7 @@ module ArelExtensions
509
525
  end
510
526
  end
511
527
 
512
- def visit_ArelExtensions_Nodes_AiMatches o, collector
528
+ def visit_ArelExtensions_Nodes_AiMatches(o, collector)
513
529
  collector = visit o.left.ai_collate, collector
514
530
  collector << ' LIKE '
515
531
  collector = visit o.right.ai_collate, collector
@@ -521,7 +537,7 @@ module ArelExtensions
521
537
  end
522
538
  end
523
539
 
524
- def visit_ArelExtensions_Nodes_AiIMatches o, collector
540
+ def visit_ArelExtensions_Nodes_AiIMatches(o, collector)
525
541
  collector = visit o.left.collate(true, true), collector
526
542
  collector << ' LIKE '
527
543
  collector = visit o.right.collate(true, true), collector
@@ -533,7 +549,7 @@ module ArelExtensions
533
549
  end
534
550
  end
535
551
 
536
- def visit_ArelExtensions_Nodes_SMatches o, collector
552
+ def visit_ArelExtensions_Nodes_SMatches(o, collector)
537
553
  collector = visit o.left.collate, collector
538
554
  collector << ' LIKE '
539
555
  collector = visit o.right.collate, collector
@@ -545,7 +561,7 @@ module ArelExtensions
545
561
  end
546
562
  end
547
563
 
548
- def visit_ArelExtensions_Nodes_Collate o, collector
564
+ def visit_ArelExtensions_Nodes_Collate(o, collector)
549
565
  if o.ai && o.ci
550
566
  collector = visit o.expressions.first, collector
551
567
  collector << ' COLLATE Latin1_General_CI_AI'
@@ -562,8 +578,8 @@ module ArelExtensions
562
578
  collector
563
579
  end
564
580
 
565
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
566
- def visit_Arel_Nodes_As o, collector
581
+ alias old_visit_Arel_Nodes_As visit_Arel_Nodes_As rescue nil
582
+ def visit_Arel_Nodes_As(o, collector)
567
583
  if o.left.is_a?(Arel::Nodes::Binary)
568
584
  collector << '('
569
585
  collector = visit o.left, collector
@@ -575,11 +591,11 @@ module ArelExtensions
575
591
  # Sometimes these values are already quoted, if they are, don't double quote it
576
592
  lft, rgt =
577
593
  if o.right.is_a?(Arel::Nodes::SqlLiteral)
578
- if Arel::VERSION.to_i >= 6 && o.right[0] != '[' && o.right[-1] != ']'
594
+ if AREL_VERSION >= V6 && o.right[0] != '[' && o.right[-1] != ']'
579
595
  # This is a lie, it's not about arel version, but SQL Server's (>= 2000).
580
- ['[', ']']
581
- elsif o.right[0] != '"' && o.right[-1] != '"'
582
- ['"', '"']
596
+ %w([ ])
597
+ elsif ACTIVE_RECORD_VERSION < V8_1 && o.right[0] != '"' && o.right[-1] != '"'
598
+ %w[" "]
583
599
  else
584
600
  []
585
601
  end
@@ -591,38 +607,38 @@ module ArelExtensions
591
607
  end
592
608
 
593
609
  # SQL Server does not know about REGEXP
594
- def visit_Arel_Nodes_Regexp o, collector
610
+ def visit_Arel_Nodes_Regexp(o, collector)
595
611
  collector = visit o.left, collector
596
612
  collector << "LIKE '%#{o.right}%'"
597
613
  collector
598
614
  end
599
615
 
600
- def visit_Arel_Nodes_NotRegexp o, collector
616
+ def visit_Arel_Nodes_NotRegexp(o, collector)
601
617
  collector = visit o.left, collector
602
618
  collector << "NOT LIKE '%#{o.right}%'"
603
619
  collector
604
620
  end
605
621
 
606
622
  def visit_Arel_Nodes_RollUp(o, collector)
607
- collector << "ROLLUP"
623
+ collector << 'ROLLUP'
608
624
  grouping_array_or_grouping_element o, collector
609
625
  end
610
626
 
611
- def visit_ArelExtensions_Nodes_GroupConcat o, collector
627
+ def visit_ArelExtensions_Nodes_GroupConcat(o, collector)
612
628
  collector << '(STRING_AGG('
613
629
  collector = visit o.left, collector
614
- collector << Arel::Visitors::Oracle::COMMA
630
+ collector << LOADED_VISITOR::COMMA
615
631
  sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
616
632
  collector =
617
- if 'NULL' != sep
618
- visit o.separator, collector
619
- else
633
+ if 'NULL' == sep
620
634
  visit Arel.quoted(','), collector
635
+ else
636
+ visit o.separator, collector
621
637
  end
622
638
  collector << ') WITHIN GROUP (ORDER BY '
623
639
  if o.order.present?
624
640
  o.order.each_with_index do |order, i|
625
- collector << Arel::Visitors::Oracle::COMMA if i != 0
641
+ collector << LOADED_VISITOR::COMMA if i != 0
626
642
  collector = visit order, collector
627
643
  end
628
644
  else
@@ -632,18 +648,18 @@ module ArelExtensions
632
648
  collector
633
649
  end
634
650
 
635
- def visit_ArelExtensions_Nodes_MD5 o, collector
636
- collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR,"
651
+ def visit_ArelExtensions_Nodes_MD5(o, collector)
652
+ collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR(MAX),"
637
653
  collector = visit o.left, collector
638
654
  collector << ')),2))'
639
655
  collector
640
656
  end
641
657
 
642
- def visit_ArelExtensions_Nodes_Cast o, collector
658
+ def visit_ArelExtensions_Nodes_Cast(o, collector)
643
659
  as_attr =
644
660
  case o.as_attr
645
661
  when :string
646
- 'varchar'
662
+ 'varchar(MAX)'
647
663
  when :time
648
664
  'time'
649
665
  when :date
@@ -670,7 +686,7 @@ module ArelExtensions
670
686
  collector
671
687
  end
672
688
 
673
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
689
+ def visit_ArelExtensions_Nodes_FormattedNumber(o, collector)
674
690
  col = o.left.coalesce(0)
675
691
  locale = Arel.quoted(o.locale.tr('_', '-'))
676
692
  param = Arel.quoted("N#{o.precision}")
@@ -731,35 +747,33 @@ module ArelExtensions
731
747
  collector
732
748
  end
733
749
 
734
- def visit_ArelExtensions_Nodes_Std o, collector
750
+ def visit_ArelExtensions_Nodes_Std(o, collector)
735
751
  collector << (o.unbiased_estimator ? 'STDEV(' : 'STDEVP(')
736
752
  visit o.left, collector
737
753
  collector << ')'
738
754
  collector
739
755
  end
740
756
 
741
- def visit_ArelExtensions_Nodes_Variance o, collector
757
+ def visit_ArelExtensions_Nodes_Variance(o, collector)
742
758
  collector << (o.unbiased_estimator ? 'VAR(' : 'VARP(')
743
759
  visit o.left, collector
744
760
  collector << ')'
745
761
  collector
746
762
  end
747
763
 
748
-
749
- def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
764
+ def visit_ArelExtensions_Nodes_LevenshteinDistance(o, collector)
750
765
  collector << 'dbo.LEVENSHTEIN_DISTANCE('
751
766
  collector = visit o.left, collector
752
- collector << Arel::Visitors::ToSql::COMMA
767
+ collector << LOADED_VISITOR::COMMA
753
768
  collector = visit o.right, collector
754
769
  collector << ')'
755
770
  collector
756
771
  end
757
772
 
758
-
759
- def visit_ArelExtensions_Nodes_JsonGet o, collector
773
+ def visit_ArelExtensions_Nodes_JsonGet(o, collector)
760
774
  collector << 'JSON_VALUE('
761
775
  collector = visit o.dict, collector
762
- collector << Arel::Visitors::MySQL::COMMA
776
+ collector << LOADED_VISITOR::COMMA
763
777
  if o.key.is_a?(Integer)
764
778
  collector << "\"$[#{o.key}]\""
765
779
  else
@@ -773,9 +787,9 @@ module ArelExtensions
773
787
  # handle grouping aggregation semantics
774
788
  def grouping_array_or_grouping_element(o, collector)
775
789
  if o.expr.is_a? Array
776
- collector << "( "
790
+ collector << '( '
777
791
  visit o.expr, collector
778
- collector << " )"
792
+ collector << ' )'
779
793
  else
780
794
  visit o.expr, collector
781
795
  end