arel_extensions 2.0.21 → 2.2.2

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -2
  3. data/.github/workflows/publish.yml +29 -0
  4. data/.github/workflows/release.yml +30 -0
  5. data/.github/workflows/ruby.yml +377 -80
  6. data/.gitignore +7 -6
  7. data/.rubocop.yml +62 -1
  8. data/CONTRIBUTING.md +102 -0
  9. data/Gemfile +2 -23
  10. data/NEWS.md +89 -0
  11. data/README.md +228 -84
  12. data/Rakefile +11 -4
  13. data/TODO +0 -1
  14. data/appveyor.yml +60 -22
  15. data/arel_extensions.gemspec +11 -12
  16. data/bin/build +15 -0
  17. data/bin/compose +6 -0
  18. data/bin/publish +8 -0
  19. data/dev/arelx.dockerfile +44 -0
  20. data/dev/compose.yaml +71 -0
  21. data/dev/postgres.dockerfile +5 -0
  22. data/dev/rbenv +189 -0
  23. data/gemfiles/rails3.gemfile +10 -10
  24. data/gemfiles/rails4_2.gemfile +38 -0
  25. data/gemfiles/rails5.gemfile +29 -0
  26. data/gemfiles/rails5_1_4.gemfile +13 -13
  27. data/gemfiles/rails5_2.gemfile +16 -14
  28. data/gemfiles/rails6.gemfile +18 -15
  29. data/gemfiles/rails6_1.gemfile +18 -15
  30. data/gemfiles/rails7.gemfile +33 -0
  31. data/gemfiles/rails7_1.gemfile +33 -0
  32. data/gemfiles/rails7_2.gemfile +33 -0
  33. data/gemspecs/arel_extensions-v1.gemspec +12 -13
  34. data/gemspecs/arel_extensions-v2.gemspec +11 -12
  35. data/init/mssql.sql +0 -0
  36. data/init/mysql.sql +0 -0
  37. data/init/oracle.sql +0 -0
  38. data/init/postgresql.sql +0 -0
  39. data/init/sqlite.sql +0 -0
  40. data/lib/arel_extensions/aliases.rb +14 -0
  41. data/lib/arel_extensions/attributes.rb +10 -2
  42. data/lib/arel_extensions/boolean_functions.rb +2 -4
  43. data/lib/arel_extensions/common_sql_functions.rb +12 -12
  44. data/lib/arel_extensions/comparators.rb +14 -14
  45. data/lib/arel_extensions/date_duration.rb +14 -9
  46. data/lib/arel_extensions/helpers.rb +62 -0
  47. data/lib/arel_extensions/insert_manager.rb +19 -17
  48. data/lib/arel_extensions/math.rb +48 -45
  49. data/lib/arel_extensions/math_functions.rb +18 -18
  50. data/lib/arel_extensions/nodes/abs.rb +0 -0
  51. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
  52. data/lib/arel_extensions/nodes/blank.rb +1 -1
  53. data/lib/arel_extensions/nodes/case.rb +10 -12
  54. data/lib/arel_extensions/nodes/cast.rb +6 -6
  55. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  56. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  57. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  58. data/lib/arel_extensions/nodes/collate.rb +9 -9
  59. data/lib/arel_extensions/nodes/concat.rb +2 -2
  60. data/lib/arel_extensions/nodes/date_diff.rb +33 -14
  61. data/lib/arel_extensions/nodes/duration.rb +0 -0
  62. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  63. data/lib/arel_extensions/nodes/floor.rb +0 -0
  64. data/lib/arel_extensions/nodes/format.rb +3 -2
  65. data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
  66. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  67. data/lib/arel_extensions/nodes/function.rb +22 -26
  68. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  69. data/lib/arel_extensions/nodes/json.rb +15 -9
  70. data/lib/arel_extensions/nodes/length.rb +6 -0
  71. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  72. data/lib/arel_extensions/nodes/locate.rb +1 -1
  73. data/lib/arel_extensions/nodes/log10.rb +0 -0
  74. data/lib/arel_extensions/nodes/matches.rb +1 -1
  75. data/lib/arel_extensions/nodes/md5.rb +0 -0
  76. data/lib/arel_extensions/nodes/power.rb +0 -0
  77. data/lib/arel_extensions/nodes/rand.rb +0 -0
  78. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  79. data/lib/arel_extensions/nodes/replace.rb +2 -10
  80. data/lib/arel_extensions/nodes/rollup.rb +36 -0
  81. data/lib/arel_extensions/nodes/round.rb +0 -0
  82. data/lib/arel_extensions/nodes/select.rb +10 -0
  83. data/lib/arel_extensions/nodes/soundex.rb +2 -2
  84. data/lib/arel_extensions/nodes/std.rb +0 -0
  85. data/lib/arel_extensions/nodes/substring.rb +1 -1
  86. data/lib/arel_extensions/nodes/sum.rb +0 -0
  87. data/lib/arel_extensions/nodes/then.rb +1 -1
  88. data/lib/arel_extensions/nodes/trim.rb +2 -2
  89. data/lib/arel_extensions/nodes/union.rb +5 -5
  90. data/lib/arel_extensions/nodes/union_all.rb +4 -4
  91. data/lib/arel_extensions/nodes/wday.rb +0 -0
  92. data/lib/arel_extensions/nodes.rb +0 -0
  93. data/lib/arel_extensions/null_functions.rb +16 -0
  94. data/lib/arel_extensions/predications.rb +10 -10
  95. data/lib/arel_extensions/railtie.rb +1 -1
  96. data/lib/arel_extensions/set_functions.rb +3 -3
  97. data/lib/arel_extensions/string_functions.rb +19 -10
  98. data/lib/arel_extensions/tasks.rb +2 -2
  99. data/lib/arel_extensions/version.rb +1 -1
  100. data/lib/arel_extensions/visitors/convert_format.rb +0 -0
  101. data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
  102. data/lib/arel_extensions/visitors/mssql.rb +394 -169
  103. data/lib/arel_extensions/visitors/mysql.rb +238 -151
  104. data/lib/arel_extensions/visitors/oracle.rb +170 -131
  105. data/lib/arel_extensions/visitors/oracle12.rb +16 -16
  106. data/lib/arel_extensions/visitors/postgresql.rb +170 -140
  107. data/lib/arel_extensions/visitors/sqlite.rb +88 -87
  108. data/lib/arel_extensions/visitors/to_sql.rb +185 -156
  109. data/lib/arel_extensions/visitors.rb +73 -60
  110. data/lib/arel_extensions.rb +173 -36
  111. data/test/arelx_test_helper.rb +49 -1
  112. data/test/database.yml +13 -7
  113. data/test/real_db_test.rb +101 -83
  114. data/test/support/fake_record.rb +8 -2
  115. data/test/test_comparators.rb +5 -5
  116. data/test/visitors/test_bulk_insert_oracle.rb +5 -5
  117. data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
  118. data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
  119. data/test/visitors/test_oracle.rb +14 -14
  120. data/test/visitors/test_to_sql.rb +121 -93
  121. data/test/with_ar/all_agnostic_test.rb +630 -320
  122. data/test/with_ar/insert_agnostic_test.rb +25 -18
  123. data/test/with_ar/test_bulk_sqlite.rb +11 -7
  124. data/test/with_ar/test_math_sqlite.rb +18 -14
  125. data/test/with_ar/test_string_mysql.rb +26 -22
  126. data/test/with_ar/test_string_sqlite.rb +26 -22
  127. data/version_v1.rb +1 -1
  128. data/version_v2.rb +1 -1
  129. metadata +24 -26
  130. data/.travis/oracle/download.js +0 -152
  131. data/.travis/oracle/download.sh +0 -30
  132. data/.travis/oracle/download_ojdbc.js +0 -116
  133. data/.travis/oracle/install.sh +0 -34
  134. data/.travis/setup_accounts.sh +0 -9
  135. data/.travis/sqlite3/extension-functions.sh +0 -6
  136. data/.travis.yml +0 -193
  137. data/gemfiles/rails4.gemfile +0 -29
  138. data/gemfiles/rails5_0.gemfile +0 -29
