arel_extensions 1.2.25 → 2.0.0.rc3
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/.rubocop.yml +4 -7
- data/.travis.yml +91 -61
- data/Gemfile +20 -15
- data/README.md +12 -17
- data/Rakefile +29 -40
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +3 -3
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions/attributes.rb +1 -0
- data/lib/arel_extensions/boolean_functions.rb +14 -55
- data/lib/arel_extensions/common_sql_functions.rb +8 -7
- data/lib/arel_extensions/comparators.rb +15 -14
- data/lib/arel_extensions/date_duration.rb +5 -4
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +12 -11
- data/lib/arel_extensions/math_functions.rb +22 -29
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -0
- data/lib/arel_extensions/nodes/case.rb +8 -11
- data/lib/arel_extensions/nodes/cast.rb +2 -4
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +3 -2
- data/lib/arel_extensions/nodes/collate.rb +2 -1
- data/lib/arel_extensions/nodes/concat.rb +16 -7
- data/lib/arel_extensions/nodes/date_diff.rb +13 -10
- data/lib/arel_extensions/nodes/duration.rb +3 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +8 -34
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +16 -25
- data/lib/arel_extensions/nodes/json.rb +36 -43
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +1 -0
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +6 -4
- data/lib/arel_extensions/nodes/md5.rb +1 -0
- data/lib/arel_extensions/nodes/power.rb +5 -5
- data/lib/arel_extensions/nodes/rand.rb +1 -0
- data/lib/arel_extensions/nodes/repeat.rb +4 -2
- data/lib/arel_extensions/nodes/replace.rb +6 -22
- data/lib/arel_extensions/nodes/round.rb +6 -5
- data/lib/arel_extensions/nodes/soundex.rb +15 -15
- data/lib/arel_extensions/nodes/std.rb +21 -18
- data/lib/arel_extensions/nodes/substring.rb +16 -8
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +5 -3
- data/lib/arel_extensions/nodes/union.rb +5 -2
- data/lib/arel_extensions/nodes/union_all.rb +3 -0
- data/lib/arel_extensions/nodes/wday.rb +4 -0
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +7 -5
- data/lib/arel_extensions/predications.rb +34 -35
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +4 -2
- data/lib/arel_extensions/string_functions.rb +23 -52
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
- data/lib/arel_extensions/visitors/mssql.rb +58 -64
- data/lib/arel_extensions/visitors/mysql.rb +98 -149
- data/lib/arel_extensions/visitors/oracle.rb +70 -73
- data/lib/arel_extensions/visitors/oracle12.rb +15 -2
- data/lib/arel_extensions/visitors/postgresql.rb +63 -116
- data/lib/arel_extensions/visitors/sqlite.rb +70 -83
- data/lib/arel_extensions/visitors/to_sql.rb +110 -142
- data/lib/arel_extensions/visitors.rb +60 -68
- data/lib/arel_extensions.rb +19 -81
- data/test/database.yml +0 -2
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +43 -28
- data/test/support/fake_record.rb +2 -2
- data/test/test_comparators.rb +12 -9
- data/test/visitors/test_bulk_insert_oracle.rb +8 -8
- data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
- data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
- data/test/visitors/test_oracle.rb +42 -42
- data/test/visitors/test_to_sql.rb +196 -361
- data/test/with_ar/all_agnostic_test.rb +160 -195
- data/test/with_ar/insert_agnostic_test.rb +4 -3
- data/test/with_ar/test_bulk_sqlite.rb +9 -6
- data/test/with_ar/test_math_sqlite.rb +12 -8
- data/test/with_ar/test_string_mysql.rb +11 -5
- data/test/with_ar/test_string_sqlite.rb +12 -4
- metadata +11 -22
- data/.github/workflows/ruby.yml +0 -102
- data/gemfiles/rails6.gemfile +0 -30
- data/gemfiles/rails6_1.gemfile +0 -30
- data/gemspecs/arel_extensions-v1.gemspec +0 -28
- data/gemspecs/arel_extensions-v2.gemspec +0 -28
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/sum.rb +0 -7
- data/lib/arel_extensions/visitors/convert_format.rb +0 -37
- data/test/arelx_test_helper.rb +0 -26
- data/version_v1.rb +0 -3
- data/version_v2.rb +0 -3
@@ -1,24 +1,21 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
}.freeze
|
8
|
-
|
9
|
-
DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
3
|
+
Arel::Visitors::MySQL.class_eval do
|
4
|
+
Arel::Visitors::MySQL::COMMA = ", "
|
5
|
+
Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
6
|
+
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
10
7
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
11
8
|
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
|
12
9
|
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
|
13
10
|
'%M' => '%i', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
|
14
|
-
}
|
11
|
+
}
|
15
12
|
|
16
13
|
|
17
|
-
#
|
14
|
+
#Math functions
|
18
15
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
19
16
|
collector << "LOG10("
|
20
17
|
o.expressions.each_with_index { |arg, i|
|
21
|
-
collector << Arel::Visitors::ToSql::COMMA
|
18
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
22
19
|
collector = visit arg, collector
|
23
20
|
}
|
24
21
|
collector << ")"
|
@@ -28,14 +25,14 @@ module ArelExtensions
|
|
28
25
|
def visit_ArelExtensions_Nodes_Power o, collector
|
29
26
|
collector << "POW("
|
30
27
|
o.expressions.each_with_index { |arg, i|
|
31
|
-
collector << Arel::Visitors::ToSql::COMMA
|
28
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
32
29
|
collector = visit arg, collector
|
33
30
|
}
|
34
31
|
collector << ")"
|
35
32
|
collector
|
36
33
|
end
|
37
34
|
|
38
|
-
#
|
35
|
+
#String functions
|
39
36
|
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
40
37
|
collector << 'LOWER('
|
41
38
|
collector = visit o.left, collector
|
@@ -101,35 +98,33 @@ module ArelExtensions
|
|
101
98
|
end
|
102
99
|
|
103
100
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
case o.option
|
101
|
+
case o.expressions.first
|
102
|
+
when Arel::Attributes::Attribute
|
103
|
+
charset = case o.option
|
108
104
|
when 'latin1','utf8'
|
109
105
|
o.option
|
110
106
|
else
|
111
107
|
Arel::Table.engine.connection.charset || 'utf8'
|
112
108
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
109
|
+
else
|
110
|
+
charset = (o.option == 'latin1') ? 'latin1' : 'utf8'
|
111
|
+
end
|
116
112
|
collector = visit o.expressions.first, collector
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
113
|
+
if o.ai
|
114
|
+
collector << " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
115
|
+
#doesn't work in latin1
|
116
|
+
elsif o.ci
|
117
|
+
collector << " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
118
|
+
else
|
119
|
+
collector << " COLLATE #{charset}_bin"
|
120
|
+
end
|
126
121
|
collector
|
127
122
|
end
|
128
123
|
|
129
124
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
130
125
|
collector << "CONCAT("
|
131
126
|
o.expressions.each_with_index { |arg, i|
|
132
|
-
collector << COMMA
|
127
|
+
collector << Arel::Visitors::MySQL::COMMA unless i == 0
|
133
128
|
if (arg.is_a?(Numeric)) || (arg.is_a?(Arel::Attributes::Attribute))
|
134
129
|
collector << "CAST("
|
135
130
|
collector = visit arg, collector
|
@@ -145,16 +140,16 @@ module ArelExtensions
|
|
145
140
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
146
141
|
collector << "GROUP_CONCAT("
|
147
142
|
collector = visit o.left, collector
|
148
|
-
if !o.
|
143
|
+
if !o.orders.blank?
|
149
144
|
collector << ' ORDER BY '
|
150
|
-
o.
|
151
|
-
collector << Arel::Visitors::ToSql::COMMA
|
145
|
+
o.orders.each_with_index do |order,i|
|
146
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
152
147
|
collector = visit order, collector
|
153
148
|
end
|
154
149
|
end
|
155
|
-
if o.
|
150
|
+
if o.right && o.right != 'NULL'
|
156
151
|
collector << ' SEPARATOR '
|
157
|
-
collector = visit o.
|
152
|
+
collector = visit o.right, collector
|
158
153
|
end
|
159
154
|
collector << ")"
|
160
155
|
collector
|
@@ -169,7 +164,7 @@ module ArelExtensions
|
|
169
164
|
collector
|
170
165
|
end
|
171
166
|
|
172
|
-
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
167
|
+
def visit_ArelExtensions_Nodes_Ltrim o , collector
|
173
168
|
collector << 'TRIM(LEADING '
|
174
169
|
collector = visit o.right, collector
|
175
170
|
collector << " FROM "
|
@@ -178,7 +173,7 @@ module ArelExtensions
|
|
178
173
|
collector
|
179
174
|
end
|
180
175
|
|
181
|
-
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
176
|
+
def visit_ArelExtensions_Nodes_Rtrim o , collector
|
182
177
|
collector << 'TRIM(TRAILING '
|
183
178
|
collector = visit o.right, collector
|
184
179
|
collector << " FROM "
|
@@ -190,28 +185,22 @@ module ArelExtensions
|
|
190
185
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
191
186
|
collector << "REPEAT("
|
192
187
|
o.expressions.each_with_index { |arg, i|
|
193
|
-
collector << Arel::Visitors::ToSql::COMMA
|
188
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
194
189
|
collector = visit arg, collector
|
195
190
|
}
|
196
191
|
collector << ")"
|
197
192
|
collector
|
198
193
|
end
|
199
194
|
|
200
|
-
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
201
|
-
if !regexp_replace_supported?
|
202
|
-
warn("Warning : ArelExtensions: REGEXP_REPLACE does not seem to be available in the current version of the DBMS, it might crash")
|
203
|
-
end
|
204
|
-
super(o,collector)
|
205
|
-
end
|
206
|
-
|
207
195
|
def visit_ArelExtensions_Nodes_Format o, collector
|
208
196
|
case o.col_type
|
209
|
-
when :date, :datetime
|
210
|
-
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
197
|
+
when :date, :datetime
|
211
198
|
collector << "DATE_FORMAT("
|
212
199
|
collector = visit o.left, collector
|
213
|
-
collector << COMMA
|
214
|
-
|
200
|
+
collector << Arel::Visitors::MySQL::COMMA
|
201
|
+
f = o.iso_format.dup
|
202
|
+
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
203
|
+
collector = visit Arel::Nodes.build_quoted(f), collector
|
215
204
|
collector << ")"
|
216
205
|
when :integer, :float, :decimal
|
217
206
|
collector << "FORMAT("
|
@@ -228,15 +217,14 @@ module ArelExtensions
|
|
228
217
|
end
|
229
218
|
|
230
219
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
end
|
220
|
+
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
|
221
|
+
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
222
|
+
'TIMESTAMPDIFF(SECOND, '
|
223
|
+
else
|
224
|
+
'DATEDIFF('
|
225
|
+
end
|
238
226
|
collector = visit o.right, collector
|
239
|
-
collector << COMMA
|
227
|
+
collector << Arel::Visitors::MySQL::COMMA
|
240
228
|
collector = visit o.left, collector
|
241
229
|
collector << ")"
|
242
230
|
else
|
@@ -260,12 +248,13 @@ module ArelExtensions
|
|
260
248
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
261
249
|
collector << "DATE_ADD("
|
262
250
|
collector = visit o.left, collector
|
263
|
-
collector << COMMA
|
251
|
+
collector << Arel::Visitors::MySQL::COMMA
|
264
252
|
collector = visit o.mysql_value(o.right), collector
|
265
253
|
collector << ")"
|
266
254
|
collector
|
267
255
|
end
|
268
256
|
|
257
|
+
|
269
258
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
270
259
|
if o.left == 'wd'
|
271
260
|
collector << "(WEEKDAY("
|
@@ -274,18 +263,18 @@ module ArelExtensions
|
|
274
263
|
else
|
275
264
|
if o.with_interval
|
276
265
|
case o.left
|
277
|
-
when
|
266
|
+
when 'd','m','y'
|
278
267
|
interval = 'DAY'
|
279
268
|
when 'h','mn','s'
|
280
269
|
interval = 'SECOND'
|
281
270
|
when /i\z/
|
282
|
-
interval = DATE_MAPPING[o.left[0..-2]]
|
271
|
+
interval = Arel::Visitors::MySQL::DATE_MAPPING[o.left[0..-2]]
|
283
272
|
else
|
284
273
|
interval = nil
|
285
274
|
end
|
286
275
|
end
|
287
276
|
collector << " INTERVAL " if o.with_interval && interval
|
288
|
-
collector << "#{DATE_MAPPING[o.left]}("
|
277
|
+
collector << "#{Arel::Visitors::MySQL::DATE_MAPPING[o.left]}("
|
289
278
|
collector = visit o.right, collector
|
290
279
|
collector << ")"
|
291
280
|
collector << " #{interval} " if o.with_interval && interval
|
@@ -293,6 +282,7 @@ module ArelExtensions
|
|
293
282
|
collector
|
294
283
|
end
|
295
284
|
|
285
|
+
|
296
286
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
297
287
|
collector << "ISNULL("
|
298
288
|
collector = visit o.expr, collector
|
@@ -318,25 +308,30 @@ module ArelExtensions
|
|
318
308
|
collector << "CAST("
|
319
309
|
collector = visit o.left, collector
|
320
310
|
collector << " AS "
|
321
|
-
as_attr
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
)
|
311
|
+
case o.as_attr
|
312
|
+
when :string
|
313
|
+
as_attr = Arel::Nodes::SqlLiteral.new('char')
|
314
|
+
when :time
|
315
|
+
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
316
|
+
when :int
|
317
|
+
as_attr = Arel::Nodes::SqlLiteral.new('signed')
|
318
|
+
when :number, :decimal
|
319
|
+
as_attr = Arel::Nodes::SqlLiteral.new('decimal(20,6)')
|
320
|
+
when :datetime
|
321
|
+
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
322
|
+
when :date
|
323
|
+
as_attr = Arel::Nodes::SqlLiteral.new('date')
|
324
|
+
when :binary
|
325
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
326
|
+
else
|
327
|
+
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
328
|
+
end
|
334
329
|
collector = visit as_attr, collector
|
335
330
|
collector << ")"
|
336
331
|
collector
|
337
332
|
end
|
338
333
|
|
339
|
-
alias_method
|
334
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
340
335
|
def visit_Arel_Nodes_SelectStatement o, collector
|
341
336
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
342
337
|
o = o.dup
|
@@ -345,7 +340,7 @@ module ArelExtensions
|
|
345
340
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
346
341
|
end
|
347
342
|
|
348
|
-
alias_method
|
343
|
+
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
349
344
|
def visit_Arel_Nodes_As o, collector
|
350
345
|
if o.left.is_a?(Arel::Nodes::Binary)
|
351
346
|
collector << '('
|
@@ -368,21 +363,20 @@ module ArelExtensions
|
|
368
363
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
369
364
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
370
365
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
Arel::Nodes
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
0
|
381
|
-
])
|
366
|
+
if o.scientific_notation
|
367
|
+
number = ArelExtensions::Nodes::Concat.new([
|
368
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
369
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
|
370
|
+
]+params),
|
371
|
+
o.type,
|
372
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
373
|
+
col.abs.log10.floor,
|
374
|
+
0
|
382
375
|
])
|
383
|
-
|
384
|
-
|
385
|
-
|
376
|
+
])
|
377
|
+
else
|
378
|
+
number = Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
|
379
|
+
end
|
386
380
|
|
387
381
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
388
382
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -405,34 +399,10 @@ module ArelExtensions
|
|
405
399
|
collector
|
406
400
|
end
|
407
401
|
|
408
|
-
def visit_Aggregate_For_AggregateFunction o, collector
|
409
|
-
if !window_supported?
|
410
|
-
warn("Warning : ArelExtensions: Window Functions are not available in the current version of the DBMS.")
|
411
|
-
return collector
|
412
|
-
end
|
413
|
-
|
414
|
-
if !o.order.empty? || !o.group.empty?
|
415
|
-
collector << " OVER ("
|
416
|
-
if !o.group.empty?
|
417
|
-
collector << " PARTITION BY ("
|
418
|
-
visit o.group, collector
|
419
|
-
collector << ")"
|
420
|
-
end
|
421
|
-
if !o.order.empty?
|
422
|
-
collector << " ORDER BY ("
|
423
|
-
visit o.order, collector
|
424
|
-
collector << ")"
|
425
|
-
end
|
426
|
-
collector << ")"
|
427
|
-
end
|
428
|
-
collector
|
429
|
-
end
|
430
|
-
|
431
402
|
def visit_ArelExtensions_Nodes_Std o, collector
|
432
403
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
433
404
|
visit o.left, collector
|
434
405
|
collector << ")"
|
435
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
436
406
|
collector
|
437
407
|
end
|
438
408
|
|
@@ -440,46 +410,25 @@ module ArelExtensions
|
|
440
410
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
441
411
|
visit o.left, collector
|
442
412
|
collector << ")"
|
443
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
444
413
|
collector
|
445
414
|
end
|
446
415
|
|
447
|
-
# JSON if implemented only after 10.2.3
|
416
|
+
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
448
417
|
def json_supported?
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
version_supported?('10.2.3', '8.0')
|
454
|
-
end
|
455
|
-
|
456
|
-
def regexp_replace_supported?
|
457
|
-
version_supported?('10.0.5', '8.0')
|
458
|
-
end
|
459
|
-
|
460
|
-
def version_supported?(mariadb_v = '10.2.3', mysql_v = '5.7.0')
|
461
|
-
conn = Arel::Table.engine.connection
|
462
|
-
conn.send(:mariadb?) && \
|
463
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mariadb_v || \
|
464
|
-
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v || \
|
465
|
-
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mariadb_v) || \
|
466
|
-
!conn.send(:mariadb?) && \
|
467
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v || \
|
468
|
-
conn.respond_to?(:version) && conn.send(:version) >= mysql_v || \
|
469
|
-
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mysql_v)
|
470
|
-
# ideally we should parse the instance_variable @full_version because @version contains only the supposedly
|
471
|
-
# corresponding mysql version of the current mariadb version (which is not very helpful most of the time)
|
418
|
+
Arel::Table.engine.connection.send(:mariadb?) &&
|
419
|
+
Arel::Table.engine.connection.send(:version) >= '10.2.3' ||
|
420
|
+
!Arel::Table.engine.connection.send(:mariadb?) &&
|
421
|
+
Arel::Table.engine.connection.send(:version) >= '5.7.0'
|
472
422
|
end
|
473
423
|
|
474
424
|
def visit_ArelExtensions_Nodes_Json o,collector
|
475
425
|
return super if !json_supported?
|
476
|
-
|
477
426
|
case o.dict
|
478
427
|
when Array
|
479
428
|
collector << 'JSON_ARRAY('
|
480
429
|
o.dict.each.with_index do |v,i|
|
481
430
|
if i != 0
|
482
|
-
collector << COMMA
|
431
|
+
collector << Arel::Visitors::MySQL::COMMA
|
483
432
|
end
|
484
433
|
collector = visit v, collector
|
485
434
|
end
|
@@ -488,10 +437,10 @@ module ArelExtensions
|
|
488
437
|
collector << 'JSON_OBJECT('
|
489
438
|
o.dict.each.with_index do |(k,v),i|
|
490
439
|
if i != 0
|
491
|
-
collector << COMMA
|
440
|
+
collector << Arel::Visitors::MySQL::COMMA
|
492
441
|
end
|
493
442
|
collector = visit k, collector
|
494
|
-
collector << COMMA
|
443
|
+
collector << Arel::Visitors::MySQL::COMMA
|
495
444
|
collector = visit v, collector
|
496
445
|
end
|
497
446
|
collector << ')'
|
@@ -505,7 +454,7 @@ module ArelExtensions
|
|
505
454
|
collector << 'JSON_MERGE_PATCH('
|
506
455
|
o.expressions.each.with_index do |v,i|
|
507
456
|
if i != 0
|
508
|
-
collector << COMMA
|
457
|
+
collector << Arel::Visitors::MySQL::COMMA
|
509
458
|
end
|
510
459
|
collector = visit v, collector
|
511
460
|
end
|
@@ -516,7 +465,7 @@ module ArelExtensions
|
|
516
465
|
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
517
466
|
collector << 'JSON_EXTRACT('
|
518
467
|
collector = visit o.dict, collector
|
519
|
-
collector << COMMA
|
468
|
+
collector << Arel::Visitors::MySQL::COMMA
|
520
469
|
if o.key.is_a?(Integer)
|
521
470
|
collector << "\"$[#{o.key}]\""
|
522
471
|
else
|
@@ -529,13 +478,13 @@ module ArelExtensions
|
|
529
478
|
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
530
479
|
collector << 'JSON_SET('
|
531
480
|
collector = visit o.dict, collector
|
532
|
-
collector << COMMA
|
481
|
+
collector << Arel::Visitors::MySQL::COMMA
|
533
482
|
if o.key.is_a?(Integer)
|
534
483
|
collector << "\"$[#{o.key}]\""
|
535
484
|
else
|
536
485
|
collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
|
537
486
|
end
|
538
|
-
collector << COMMA
|
487
|
+
collector << Arel::Visitors::MySQL::COMMA
|
539
488
|
collector = visit o.value, collector
|
540
489
|
collector << ')'
|
541
490
|
collector
|
@@ -543,7 +492,6 @@ module ArelExtensions
|
|
543
492
|
|
544
493
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
545
494
|
return super if !json_supported?
|
546
|
-
|
547
495
|
if o.as_array
|
548
496
|
collector << 'JSON_ARRAYAGG('
|
549
497
|
collector = visit o.dict, collector
|
@@ -554,11 +502,11 @@ module ArelExtensions
|
|
554
502
|
collector << 'JSON_MERGE_PATCH(' if o.dict.length > 1
|
555
503
|
o.dict.each.with_index do |(k,v),i|
|
556
504
|
if i != 0
|
557
|
-
collector << COMMA
|
505
|
+
collector << Arel::Visitors::MySQL::COMMA
|
558
506
|
end
|
559
507
|
collector << 'JSON_OBJECTAGG('
|
560
508
|
collector = visit k, collector
|
561
|
-
collector << COMMA
|
509
|
+
collector << Arel::Visitors::MySQL::COMMA
|
562
510
|
collector = visit v, collector
|
563
511
|
collector << ')'
|
564
512
|
end
|
@@ -571,6 +519,7 @@ module ArelExtensions
|
|
571
519
|
end
|
572
520
|
collector
|
573
521
|
end
|
522
|
+
|
574
523
|
end
|
575
524
|
end
|
576
525
|
end
|