arel_extensions 2.0.13 → 2.0.14
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/Gemfile +10 -10
- data/Rakefile +4 -4
- 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/gemfiles/rails6.gemfile +13 -13
- data/lib/arel_extensions.rb +2 -2
- data/lib/arel_extensions/attributes.rb +0 -0
- data/lib/arel_extensions/boolean_functions.rb +3 -7
- data/lib/arel_extensions/common_sql_functions.rb +0 -2
- data/lib/arel_extensions/comparators.rb +11 -14
- data/lib/arel_extensions/date_duration.rb +4 -5
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +8 -9
- data/lib/arel_extensions/math_functions.rb +15 -17
- data/lib/arel_extensions/nodes/abs.rb +0 -1
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
- data/lib/arel_extensions/nodes/blank.rb +0 -1
- data/lib/arel_extensions/nodes/case.rb +3 -4
- data/lib/arel_extensions/nodes/cast.rb +0 -1
- 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 +0 -1
- data/lib/arel_extensions/nodes/collate.rb +0 -1
- data/lib/arel_extensions/nodes/concat.rb +1 -3
- data/lib/arel_extensions/nodes/date_diff.rb +4 -5
- data/lib/arel_extensions/nodes/duration.rb +0 -1
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +1 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
- data/lib/arel_extensions/nodes/function.rb +2 -3
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +0 -6
- data/lib/arel_extensions/nodes/length.rb +0 -1
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -1
- data/lib/arel_extensions/nodes/log10.rb +1 -2
- data/lib/arel_extensions/nodes/matches.rb +0 -2
- data/lib/arel_extensions/nodes/md5.rb +0 -1
- data/lib/arel_extensions/nodes/power.rb +0 -1
- data/lib/arel_extensions/nodes/rand.rb +0 -1
- data/lib/arel_extensions/nodes/repeat.rb +0 -2
- data/lib/arel_extensions/nodes/replace.rb +0 -2
- data/lib/arel_extensions/nodes/round.rb +0 -1
- data/lib/arel_extensions/nodes/soundex.rb +0 -1
- data/lib/arel_extensions/nodes/std.rb +0 -1
- data/lib/arel_extensions/nodes/substring.rb +0 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +0 -2
- data/lib/arel_extensions/nodes/union.rb +0 -2
- data/lib/arel_extensions/nodes/union_all.rb +0 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -4
- data/lib/arel_extensions/null_functions.rb +3 -5
- data/lib/arel_extensions/predications.rb +2 -3
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +0 -2
- data/lib/arel_extensions/string_functions.rb +21 -22
- data/lib/arel_extensions/tasks.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +9 -7
- data/lib/arel_extensions/visitors/convert_format.rb +37 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
- data/lib/arel_extensions/visitors/mssql.rb +48 -44
- data/lib/arel_extensions/visitors/mysql.rb +63 -65
- data/lib/arel_extensions/visitors/oracle.rb +48 -55
- data/lib/arel_extensions/visitors/oracle12.rb +2 -3
- data/lib/arel_extensions/visitors/postgresql.rb +39 -34
- data/lib/arel_extensions/visitors/sqlite.rb +23 -18
- data/lib/arel_extensions/visitors/to_sql.rb +42 -44
- data/test/arelx_test_helper.rb +0 -2
- data/test/real_db_test.rb +26 -41
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +0 -4
- data/test/visitors/test_bulk_insert_oracle.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +16 -25
- data/test/with_ar/all_agnostic_test.rb +134 -139
- data/test/with_ar/insert_agnostic_test.rb +0 -2
- data/test/with_ar/test_bulk_sqlite.rb +0 -4
- data/test/with_ar/test_math_sqlite.rb +4 -8
- data/test/with_ar/test_string_mysql.rb +1 -5
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -2
@@ -1,22 +1,21 @@
|
|
1
|
-
#require 'oracle_visitor'
|
1
|
+
# require 'oracle_visitor'
|
2
2
|
module ArelExtensions
|
3
3
|
module Visitors
|
4
4
|
class Arel::Visitors::Oracle
|
5
|
-
|
6
5
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
7
|
-
|
8
|
-
|
6
|
+
DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
7
|
+
DATE_FORMAT_DIRECTIVES = {
|
9
8
|
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
10
9
|
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
11
10
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
12
11
|
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
13
12
|
}
|
14
|
-
|
13
|
+
NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
|
15
14
|
|
16
15
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
17
16
|
collector << "LOG("
|
18
17
|
o.expressions.each_with_index { |arg, i|
|
19
|
-
collector << Arel::Visitors::ToSql::COMMA
|
18
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
20
19
|
collector = visit arg, collector
|
21
20
|
}
|
22
21
|
collector << ",10)"
|
@@ -26,7 +25,7 @@ module ArelExtensions
|
|
26
25
|
def visit_ArelExtensions_Nodes_Power o, collector
|
27
26
|
collector << "POWER("
|
28
27
|
o.expressions.each_with_index { |arg, i|
|
29
|
-
collector << Arel::Visitors::ToSql::COMMA
|
28
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
30
29
|
collector = visit arg, collector
|
31
30
|
}
|
32
31
|
collector << ")"
|
@@ -93,7 +92,6 @@ module ArelExtensions
|
|
93
92
|
end
|
94
93
|
end
|
95
94
|
|
96
|
-
|
97
95
|
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
98
96
|
collector << 'LOWER('
|
99
97
|
collector = visit o.left, collector
|
@@ -112,25 +110,25 @@ module ArelExtensions
|
|
112
110
|
if o.ai
|
113
111
|
collector << "NLSSORT("
|
114
112
|
collector = visit o.expressions.first, collector
|
115
|
-
collector <<
|
113
|
+
collector << COMMA
|
116
114
|
collector << "'NLS_SORT = BINARY_AI NLS_COMP = LINGUISTIC'"
|
117
115
|
collector << ")"
|
118
116
|
elsif o.ci
|
119
117
|
collector << "NLSSORT("
|
120
118
|
collector = visit o.expressions.first, collector
|
121
|
-
collector <<
|
119
|
+
collector << COMMA
|
122
120
|
collector << "'NLS_SORT = BINARY_CI NLS_COMP = LINGUISTIC'"
|
123
121
|
collector << ")"
|
124
122
|
else
|
125
123
|
collector = visit o.expressions.first, collector
|
126
124
|
end
|
127
|
-
|
125
|
+
collector
|
128
126
|
end
|
129
127
|
|
130
128
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
131
129
|
collector << "(LISTAGG("
|
132
130
|
collector = visit o.left, collector
|
133
|
-
collector <<
|
131
|
+
collector << COMMA
|
134
132
|
collector =
|
135
133
|
if o.separator && o.separator != 'NULL'
|
136
134
|
visit o.separator, collector
|
@@ -140,7 +138,7 @@ module ArelExtensions
|
|
140
138
|
collector << ") WITHIN GROUP (ORDER BY "
|
141
139
|
if !o.order.blank?
|
142
140
|
o.order.each_with_index do |order,i|
|
143
|
-
collector <<
|
141
|
+
collector << COMMA if i != 0
|
144
142
|
collector = visit order, collector
|
145
143
|
end
|
146
144
|
else
|
@@ -153,7 +151,7 @@ module ArelExtensions
|
|
153
151
|
def visit_ArelExtensions_Nodes_Coalesce o, collector
|
154
152
|
collector << "COALESCE("
|
155
153
|
o.expressions.each_with_index { |arg, i|
|
156
|
-
collector <<
|
154
|
+
collector << COMMA if i != 0
|
157
155
|
if i > 0 && o.left_node_type == :text
|
158
156
|
if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
|
159
157
|
collector << "NULL"
|
@@ -196,7 +194,7 @@ module ArelExtensions
|
|
196
194
|
collector << 'TO_DATE(' if lc
|
197
195
|
collector = visit o.left, collector
|
198
196
|
collector << ')' if lc
|
199
|
-
collector <<
|
197
|
+
collector << COMMA
|
200
198
|
collector << "'DDD') = "
|
201
199
|
collector << 'TO_DATE(' if lc
|
202
200
|
collector = visit o.left, collector
|
@@ -222,8 +220,8 @@ module ArelExtensions
|
|
222
220
|
when 'wd', 'w'
|
223
221
|
collector << "TO_CHAR("
|
224
222
|
collector = visit o.right, collector
|
225
|
-
collector <<
|
226
|
-
collector = visit Arel::Nodes.build_quoted(
|
223
|
+
collector << COMMA
|
224
|
+
collector = visit Arel::Nodes.build_quoted(DATE_MAPPING[o.left]), collector
|
227
225
|
else
|
228
226
|
right = case o.left
|
229
227
|
when 'd','m','y'
|
@@ -233,7 +231,7 @@ module ArelExtensions
|
|
233
231
|
interval = 'SECOND'
|
234
232
|
o.right.cast(:datetime)
|
235
233
|
when /i\z/
|
236
|
-
interval =
|
234
|
+
interval = DATE_MAPPING[o.left[0..-2]]
|
237
235
|
collector << '('
|
238
236
|
collector = visit o.right, collector
|
239
237
|
collector << ") * (INTERVAL '1' #{interval})"
|
@@ -242,7 +240,7 @@ module ArelExtensions
|
|
242
240
|
interval = nil
|
243
241
|
o.right
|
244
242
|
end
|
245
|
-
collector << "EXTRACT(#{
|
243
|
+
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
|
246
244
|
collector = visit right, collector
|
247
245
|
end
|
248
246
|
collector << ")"
|
@@ -332,7 +330,7 @@ module ArelExtensions
|
|
332
330
|
collector << "DBMS_RANDOM.VALUE("
|
333
331
|
if o.left && o.right
|
334
332
|
collector = visit o.left, collector
|
335
|
-
collector <<
|
333
|
+
collector << COMMA
|
336
334
|
collector = visit o.right, collector
|
337
335
|
end
|
338
336
|
collector << ")"
|
@@ -342,7 +340,7 @@ module ArelExtensions
|
|
342
340
|
def visit_Arel_Nodes_Regexp o, collector
|
343
341
|
collector << " REGEXP_LIKE("
|
344
342
|
collector = visit o.left, collector
|
345
|
-
collector <<
|
343
|
+
collector << COMMA
|
346
344
|
collector = visit o.right, collector
|
347
345
|
collector << ')'
|
348
346
|
collector
|
@@ -351,7 +349,7 @@ module ArelExtensions
|
|
351
349
|
def visit_Arel_Nodes_NotRegexp o, collector
|
352
350
|
collector << " NOT REGEXP_LIKE("
|
353
351
|
collector = visit o.left, collector
|
354
|
-
collector <<
|
352
|
+
collector << COMMA
|
355
353
|
collector = visit o.right, collector
|
356
354
|
collector << ')'
|
357
355
|
collector
|
@@ -360,7 +358,7 @@ module ArelExtensions
|
|
360
358
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
361
359
|
collector << "INSTR("
|
362
360
|
o.expressions.each_with_index { |arg, i|
|
363
|
-
collector <<
|
361
|
+
collector << COMMA if i != 0
|
364
362
|
collector = visit arg, collector
|
365
363
|
}
|
366
364
|
collector << ")"
|
@@ -370,7 +368,7 @@ module ArelExtensions
|
|
370
368
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
371
369
|
collector << "SUBSTR("
|
372
370
|
o.expressions.each_with_index { |arg, i|
|
373
|
-
collector <<
|
371
|
+
collector << COMMA if i != 0
|
374
372
|
collector = visit arg, collector
|
375
373
|
}
|
376
374
|
collector << ")"
|
@@ -389,11 +387,11 @@ module ArelExtensions
|
|
389
387
|
if o.type_of_attribute(o.left) == :text
|
390
388
|
collector << 'dbms_lob.SUBSTR('
|
391
389
|
collector = visit o.left, collector
|
392
|
-
collector <<
|
390
|
+
collector << COMMA
|
393
391
|
collector << 'COALESCE(dbms_lob.GETLENGTH('
|
394
392
|
collector = visit o.left, collector
|
395
393
|
collector << "), 0)"
|
396
|
-
collector <<
|
394
|
+
collector << COMMA
|
397
395
|
collector << '1)'
|
398
396
|
else
|
399
397
|
collector = visit o.left, collector
|
@@ -440,28 +438,25 @@ module ArelExtensions
|
|
440
438
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
441
439
|
collector << '('
|
442
440
|
collector = visit o.left, collector
|
443
|
-
collector << ' + '# (o.right.value >= 0 ? ' + ' : ' - ')
|
441
|
+
collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
|
444
442
|
collector = visit o.oracle_value(o.right), collector
|
445
443
|
collector << ')'
|
446
444
|
collector
|
447
445
|
end
|
448
446
|
|
449
447
|
def visit_ArelExtensions_Nodes_Format o, collector
|
448
|
+
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
450
449
|
collector << "TO_CHAR("
|
451
450
|
collector = visit o.left, collector
|
452
|
-
collector <<
|
453
|
-
|
454
|
-
f = o.iso_format.gsub(/\ (\w+)/, ' "\1"')
|
455
|
-
Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
456
|
-
collector = visit Arel::Nodes.build_quoted(f), collector
|
457
|
-
|
451
|
+
collector << COMMA
|
452
|
+
collector = visit Arel::Nodes.build_quoted(fmt), collector
|
458
453
|
collector << ")"
|
459
454
|
collector
|
460
455
|
end
|
461
456
|
|
462
457
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
463
458
|
collector << "LPAD("
|
464
|
-
collector = visit o.expressions[0], collector #can't put empty string, otherwise it wouldn't work
|
459
|
+
collector = visit o.expressions[0], collector # can't put empty string, otherwise it wouldn't work
|
465
460
|
collector << Arel::Visitors::ToSql::COMMA
|
466
461
|
collector = visit o.expressions[1], collector
|
467
462
|
collector << Arel::Visitors::ToSql::COMMA
|
@@ -470,24 +465,24 @@ module ArelExtensions
|
|
470
465
|
collector
|
471
466
|
end
|
472
467
|
|
473
|
-
|
468
|
+
# add primary_key if not present, avoid zip
|
474
469
|
if Arel::VERSION.to_i < 7
|
475
470
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
476
471
|
collector << "("
|
477
472
|
o.left.each_with_index do |row, idx| # values
|
478
473
|
collector << " UNION ALL " if idx != 0
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
474
|
+
collector << "(SELECT "
|
475
|
+
len = row.length - 1
|
476
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
477
|
+
case value
|
478
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
479
|
+
collector = visit value, collector
|
480
|
+
else
|
481
|
+
collector << quote(value, attr && column_for(attr)).to_s
|
482
|
+
end
|
483
|
+
collector << COMMA unless i == len
|
484
|
+
}
|
485
|
+
collector << ' FROM DUAL)'
|
491
486
|
end
|
492
487
|
collector << ")"
|
493
488
|
collector
|
@@ -508,7 +503,7 @@ module ArelExtensions
|
|
508
503
|
else
|
509
504
|
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
510
505
|
end
|
511
|
-
collector <<
|
506
|
+
collector << COMMA unless i == len
|
512
507
|
}
|
513
508
|
collector << ' FROM DUAL)'
|
514
509
|
end
|
@@ -567,7 +562,7 @@ module ArelExtensions
|
|
567
562
|
end
|
568
563
|
|
569
564
|
|
570
|
-
alias_method
|
565
|
+
alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
|
571
566
|
def visit_Arel_Nodes_SelectStatement o, collector
|
572
567
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
573
568
|
o = o.dup
|
@@ -576,7 +571,7 @@ module ArelExtensions
|
|
576
571
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
577
572
|
end
|
578
573
|
|
579
|
-
alias_method
|
574
|
+
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
580
575
|
def visit_Arel_Nodes_TableAlias o, collector
|
581
576
|
if o.name.length > 30
|
582
577
|
o = Arel::Table.new(o.table_name).alias(Base64.urlsafe_encode64(Digest::MD5.new.digest(o.name)).tr('=', '').tr('-', '_'))
|
@@ -584,7 +579,7 @@ module ArelExtensions
|
|
584
579
|
old_visit_Arel_Nodes_TableAlias(o,collector)
|
585
580
|
end
|
586
581
|
|
587
|
-
alias_method
|
582
|
+
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
588
583
|
def visit_Arel_Nodes_As o, collector
|
589
584
|
if o.left.is_a?(Arel::Nodes::Binary)
|
590
585
|
collector << '('
|
@@ -604,7 +599,7 @@ module ArelExtensions
|
|
604
599
|
visit_Arel_Nodes_As o, collector
|
605
600
|
end
|
606
601
|
|
607
|
-
alias_method
|
602
|
+
alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
|
608
603
|
def visit_Arel_Attributes_Attribute o, collector
|
609
604
|
join_name = o.relation.table_alias || o.relation.name
|
610
605
|
if join_name.length > 30
|
@@ -613,10 +608,9 @@ module ArelExtensions
|
|
613
608
|
collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
|
614
609
|
end
|
615
610
|
|
616
|
-
|
617
611
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
618
612
|
col = o.left.coalesce(0)
|
619
|
-
comma =
|
613
|
+
comma = NUMBER_COMMA_MAPPING[o.locale] || '.,'
|
620
614
|
comma_in_format = o.precision == 0 ? '' : 'D'
|
621
615
|
nines_after = (1..o.precision-1).map{'9'}.join('')+'0'
|
622
616
|
if comma.length == 1
|
@@ -693,7 +687,6 @@ module ArelExtensions
|
|
693
687
|
collector << ')'
|
694
688
|
collector
|
695
689
|
end
|
696
|
-
|
697
690
|
end
|
698
691
|
end
|
699
692
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
3
|
Arel::Visitors.send(:remove_const,'Oracle12') if Arel::Visitors.const_defined?('Oracle12')
|
5
4
|
Arel::Visitors.const_set('Oracle12',Class.new(Arel::Visitors::Oracle)).class_eval do
|
6
5
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
@@ -12,6 +11,7 @@ module ArelExtensions
|
|
12
11
|
`SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
|
13
12
|
MSG
|
14
13
|
end
|
14
|
+
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
@@ -84,7 +84,7 @@ module ArelExtensions
|
|
84
84
|
collector << 'FORMAT JSON'
|
85
85
|
end
|
86
86
|
collector << ')'
|
87
|
-
when String,Numeric,TrueClass,FalseClass
|
87
|
+
when String, Numeric, TrueClass, FalseClass
|
88
88
|
collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
|
89
89
|
collector << ' FORMAT JSON'
|
90
90
|
when NilClass
|
@@ -97,7 +97,6 @@ module ArelExtensions
|
|
97
97
|
end
|
98
98
|
collector
|
99
99
|
end
|
100
|
-
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -1,20 +1,29 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::PostgreSQL
|
4
|
-
|
5
|
-
|
6
|
-
'
|
4
|
+
DATE_MAPPING = {
|
5
|
+
'd' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW',
|
6
|
+
'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
DATE_FORMAT_DIRECTIVES = {
|
10
|
+
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY',
|
11
|
+
'%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
7
12
|
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
8
13
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
9
|
-
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
10
|
-
|
11
|
-
|
14
|
+
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
|
15
|
+
'%%' => '%',
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
NUMBER_COMMA_MAPPING = {
|
19
|
+
'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '
|
20
|
+
}.freeze
|
12
21
|
|
13
22
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
14
23
|
collector << "RANDOM("
|
15
|
-
if(o.left != nil && o.right != nil)
|
24
|
+
if (o.left != nil && o.right != nil)
|
16
25
|
collector = visit o.left, collector
|
17
|
-
collector <<
|
26
|
+
collector << COMMA
|
18
27
|
collector = isit o.right, collector
|
19
28
|
end
|
20
29
|
collector << ")"
|
@@ -24,7 +33,7 @@ module ArelExtensions
|
|
24
33
|
def visit_ArelExtensions_Nodes_Power o, collector
|
25
34
|
collector << "POWER("
|
26
35
|
o.expressions.each_with_index { |arg, i|
|
27
|
-
collector << Arel::Visitors::ToSql::COMMA
|
36
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
28
37
|
collector = visit arg, collector
|
29
38
|
}
|
30
39
|
collector << ")"
|
@@ -34,7 +43,7 @@ module ArelExtensions
|
|
34
43
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
35
44
|
collector << "LOG("
|
36
45
|
o.expressions.each_with_index { |arg, i|
|
37
|
-
collector << Arel::Visitors::ToSql::COMMA
|
46
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
38
47
|
collector = visit arg, collector
|
39
48
|
}
|
40
49
|
collector << ")"
|
@@ -68,7 +77,7 @@ module ArelExtensions
|
|
68
77
|
collector
|
69
78
|
end
|
70
79
|
|
71
|
-
alias_method
|
80
|
+
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
72
81
|
def visit_Arel_Nodes_As o, collector
|
73
82
|
if o.left.is_a?(Arel::Nodes::Binary)
|
74
83
|
collector << '('
|
@@ -89,14 +98,14 @@ module ArelExtensions
|
|
89
98
|
if !o.group.blank?
|
90
99
|
collector << " PARTITION BY "
|
91
100
|
o.group.each_with_index do |group, i|
|
92
|
-
collector <<
|
101
|
+
collector << COMMA if i != 0
|
93
102
|
visit group, collector
|
94
103
|
end
|
95
104
|
end
|
96
105
|
if !o.order.blank?
|
97
106
|
collector << " ORDER BY "
|
98
107
|
o.order.each_with_index do |order, i|
|
99
|
-
collector <<
|
108
|
+
collector << COMMA if i != 0
|
100
109
|
visit order, collector
|
101
110
|
end
|
102
111
|
end
|
@@ -111,7 +120,7 @@ module ArelExtensions
|
|
111
120
|
if o.order && !o.order.blank?
|
112
121
|
collector << " ORDER BY"
|
113
122
|
o.order.each_with_index do |order, i|
|
114
|
-
collector <<
|
123
|
+
collector << COMMA if i != 0
|
115
124
|
collector << " "
|
116
125
|
visit order, collector
|
117
126
|
end
|
@@ -119,7 +128,7 @@ module ArelExtensions
|
|
119
128
|
collector << ")"
|
120
129
|
o.order = nil
|
121
130
|
visit_Aggregate_For_AggregateFunction o, collector
|
122
|
-
collector <<
|
131
|
+
collector << COMMA
|
123
132
|
collector =
|
124
133
|
if o.separator && o.separator != 'NULL'
|
125
134
|
visit o.separator, collector
|
@@ -158,14 +167,11 @@ module ArelExtensions
|
|
158
167
|
end
|
159
168
|
|
160
169
|
def visit_ArelExtensions_Nodes_Format o, collector
|
170
|
+
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
161
171
|
collector << "TO_CHAR("
|
162
172
|
collector = visit o.left, collector
|
163
|
-
collector <<
|
164
|
-
|
165
|
-
f = o.iso_format.dup
|
166
|
-
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
167
|
-
collector = visit Arel::Nodes.build_quoted(f), collector
|
168
|
-
|
173
|
+
collector << COMMA
|
174
|
+
collector = visit Arel::Nodes.build_quoted(fmt), collector
|
169
175
|
collector << ")"
|
170
176
|
collector
|
171
177
|
end
|
@@ -173,7 +179,7 @@ module ArelExtensions
|
|
173
179
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
174
180
|
collector << "REPEAT("
|
175
181
|
o.expressions.each_with_index { |arg, i|
|
176
|
-
collector << Arel::Visitors::ToSql::COMMA
|
182
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
177
183
|
collector = visit arg, collector
|
178
184
|
}
|
179
185
|
collector << ")"
|
@@ -231,7 +237,7 @@ module ArelExtensions
|
|
231
237
|
|
232
238
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
233
239
|
collector = visit o.left, collector
|
234
|
-
collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
|
240
|
+
collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
|
235
241
|
collector = visit o.postgresql_value(o.right), collector
|
236
242
|
collector
|
237
243
|
end
|
@@ -245,7 +251,7 @@ module ArelExtensions
|
|
245
251
|
end
|
246
252
|
collector = visit o.right, collector
|
247
253
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
248
|
-
collector <<
|
254
|
+
collector << COMMA
|
249
255
|
collector = visit o.left, collector
|
250
256
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
251
257
|
collector << ")"
|
@@ -273,11 +279,11 @@ module ArelExtensions
|
|
273
279
|
collector << "("
|
274
280
|
collector = visit o.right, collector
|
275
281
|
collector << ")"
|
276
|
-
collector << " * (INTERVAL '1' #{
|
282
|
+
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
277
283
|
return collector
|
278
284
|
end
|
279
285
|
end
|
280
|
-
collector << "EXTRACT(#{
|
286
|
+
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
|
281
287
|
collector = visit o.right, collector
|
282
288
|
collector << ")"
|
283
289
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
@@ -296,7 +302,7 @@ module ArelExtensions
|
|
296
302
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
297
303
|
collector << "SUBSTR("
|
298
304
|
o.expressions.each_with_index { |arg, i|
|
299
|
-
collector <<
|
305
|
+
collector << COMMA if i != 0
|
300
306
|
collector = visit arg, collector
|
301
307
|
}
|
302
308
|
collector << ")"
|
@@ -308,7 +314,7 @@ module ArelExtensions
|
|
308
314
|
visit o.left, collector
|
309
315
|
collector << Arel::Visitors::ToSql::COMMA
|
310
316
|
tab = o.pattern.inspect+ 'g' # Make it always global
|
311
|
-
pattern = tab.split('/')[1..-2].join('/')
|
317
|
+
pattern = tab.split('/')[1..-2].join('/')
|
312
318
|
flags = tab.split('/')[-1]
|
313
319
|
visit Arel::Nodes.build_quoted(pattern), collector
|
314
320
|
collector << Arel::Visitors::ToSql::COMMA
|
@@ -380,8 +386,8 @@ module ArelExtensions
|
|
380
386
|
|
381
387
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
382
388
|
col = o.left.coalesce(0)
|
383
|
-
comma = o.precision == 0 ? '' : (
|
384
|
-
thousand_separator =
|
389
|
+
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
390
|
+
thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
|
385
391
|
nines_after = (1..o.precision).map{'9'}.join('')
|
386
392
|
nines_before = ("999#{thousand_separator}"*4+"990")
|
387
393
|
|
@@ -435,7 +441,7 @@ module ArelExtensions
|
|
435
441
|
end
|
436
442
|
|
437
443
|
|
438
|
-
alias_method
|
444
|
+
alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
|
439
445
|
def visit_Arel_Nodes_SelectStatement o, collector
|
440
446
|
|
441
447
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
@@ -445,7 +451,7 @@ module ArelExtensions
|
|
445
451
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
446
452
|
end
|
447
453
|
|
448
|
-
alias_method
|
454
|
+
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
449
455
|
def visit_Arel_Nodes_TableAlias o, collector
|
450
456
|
if o.name.length > 63
|
451
457
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
@@ -453,7 +459,7 @@ module ArelExtensions
|
|
453
459
|
old_visit_Arel_Nodes_TableAlias(o,collector)
|
454
460
|
end
|
455
461
|
|
456
|
-
alias_method
|
462
|
+
alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
|
457
463
|
def visit_Arel_Attributes_Attribute o, collector
|
458
464
|
join_name = o.relation.table_alias || o.relation.name
|
459
465
|
if join_name.length > 63
|
@@ -571,7 +577,6 @@ module ArelExtensions
|
|
571
577
|
end
|
572
578
|
collector
|
573
579
|
end
|
574
|
-
|
575
580
|
end
|
576
581
|
end
|
577
582
|
end
|