@@ -8,10 +8,11 @@ module ArelExtensions
8
8
 
9
9
  DATE_FORMAT_DIRECTIVES = {
10
10
  '%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY',
11
- '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
12
- '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
13
- '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
14
- '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
11
+ '%m' => 'MM', '%B' => 'TMMonth', '%^B' => 'TMMONTH', '%b' => 'TMMon', '%^b' => 'TMMON',
12
+ '%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
13
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'TMDy', '%A' => 'TMDay', # day, weekday
14
+ '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
15
+ '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
15
16
  '%%' => '%',
16
17
  }.freeze
17
18
 
@@ -20,33 +21,33 @@ module ArelExtensions
20
21
  }.freeze
21
22
 
22
23
  def visit_ArelExtensions_Nodes_Rand o, collector
23
- collector << "RANDOM("
24
+ collector << 'RANDOM('
24
25
  if (o.left != nil && o.right != nil)
25
26
  collector = visit o.left, collector
26
27
  collector << COMMA
27
28
  collector = isit o.right, collector
28
29
  end
29
- collector << ")"
30
+ collector << ')'
30
31
  collector
31
32
  end
32
33
 
33
34
  def visit_ArelExtensions_Nodes_Power o, collector
34
- collector << "POWER("
35
+ collector << 'POWER('
35
36
  o.expressions.each_with_index { |arg, i|
36
37
  collector << Arel::Visitors::ToSql::COMMA if i != 0
37
38
  collector = visit arg, collector
38
39
  }
