arel_extensions 1.2.2 → 1.2.13
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 +5 -5
- data/.rubocop.yml +7 -4
- data/.travis.yml +59 -91
- data/Gemfile +2 -2
- data/README.md +17 -12
- data/Rakefile +38 -27
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +1 -1
- data/functions.html +3 -3
- data/gemfiles/rails4.gemfile +1 -1
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +14 -0
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions.rb +63 -19
- data/lib/arel_extensions/attributes.rb +0 -1
- data/lib/arel_extensions/boolean_functions.rb +38 -13
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/comparators.rb +4 -2
- data/lib/arel_extensions/insert_manager.rb +26 -24
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +10 -5
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
- data/lib/arel_extensions/nodes/blank.rb +14 -11
- data/lib/arel_extensions/nodes/case.rb +8 -4
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/change_case.rb +2 -2
- data/lib/arel_extensions/nodes/coalesce.rb +2 -2
- data/lib/arel_extensions/nodes/collate.rb +12 -12
- data/lib/arel_extensions/nodes/concat.rb +6 -13
- data/lib/arel_extensions/nodes/date_diff.rb +3 -5
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +8 -8
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
- data/lib/arel_extensions/nodes/function.rb +10 -0
- data/lib/arel_extensions/nodes/is_null.rb +10 -8
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +5 -5
- data/lib/arel_extensions/nodes/locate.rb +7 -7
- data/lib/arel_extensions/nodes/matches.rb +4 -4
- data/lib/arel_extensions/nodes/power.rb +6 -5
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +24 -6
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +16 -15
- data/lib/arel_extensions/nodes/std.rb +19 -21
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/sum.rb +7 -0
- data/lib/arel_extensions/nodes/trim.rb +3 -3
- data/lib/arel_extensions/nodes/union.rb +2 -3
- data/lib/arel_extensions/nodes/union_all.rb +1 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/predications.rb +35 -33
- data/lib/arel_extensions/set_functions.rb +16 -16
- data/lib/arel_extensions/string_functions.rb +34 -12
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +18 -17
- data/lib/arel_extensions/visitors/mysql.rb +92 -46
- data/lib/arel_extensions/visitors/oracle.rb +40 -28
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +80 -34
- data/lib/arel_extensions/visitors/sqlite.rb +54 -46
- data/lib/arel_extensions/visitors/to_sql.rb +75 -62
- data/test/arelx_test_helper.rb +28 -0
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +4 -0
- data/test/test_comparators.rb +9 -8
- data/test/visitors/test_bulk_insert_oracle.rb +8 -7
- data/test/visitors/test_bulk_insert_sqlite.rb +9 -8
- data/test/visitors/test_bulk_insert_to_sql.rb +8 -10
- data/test/visitors/test_oracle.rb +41 -40
- data/test/visitors/test_to_sql.rb +367 -193
- data/test/with_ar/all_agnostic_test.rb +85 -39
- data/test/with_ar/insert_agnostic_test.rb +3 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -5
- data/test/with_ar/test_math_sqlite.rb +4 -4
- data/test/with_ar/test_string_mysql.rb +4 -6
- data/test/with_ar/test_string_sqlite.rb +3 -7
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +13 -7
- data/test/helper.rb +0 -18
@@ -1,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
Arel::Visitors::MySQL
|
3
|
+
class Arel::Visitors::MySQL
|
4
4
|
Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
5
5
|
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
6
6
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
@@ -97,26 +97,28 @@ module ArelExtensions
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
charset =
|
101
|
+
case o.expressions.first
|
102
|
+
when Arel::Attributes::Attribute
|
103
|
+
case o.option
|
103
104
|
when 'latin1','utf8'
|
104
105
|
o.option
|
105
106
|
else
|
106
107
|
Arel::Table.engine.connection.charset || 'utf8'
|
107
108
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
else
|
110
|
+
(o.option == 'latin1') ? 'latin1' : 'utf8'
|
111
|
+
end
|
111
112
|
collector = visit o.expressions.first, collector
|
112
|
-
|
113
|
-
|
113
|
+
collector <<
|
114
|
+
if o.ai
|
115
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
114
116
|
#doesn't work in latin1
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
117
|
+
elsif o.ci
|
118
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
119
|
+
else
|
120
|
+
" COLLATE #{charset}_bin"
|
121
|
+
end
|
120
122
|
collector
|
121
123
|
end
|
122
124
|
|
@@ -139,16 +141,16 @@ module ArelExtensions
|
|
139
141
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
140
142
|
collector << "GROUP_CONCAT("
|
141
143
|
collector = visit o.left, collector
|
142
|
-
if !o.
|
144
|
+
if !o.order.blank?
|
143
145
|
collector << ' ORDER BY '
|
144
|
-
o.
|
146
|
+
o.order.each_with_index do |order,i|
|
145
147
|
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
146
148
|
collector = visit order, collector
|
147
149
|
end
|
148
150
|
end
|
149
|
-
if o.
|
151
|
+
if o.separator && o.separator != 'NULL'
|
150
152
|
collector << ' SEPARATOR '
|
151
|
-
collector = visit o.
|
153
|
+
collector = visit o.separator, collector
|
152
154
|
end
|
153
155
|
collector << ")"
|
154
156
|
collector
|
@@ -191,6 +193,13 @@ module ArelExtensions
|
|
191
193
|
collector
|
192
194
|
end
|
193
195
|
|
196
|
+
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
197
|
+
if !regexp_replace_supported?
|
198
|
+
warn("Warning : ArelExtensions: REGEXP_REPLACE does not seem to be available in the current version of the DBMS, it might crash")
|
199
|
+
end
|
200
|
+
super(o,collector)
|
201
|
+
end
|
202
|
+
|
194
203
|
def visit_ArelExtensions_Nodes_Format o, collector
|
195
204
|
case o.col_type
|
196
205
|
when :date, :datetime
|
@@ -262,7 +271,7 @@ module ArelExtensions
|
|
262
271
|
else
|
263
272
|
if o.with_interval
|
264
273
|
case o.left
|
265
|
-
when
|
274
|
+
when 'd','m','y'
|
266
275
|
interval = 'DAY'
|
267
276
|
when 'h','mn','s'
|
268
277
|
interval = 'SECOND'
|
@@ -284,22 +293,14 @@ module ArelExtensions
|
|
284
293
|
|
285
294
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
286
295
|
collector << "ISNULL("
|
287
|
-
collector = visit o.
|
288
|
-
if o.right
|
289
|
-
collector << Arel::Visitors::MySQL::COMMA
|
290
|
-
collector = visit o.right, collector
|
291
|
-
end
|
296
|
+
collector = visit o.expr, collector
|
292
297
|
collector << ")"
|
293
298
|
collector
|
294
299
|
end
|
295
300
|
|
296
301
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
297
302
|
collector << "NOT ISNULL("
|
298
|
-
collector = visit o.
|
299
|
-
if o.right
|
300
|
-
collector << Arel::Visitors::MySQL::COMMA
|
301
|
-
collector = visit o.right, collector
|
302
|
-
end
|
303
|
+
collector = visit o.expr, collector
|
303
304
|
collector << ")"
|
304
305
|
collector
|
305
306
|
end
|
@@ -370,20 +371,21 @@ module ArelExtensions
|
|
370
371
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
371
372
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
372
373
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
374
|
+
number =
|
375
|
+
if o.scientific_notation
|
376
|
+
ArelExtensions::Nodes::Concat.new([
|
377
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
378
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
|
379
|
+
]+params),
|
380
|
+
o.type,
|
381
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
382
|
+
col.abs.log10.floor,
|
383
|
+
0
|
384
|
+
])
|
382
385
|
])
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
end
|
386
|
+
else
|
387
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
|
388
|
+
end
|
387
389
|
|
388
390
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
389
391
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -406,10 +408,34 @@ module ArelExtensions
|
|
406
408
|
collector
|
407
409
|
end
|
408
410
|
|
411
|
+
def visit_Aggregate_For_AggregateFunction o, collector
|
412
|
+
if !window_supported?
|
413
|
+
warn("Warning : ArelExtensions: Window Functions are not available in the current version of the DBMS.")
|
414
|
+
return collector
|
415
|
+
end
|
416
|
+
|
417
|
+
if !o.order.empty? || !o.group.empty?
|
418
|
+
collector << " OVER ("
|
419
|
+
if !o.group.empty?
|
420
|
+
collector << " PARTITION BY ("
|
421
|
+
visit o.group, collector
|
422
|
+
collector << ")"
|
423
|
+
end
|
424
|
+
if !o.order.empty?
|
425
|
+
collector << " ORDER BY ("
|
426
|
+
visit o.order, collector
|
427
|
+
collector << ")"
|
428
|
+
end
|
429
|
+
collector << ")"
|
430
|
+
end
|
431
|
+
collector
|
432
|
+
end
|
433
|
+
|
409
434
|
def visit_ArelExtensions_Nodes_Std o, collector
|
410
435
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
411
436
|
visit o.left, collector
|
412
437
|
collector << ")"
|
438
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
413
439
|
collector
|
414
440
|
end
|
415
441
|
|
@@ -417,15 +443,35 @@ module ArelExtensions
|
|
417
443
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
418
444
|
visit o.left, collector
|
419
445
|
collector << ")"
|
446
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
420
447
|
collector
|
421
448
|
end
|
422
449
|
|
423
450
|
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
424
451
|
def json_supported?
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
452
|
+
version_supported?('10.2.3', '5.7.0')
|
453
|
+
end
|
454
|
+
|
455
|
+
def window_supported?
|
456
|
+
version_supported?('10.2.3', '8.0')
|
457
|
+
end
|
458
|
+
|
459
|
+
def regexp_replace_supported?
|
460
|
+
version_supported?('10.0.5', '8.0')
|
461
|
+
end
|
462
|
+
|
463
|
+
def version_supported?(mariadb_v = '10.2.3', mysql_v = '5.7.0')
|
464
|
+
conn = Arel::Table.engine.connection
|
465
|
+
conn.send(:mariadb?) && \
|
466
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mariadb_v || \
|
467
|
+
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v || \
|
468
|
+
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mariadb_v) || \
|
469
|
+
!conn.send(:mariadb?) && \
|
470
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v || \
|
471
|
+
conn.respond_to?(:version) && conn.send(:version) >= mysql_v || \
|
472
|
+
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mysql_v)
|
473
|
+
# ideally we should parse the instance_variable @full_version because @version contains only the supposedly
|
474
|
+
# corresponding mysql version of the current mariadb version (which is not very helpful most of the time)
|
429
475
|
end
|
430
476
|
|
431
477
|
def visit_ArelExtensions_Nodes_Json o,collector
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#require 'oracle_visitor'
|
2
2
|
module ArelExtensions
|
3
3
|
module Visitors
|
4
|
-
Arel::Visitors::Oracle
|
4
|
+
class Arel::Visitors::Oracle
|
5
5
|
|
6
6
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
7
7
|
Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
@@ -131,14 +131,15 @@ module ArelExtensions
|
|
131
131
|
collector << "(LISTAGG("
|
132
132
|
collector = visit o.left, collector
|
133
133
|
collector << Arel::Visitors::Oracle::COMMA
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
collector =
|
135
|
+
if o.separator && o.separator != 'NULL'
|
136
|
+
visit o.separator, collector
|
137
|
+
else
|
138
|
+
visit Arel::Nodes.build_quoted(','), collector
|
139
|
+
end
|
139
140
|
collector << ") WITHIN GROUP (ORDER BY "
|
140
|
-
if !o.
|
141
|
-
o.
|
141
|
+
if !o.order.blank?
|
142
|
+
o.order.each_with_index do |order,i|
|
142
143
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
143
144
|
collector = visit order, collector
|
144
145
|
end
|
@@ -154,8 +155,8 @@ module ArelExtensions
|
|
154
155
|
o.expressions.each_with_index { |arg, i|
|
155
156
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
156
157
|
if i > 0 && o.left_node_type == :text
|
157
|
-
if arg == ''
|
158
|
-
collector <<
|
158
|
+
if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
|
159
|
+
collector << "NULL"
|
159
160
|
else
|
160
161
|
collector << 'TO_CLOB('
|
161
162
|
collector = visit arg, collector
|
@@ -257,9 +258,15 @@ module ArelExtensions
|
|
257
258
|
collector << ")"
|
258
259
|
return collector
|
259
260
|
when :time
|
260
|
-
|
261
|
-
|
262
|
-
|
261
|
+
if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
|
262
|
+
collector << "TO_DATE("
|
263
|
+
collector = visit o.left, collector
|
264
|
+
collector << ",'HH24:MI:SS')"
|
265
|
+
else
|
266
|
+
collector << "TO_DATE(TO_CHAR("
|
267
|
+
collector = visit o.left, collector
|
268
|
+
collector << ",'HH24:MI:SS'),'HH24:MI:SS')"
|
269
|
+
end
|
263
270
|
return collector
|
264
271
|
when :number, :decimal
|
265
272
|
collector << "TO_NUMBER("
|
@@ -269,9 +276,15 @@ module ArelExtensions
|
|
269
276
|
when :datetime
|
270
277
|
as_attr = Arel::Nodes::SqlLiteral.new('timestamp')
|
271
278
|
when :date
|
272
|
-
|
273
|
-
|
274
|
-
|
279
|
+
if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
|
280
|
+
collector << "TO_DATE("
|
281
|
+
collector = visit o.left, collector
|
282
|
+
collector << ",'YYYY-MM-DD')"
|
283
|
+
else
|
284
|
+
collector << "TO_DATE(TO_CHAR("
|
285
|
+
collector = visit o.left, collector
|
286
|
+
collector << ",'YYYY-MM-DD'),'YYYY-MM-DD')"
|
287
|
+
end
|
275
288
|
return collector
|
276
289
|
when :binary
|
277
290
|
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
@@ -294,13 +307,13 @@ module ArelExtensions
|
|
294
307
|
end
|
295
308
|
|
296
309
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
297
|
-
collector = visit o.
|
310
|
+
collector = visit o.expr, collector
|
298
311
|
collector << ' IS NULL'
|
299
312
|
collector
|
300
313
|
end
|
301
314
|
|
302
315
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
303
|
-
collector = visit o.
|
316
|
+
collector = visit o.expr, collector
|
304
317
|
collector << ' IS NOT NULL'
|
305
318
|
collector
|
306
319
|
end
|
@@ -407,11 +420,11 @@ module ArelExtensions
|
|
407
420
|
end
|
408
421
|
|
409
422
|
def visit_ArelExtensions_Nodes_Blank o, collector
|
410
|
-
visit o.
|
423
|
+
visit o.expr.trim.length.coalesce(0).eq(0), collector
|
411
424
|
end
|
412
425
|
|
413
426
|
def visit_ArelExtensions_Nodes_NotBlank o, collector
|
414
|
-
visit o.
|
427
|
+
visit o.expr.trim.length.coalesce(0).gt(0), collector
|
415
428
|
end
|
416
429
|
|
417
430
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
@@ -454,14 +467,12 @@ module ArelExtensions
|
|
454
467
|
o.left.each_with_index do |row, idx| # values
|
455
468
|
collector << " UNION ALL " if idx != 0
|
456
469
|
collector << "(SELECT "
|
457
|
-
|
458
|
-
|
459
|
-
v.expressions.each_with_index { |value, i|
|
470
|
+
len = row.length - 1
|
471
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
460
472
|
case value
|
461
473
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
462
474
|
collector = visit value, collector
|
463
475
|
else
|
464
|
-
attr = v.columns[i]
|
465
476
|
collector << quote(value, attr && column_for(attr)).to_s
|
466
477
|
end
|
467
478
|
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
@@ -477,12 +488,13 @@ module ArelExtensions
|
|
477
488
|
o.left.each_with_index do |row, idx|
|
478
489
|
collector << " UNION ALL " if idx != 0
|
479
490
|
collector << "(SELECT "
|
480
|
-
|
481
|
-
|
482
|
-
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
491
|
+
len = row.length - 1
|
492
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
483
493
|
case value
|
484
494
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
485
495
|
collector = visit value, collector
|
496
|
+
when Integer
|
497
|
+
collector << value.to_s
|
486
498
|
else
|
487
499
|
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
488
500
|
end
|
@@ -571,7 +583,7 @@ module ArelExtensions
|
|
571
583
|
else
|
572
584
|
collector = visit o.left, collector
|
573
585
|
end
|
574
|
-
quote = o.right.to_s =~ /[
|
586
|
+
quote = o.right.to_s =~ /(\A["].*["]\z)|\A[a-zA-Z_]*\z/ ? '' : '"'
|
575
587
|
collector << " AS #{quote}"
|
576
588
|
collector = visit o.right, collector
|
577
589
|
collector << "#{quote}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
Arel::Visitors::PostgreSQL
|
3
|
+
class Arel::Visitors::PostgreSQL
|
4
4
|
Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
5
5
|
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
|
6
6
|
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
@@ -83,23 +83,49 @@ module ArelExtensions
|
|
83
83
|
collector
|
84
84
|
end
|
85
85
|
|
86
|
+
def visit_Aggregate_For_AggregateFunction o, collector
|
87
|
+
if !o.order.blank? || !o.group.blank?
|
88
|
+
collector << " OVER ("
|
89
|
+
if !o.group.blank?
|
90
|
+
collector << " PARTITION BY "
|
91
|
+
o.group.each_with_index do |group, i|
|
92
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
93
|
+
visit group, collector
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if !o.order.blank?
|
97
|
+
collector << " ORDER BY "
|
98
|
+
o.order.each_with_index do |order, i|
|
99
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
100
|
+
visit order, collector
|
101
|
+
end
|
102
|
+
end
|
103
|
+
collector << ")"
|
104
|
+
end
|
105
|
+
collector
|
106
|
+
end
|
107
|
+
|
86
108
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
87
109
|
collector << "array_to_string(array_agg("
|
88
110
|
collector = visit o.left, collector
|
89
|
-
if !o.
|
90
|
-
collector <<
|
91
|
-
o.
|
111
|
+
if o.order && !o.order.blank?
|
112
|
+
collector << " ORDER BY"
|
113
|
+
o.order.each_with_index do |order, i|
|
92
114
|
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
93
|
-
collector
|
115
|
+
collector << " "
|
116
|
+
visit order, collector
|
94
117
|
end
|
95
118
|
end
|
96
119
|
collector << ")"
|
120
|
+
o.order = nil
|
121
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
97
122
|
collector << Arel::Visitors::PostgreSQL::COMMA
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
123
|
+
collector =
|
124
|
+
if o.separator && o.separator != 'NULL'
|
125
|
+
visit o.separator, collector
|
126
|
+
else
|
127
|
+
visit Arel::Nodes.build_quoted(','), collector
|
128
|
+
end
|
103
129
|
collector << ")"
|
104
130
|
collector
|
105
131
|
end
|
@@ -277,14 +303,30 @@ module ArelExtensions
|
|
277
303
|
collector
|
278
304
|
end
|
279
305
|
|
306
|
+
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
307
|
+
collector << "REGEXP_REPLACE("
|
308
|
+
visit o.left, collector
|
309
|
+
collector << Arel::Visitors::ToSql::COMMA
|
310
|
+
tab = o.pattern.inspect+ 'g' # Make it always global
|
311
|
+
pattern = tab.split('/')[1..-2].join('/')
|
312
|
+
flags = tab.split('/')[-1]
|
313
|
+
visit Arel::Nodes.build_quoted(pattern), collector
|
314
|
+
collector << Arel::Visitors::ToSql::COMMA
|
315
|
+
visit o.substitute, collector
|
316
|
+
collector << Arel::Visitors::ToSql::COMMA
|
317
|
+
visit Arel::Nodes.build_quoted(flags+"g"), collector
|
318
|
+
collector << ")"
|
319
|
+
collector
|
320
|
+
end
|
321
|
+
|
280
322
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
281
|
-
collector = visit o.
|
323
|
+
collector = visit o.expr, collector
|
282
324
|
collector << ' IS NULL'
|
283
325
|
collector
|
284
326
|
end
|
285
327
|
|
286
328
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
287
|
-
collector = visit o.
|
329
|
+
collector = visit o.expr, collector
|
288
330
|
collector << ' IS NOT NULL'
|
289
331
|
collector
|
290
332
|
end
|
@@ -293,6 +335,7 @@ module ArelExtensions
|
|
293
335
|
collector << "sum("
|
294
336
|
collector = visit o.expr, collector
|
295
337
|
collector << ")"
|
338
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
296
339
|
collector
|
297
340
|
end
|
298
341
|
|
@@ -345,27 +388,28 @@ module ArelExtensions
|
|
345
388
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
346
389
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
347
390
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
391
|
+
number =
|
392
|
+
if o.scientific_notation
|
393
|
+
ArelExtensions::Nodes::Concat.new([
|
394
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
395
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
396
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
397
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
398
|
+
])]),
|
399
|
+
o.type,
|
400
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
401
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
402
|
+
col.abs.log10.floor,
|
403
|
+
Arel::Nodes.build_quoted('FM'+nines_before)
|
404
|
+
])])
|
405
|
+
])
|
406
|
+
else
|
407
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
408
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
409
|
+
Arel::Nodes.build_quoted(col.abs),
|
410
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
411
|
+
])])
|
412
|
+
end
|
369
413
|
|
370
414
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
371
415
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -420,6 +464,7 @@ module ArelExtensions
|
|
420
464
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
421
465
|
visit o.left, collector
|
422
466
|
collector << ")"
|
467
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
423
468
|
collector
|
424
469
|
end
|
425
470
|
|
@@ -427,6 +472,7 @@ module ArelExtensions
|
|
427
472
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
428
473
|
visit o.left, collector
|
429
474
|
collector << ")"
|
475
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
430
476
|
collector
|
431
477
|
end
|
432
478
|
|
@@ -438,7 +484,7 @@ module ArelExtensions
|
|
438
484
|
if i != 0
|
439
485
|
collector << Arel::Visitors::MySQL::COMMA
|
440
486
|
end
|
441
|
-
collector
|
487
|
+
collector = visit v, collector
|
442
488
|
end
|
443
489
|
collector << '])'
|
444
490
|
when Hash
|