39
- collector << ")"
40
+ collector << ')'
40
41
  collector
41
42
  end
42
43
 
43
44
  def visit_ArelExtensions_Nodes_Log10 o, collector
44
- collector << "LOG("
45
+ collector << 'LOG('
45
46
  o.expressions.each_with_index { |arg, i|
46
47
  collector << Arel::Visitors::ToSql::COMMA if i != 0
47
48
  collector = visit arg, collector
48
49
  }
49
- collector << ")"
50
+ collector << ')'
50
51
  collector
51
52
  end
52
53
 
@@ -54,7 +55,7 @@ module ArelExtensions
54
55
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil
55
56
  def visit_Arel_Nodes_Regexp o, collector
56
57
  collector = visit o.left, collector
57
- collector << " ~ "
58
+ collector << ' ~ '
58
59
  collector = visit o.right, collector
59
60
  collector
60
61
  end
@@ -62,7 +63,7 @@ module ArelExtensions
62
63
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
63
64
  def visit_Arel_Nodes_NotRegexp o, collector
64
65
  collector = visit o.left, collector
65
- collector << " !~ "
66
+ collector << ' !~ '
66
67
  collector = visit o.right, collector
67
68
  collector
68
69
  end
@@ -73,7 +74,7 @@ module ArelExtensions
73
74
  collector = visit arg, collector
74
75
  collector << ' || ' unless i == o.expressions.length - 1
75
76
  }
76
- collector << ")"
77
+ collector << ')'
77
78
  collector
78
79
  end
79
80
 
@@ -86,46 +87,52 @@ module ArelExtensions
86
87
  else
87
88
  collector = visit o.left, collector
88
89
  end
89
- collector << " AS \""
90
+ collector << ' AS '
91
+
92
+ # sometimes these values are already quoted, if they are, don't double quote it
93
+ quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
94
+
95
+ collector << '"' if quote
90
96
  collector = visit o.right, collector
91
- collector << "\""
97
+ collector << '"' if quote
98
+
92
99
  collector
93
100
  end
94
101
 
95
102
  def visit_Aggregate_For_AggregateFunction o, collector
96
103
  if !o.order.blank? || !o.group.blank?
97
- collector << " OVER ("
104
+ collector << ' OVER ('
98
105
  if !o.group.blank?
99
- collector << " PARTITION BY "
106
+ collector << ' PARTITION BY '
100
107
  o.group.each_with_index do |group, i|
101
108
  collector << COMMA if i != 0
102
109
  visit group, collector
103
110
  end
104
111
  end
105
112
  if !o.order.blank?
106
- collector << " ORDER BY "
113
+ collector << ' ORDER BY '
107
114
  o.order.each_with_index do |order, i|
108
115
  collector << COMMA if i != 0
109
116
  visit order, collector
110
117
  end
111
118
  end
112
- collector << ")"
119
+ collector << ')'
113
120
  end
114
121
  collector
115
122
  end
116
123
 
117
124
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
118
- collector << "array_to_string(array_agg("
125
+ collector << 'array_to_string(array_agg('
119
126
  collector = visit o.left, collector
120
127
  if o.order && !o.order.blank?
121
- collector << " ORDER BY"
128
+ collector << ' ORDER BY'
122
129
  o.order.each_with_index do |order, i|
123
130
  collector << COMMA if i != 0
124
- collector << " "
131
+ collector << ' '
125
132
  visit order, collector
126
133
  end
127
134
  end
128
- collector << ")"
135
+ collector << ')'
129
136
  o.order = nil
130
137
  visit_Aggregate_For_AggregateFunction o, collector
131
138
  collector << COMMA
@@ -133,56 +140,72 @@ module ArelExtensions
133
140
  if o.separator && o.separator != 'NULL'
134
141
  visit o.separator, collector
135
142
  else
136
- visit Arel::Nodes.build_quoted(','), collector
143
+ visit Arel.quoted(','), collector
137
144
  end
138
- collector << ")"
145
+ collector << ')'
139
146
  collector
140
147
  end
141
148
 
142
149
  def visit_ArelExtensions_Nodes_Trim o, collector
143
- collector << 'TRIM(BOTH '
144
- collector = visit o.right, collector
145
- collector << " FROM "
146
- collector = visit o.left, collector
147
- collector << ")"
148
- collector
150
+ collector << 'TRIM(BOTH '
151
+ collector = visit o.right, collector
152
+ collector << ' FROM '
153
+ collector = visit o.left, collector
154
+ collector << ')'
155
+ collector
149
156
  end
150
157
 
151
158
  def visit_ArelExtensions_Nodes_Ltrim o, collector
152
- collector << 'TRIM(LEADING '
153
- collector = visit o.right, collector
154
- collector << " FROM "
155
- collector = visit o.left, collector
156
- collector << ")"
157
- collector
159
+ collector << 'TRIM(LEADING '
160
+ collector = visit o.right, collector
161
+ collector << ' FROM '
162
+ collector = visit o.left, collector
163
+ collector << ')'
164
+ collector
158
165
  end
159
166
 
160
167
  def visit_ArelExtensions_Nodes_Rtrim o, collector
161
168
  collector << 'TRIM(TRAILING '
162
169
  collector = visit o.right, collector
163
- collector << " FROM "
170
+ collector << ' FROM '
164
171
  collector = visit o.left, collector
165
- collector << ")"
172
+ collector << ')'
166
173
  collector
167
174
  end
168
175
 
169
176
  def visit_ArelExtensions_Nodes_Format o, collector
177
+ visit_ArelExtensions_Nodes_FormattedDate o, collector
178
+ end
179
+
180
+ def visit_ArelExtensions_Nodes_FormattedDate o, collector
170
181
  fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
171
- collector << "TO_CHAR("
182
+ collector << 'TO_CHAR('
183
+ collector << '(' if o.time_zone
172
184
  collector = visit o.left, collector
185
+ case o.time_zone
186
+ when Hash
187
+ src_tz, dst_tz = o.time_zone.first
188
+ collector << ') AT TIME ZONE '
189
+ collector = visit Arel.quoted(src_tz), collector
190
+ collector << ' AT TIME ZONE '
191
+ collector = visit Arel.quoted(dst_tz), collector
192
+ when String
193
+ collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
194
+ collector = visit Arel.quoted(o.time_zone), collector
195
+ end
173
196
  collector << COMMA
174
- collector = visit Arel::Nodes.build_quoted(fmt), collector
175
- collector << ")"
197
+ collector = visit Arel.quoted(fmt), collector
198
+ collector << ')'
176
199
  collector
177
200
  end
178
201
 
179
202
  def visit_ArelExtensions_Nodes_Repeat o, collector
180
- collector << "REPEAT("
203
+ collector << 'REPEAT('
181
204
  o.expressions.each_with_index { |arg, i|
182
205
  collector << Arel::Visitors::ToSql::COMMA if i != 0
183
206
  collector = visit arg, collector
184
207
  }
185
- collector << ")"
208
+ collector << ')'
186
209
  collector
187
210
  end
188
211
 
@@ -224,9 +247,9 @@ module ArelExtensions
224
247
 
225
248
  def visit_ArelExtensions_Nodes_Collate o, collector
226
249
  if o.ai
227
- collector << "unaccent("
250
+ collector << 'unaccent('
228
251
  collector = visit o.expressions.first, collector
229
- collector << ")"
252
+ collector << ')'
230
253
  elsif o.ci
231
254
  collector = visit o.expressions.first, collector
232
255
  else
@@ -245,16 +268,16 @@ module ArelExtensions
245
268
  def visit_ArelExtensions_Nodes_DateDiff o, collector
246
269
  if o.right_node_type == :ruby_date || o.right_node_type == :ruby_time || o.right_node_type == :date || o.right_node_type == :datetime || o.right_node_type == :time
247
270
  collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
248
- "DATEDIFF('second', "
271
+ "DATEDIFF('second', "
249
272
  else
250
- "DATEDIFF('day', "
273
+ "DATEDIFF('day', "
251
274
  end
252
275
  collector = visit o.right, collector
253
276
  collector << (o.right_node_type == :date ? '::date' : '::timestamp')
254
277
  collector << COMMA
255
278
  collector = visit o.left, collector
256
279
  collector << (o.left_node_type == :date ? '::date' : '::timestamp')
257
- collector << ")"
280
+ collector << ')'
258
281
  else
259
282
  collector << '('
260
283
  collector = visit o.left, collector
@@ -271,57 +294,57 @@ module ArelExtensions
271
294
  def visit_ArelExtensions_Nodes_Duration o, collector
272
295
  if o.with_interval
273
296
  interval = case o.left
274
- when 'd','m','y'
297
+ when 'd', 'm', 'y'
275
298
  'DAY'
276
- when 'h','mn','s'
299
+ when 'h', 'mn', 's'
277
300
  'SECOND'
278
301
  when /i\z/
279
- collector << "("
302
+ collector << '('
280
303
  collector = visit o.right, collector
281
- collector << ")"
304
+ collector << ')'
282
305
  collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
283
306
  return collector
284
307
  end
285
308
  end
286
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
309
+ collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM CAST("
287
310
  collector = visit o.right, collector
288
- collector << ")"
311
+ collector << ' AS TIMESTAMP WITH TIME ZONE))'
289
312
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
290
313
  collector
291
314
  end
292
315
 
293
316
  def visit_ArelExtensions_Nodes_Locate o, collector
294
- collector << "POSITION("
317
+ collector << 'POSITION('
295
318
  collector = visit o.right, collector
296
- collector << " IN "
319
+ collector << ' IN '
297
320
  collector = visit o.left, collector
298
- collector << ")"
321
+ collector << ')'
299
322
  collector
300
323
  end
301
324
 
302
325
  def visit_ArelExtensions_Nodes_Substring o, collector
303
- collector << "SUBSTR("
326
+ collector << 'SUBSTR('
304
327
  o.expressions.each_with_index { |arg, i|
305
328
  collector << COMMA if i != 0
306
329
  collector = visit arg, collector
307
330
  }
308
- collector << ")"
331
+ collector << ')'
309
332
  collector
310
333
  end
311
334
 
312
335
  def visit_ArelExtensions_Nodes_RegexpReplace o, collector
313
- collector << "REGEXP_REPLACE("
336
+ collector << 'REGEXP_REPLACE('
314
337
  visit o.left, collector
315
338
  collector << Arel::Visitors::ToSql::COMMA
316
- tab = o.pattern.inspect+ 'g' # Make it always global
339
+ tab = o.pattern.inspect + 'g' # Make it always global
317
340
  pattern = tab.split('/')[1..-2].join('/')
318
341
  flags = tab.split('/')[-1]
319
- visit Arel::Nodes.build_quoted(pattern), collector
342
+ visit Arel.quoted(pattern), collector
320
343
  collector << Arel::Visitors::ToSql::COMMA
321
344
  visit o.substitute, collector
322
345
  collector << Arel::Visitors::ToSql::COMMA
323
- visit Arel::Nodes.build_quoted(flags+"g"), collector
324
- collector << ")"
346
+ visit Arel.quoted(flags + 'g'), collector
347
+ collector << ')'
325
348
  collector
326
349
  end
327
350
 
@@ -332,55 +355,59 @@ module ArelExtensions
332
355
  end
333
356
 
334
357
  def visit_ArelExtensions_Nodes_IsNotNull o, collector
335
- collector = visit o.expr, collector
358
+ collector = visit o.expr, collector
336
359
  collector << ' IS NOT NULL'
337
360
  collector
338
361
  end
339
362
 
340
363
  def visit_ArelExtensions_Nodes_Sum o, collector
341
- collector << "sum("
364
+ collector << 'sum('
342
365
  collector = visit o.expr, collector
343
- collector << ")"
366
+ collector << ')'
344
367
  visit_Aggregate_For_AggregateFunction o, collector
345
368
  collector
346
369
  end
347
370
 
348
371
  def visit_ArelExtensions_Nodes_Wday o, collector
349
- collector << "EXRTACT(DOW, "
372
+ collector << 'EXRTACT(DOW, '
350
373
  collector = visit o.date, collector
351
374
  collector << ')'
352
375
  collector
353
376
  end
354
377
 
355
378
  def visit_ArelExtensions_Nodes_Cast o, collector
356
- as_attr = case o.as_attr
357
- when :string
358
- Arel::Nodes::SqlLiteral.new('varchar')
359
- when :text, :ntext
360
- Arel::Nodes::SqlLiteral.new('text')
361
- when :time
362
- Arel::Nodes::SqlLiteral.new('time')
363
- when :int
364
- collector << "CAST(CAST("
365
- collector = visit o.left, collector
366
- collector << " AS numeric) AS int)"
367
- return collector
368
- when :number, :decimal, :float
369
- Arel::Nodes::SqlLiteral.new('numeric')
370
- when :datetime
371
- Arel::Nodes::SqlLiteral.new('timestamp')
372
- when :date
373
- Arel::Nodes::SqlLiteral.new('date')
374
- when :binary
375
- Arel::Nodes::SqlLiteral.new('binary')
376
- else
377
- Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
378
- end
379
- collector << "CAST("
379
+ as_attr =
380
+ case o.as_attr
381
+ when :string
382
+ 'varchar'
383
+ when :text, :ntext
384
+ 'text'
385
+ when :time
386
+ 'time'
387
+ when :int
388
+ collector << 'CAST(CAST('
389
+ collector = visit o.left, collector
390
+ collector << ' AS numeric) AS int)'
391
+ return collector
392
+ when :number, :decimal, :float
393
+ 'numeric'
394
+ when :datetime
395
+ 'timestamp without time zone'
396
+ when :date
397
+ 'date'
398
+ when :binary
399
+ 'binary'
400
+ when :jsonb
401
+ 'jsonb'
402
+ else
403
+ o.as_attr.to_s
404
+ end
405
+
406
+ collector << 'CAST('
380
407
  collector = visit o.left, collector
381
- collector << " AS "
382
- collector = visit as_attr, collector
383
- collector << ")"
408
+ collector << ' AS '
409
+ collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
410
+ collector << ')'
384
411
  collector
385
412
  end
386
413
 
@@ -389,9 +416,9 @@ module ArelExtensions
389
416
  comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
390
417
  thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
391
418
  nines_after = (1..o.precision).map{'9'}.join('')
392
- nines_before = ("999#{thousand_separator}"*4+"990")
419
+ nines_before = ("999#{thousand_separator}" * 4 + '990')
393
420
 
394
- sign = ArelExtensions::Nodes::Case.new.when(col<0).
421
+ sign = Arel.when(col < 0).
395
422
  then('-').
396
423
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
397
424
  sign_length = ArelExtensions::Nodes::Length.new([sign])
@@ -399,35 +426,40 @@ module ArelExtensions
399
426
  number =
400
427
  if o.scientific_notation
401
428
  ArelExtensions::Nodes::Concat.new([
402
- Arel::Nodes::NamedFunction.new('TRIM',[
403
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
404
- col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
405
- Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
429
+ Arel::Nodes::NamedFunction.new('TRIM', [
430
+ Arel::Nodes::NamedFunction.new('TO_CHAR', [
431
+ Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
432
+ Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
406
433
  ])]),
407
434
  o.type,
408
- Arel::Nodes::NamedFunction.new('TRIM',[
409
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
410
- col.abs.log10.floor,
411
- Arel::Nodes.build_quoted('FM'+nines_before)
435
+ Arel::Nodes::NamedFunction.new('TRIM', [
436
+ Arel::Nodes::NamedFunction.new('TO_CHAR', [
437
+ Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
438
+ Arel.quoted("FM#{nines_before}")
412
439
  ])])
413
440
  ])
414
441
  else
415
- Arel::Nodes::NamedFunction.new('TRIM',[
416
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
417
- Arel::Nodes.build_quoted(col.abs),
418
- Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
442
+ Arel::Nodes::NamedFunction.new('TRIM', [
443
+ Arel::Nodes::NamedFunction.new('TO_CHAR', [
444
+ Arel.quoted(col.abs),
445
+ Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
419
446
  ])])
420
447
  end
421
448
 
422
- repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
423
- when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
424
- then(Arel::Nodes.build_quoted(
425
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
426
- ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
427
- ).
428
- else('')
429
- before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
430
- middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
449
+ repeated_char =
450
+ if o.width == 0
451
+ Arel.quoted('')
452
+ else
453
+ Arel
454
+ .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
455
+ .then(Arel.quoted(
456
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
457
+ ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
458
+ )
459
+ .else('')
460
+ end
461
+ before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
462
+ middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
431
463
  after = o.flags.include?('-') ? repeated_char : ''
432
464
  full_number = ArelExtensions::Nodes::Concat.new([
433
465
  before,
@@ -436,7 +468,7 @@ module ArelExtensions
436
468
  number,
437
469
  after
438
470
  ])
439
- collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
471
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
440
472
  collector
441
473
  end
442
474
 
@@ -448,7 +480,7 @@ module ArelExtensions
448
480
  o = o.dup
449
481
  o.orders = []
450
482
  end
451
- old_visit_Arel_Nodes_SelectStatement(o,collector)
483
+ old_visit_Arel_Nodes_SelectStatement(o, collector)
452
484
  end
453
485
 
454
486
  alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
@@ -456,7 +488,7 @@ module ArelExtensions
456
488
  if o.name.length > 63
457
489
  o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
458
490
  end
459
- old_visit_Arel_Nodes_TableAlias(o,collector)
491
+ old_visit_Arel_Nodes_TableAlias(o, collector)
460
492
  end
461
493
 
462
494
  alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
@@ -469,26 +501,26 @@ module ArelExtensions
469
501
  end
470
502
 
471
503
  def visit_ArelExtensions_Nodes_Std o, collector
472
- collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
504
+ collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
473
505
  visit o.left, collector
474
- collector << ")"
506
+ collector << ')'
475
507
  visit_Aggregate_For_AggregateFunction o, collector
476
508
  collector
477
509
  end
478
510
 
479
511
  def visit_ArelExtensions_Nodes_Variance o, collector
480
- collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
512
+ collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
481
513
  visit o.left, collector
482
- collector << ")"
514
+ collector << ')'
483
515
  visit_Aggregate_For_AggregateFunction o, collector
484
516
  collector
485
517
  end
486
518
 
487
- def visit_ArelExtensions_Nodes_Json o,collector
519
+ def visit_ArelExtensions_Nodes_Json o, collector
488
520
  case o.dict
489
521
  when Array
490
522
  collector << 'to_jsonb(array['
491
- o.dict.each.with_index do |v,i|
523
+ o.dict.each.with_index do |v, i|
492
524
  if i != 0
493
525
  collector << Arel::Visitors::MySQL::COMMA
494
526
  end
@@ -497,7 +529,7 @@ module ArelExtensions
497
529
  collector << '])'
498
530
  when Hash
499
531
  collector << 'jsonb_build_object('
500
- o.dict.each.with_index do |(k,v),i|
532
+ o.dict.each.with_index do |(k, v), i|
501
533
  if i != 0
502
534
  collector << Arel::Visitors::MySQL::COMMA
503
535
  end
@@ -506,13 +538,11 @@ module ArelExtensions
506
538
  collector = visit v, collector
507
539
  end
508
540
  collector << ')'
509
- when String,Numeric,TrueClass,FalseClass
510
- collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
541
+ when String, Numeric, TrueClass, FalseClass
542
+ collector = visit Arel.quoted("#{o.dict}"), collector
511
543
  collector << '::jsonb'
512
544
  when NilClass
513
- collector << %Q['null'::jsonb]
514
- when Arel::Attributes::Attribute
515
- collector = visit o.dict.cast(:jsonb), collector
545
+ collector << %Q['null'::jsonb]
516
546
  else
517
547
  collector = visit o.dict, collector
518
548
  collector << '::jsonb'
@@ -520,8 +550,8 @@ module ArelExtensions
520
550
  collector
521
551
  end
522
552
 
523
- def visit_ArelExtensions_Nodes_JsonMerge o,collector
524
- o.expressions.each.with_index do |v,i|
553
+ def visit_ArelExtensions_Nodes_JsonMerge o, collector
554
+ o.expressions.each.with_index do |v, i|
525
555
  if i != 0
526
556
  collector << ' || '
527
557
  end
@@ -530,14 +560,14 @@ module ArelExtensions
530
560
  collector
531
561
  end
532
562
 
533
- def visit_ArelExtensions_Nodes_JsonGet o,collector
563
+ def visit_ArelExtensions_Nodes_JsonGet o, collector
534
564
  collector = visit o.dict, collector
535
- collector << ' -> '
565
+ collector << ' ->> '
536
566
  collector = visit o.key, collector
537
567
  collector
538
568
  end
539
569
 
540
- def visit_ArelExtensions_Nodes_JsonSet o,collector
570
+ def visit_ArelExtensions_Nodes_JsonSet o, collector
541
571
  collector << 'jsonb_set('
542
572
  collector = visit o.dict, collector
543
573
  collector << Arel::Visitors::MySQL::COMMA
@@ -559,7 +589,7 @@ module ArelExtensions
559
589
  else
560
590
  case o.dict
561
591
  when Hash
562
- o.dict.each.with_index do |(k,v),i|
592
+ o.dict.each.with_index do |(k, v), i|
563
593
  if i != 0
564
594
  collector << ' || '
565
595
  end