arel_extensions 2.0.0 → 2.0.10

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -4
  3. data/.travis.yml +59 -91
  4. data/Gemfile +14 -19
  5. data/README.md +17 -12
  6. data/Rakefile +38 -27
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +2 -2
  9. data/functions.html +3 -3
  10. data/gemfiles/rails4.gemfile +1 -1
  11. data/gemfiles/rails6.gemfile +30 -0
  12. data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
  13. data/generate_gems.sh +14 -0
  14. data/init/mssql.sql +4 -4
  15. data/init/mysql.sql +38 -38
  16. data/init/postgresql.sql +21 -21
  17. data/lib/arel_extensions.rb +63 -19
  18. data/lib/arel_extensions/attributes.rb +0 -1
  19. data/lib/arel_extensions/boolean_functions.rb +38 -13
  20. data/lib/arel_extensions/common_sql_functions.rb +5 -4
  21. data/lib/arel_extensions/comparators.rb +4 -2
  22. data/lib/arel_extensions/insert_manager.rb +15 -13
  23. data/lib/arel_extensions/math.rb +3 -3
  24. data/lib/arel_extensions/math_functions.rb +10 -5
  25. data/lib/arel_extensions/nodes.rb +1 -1
  26. data/lib/arel_extensions/nodes/abs.rb +0 -0
  27. data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
  28. data/lib/arel_extensions/nodes/case.rb +8 -4
  29. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  30. data/lib/arel_extensions/nodes/coalesce.rb +2 -2
  31. data/lib/arel_extensions/nodes/collate.rb +1 -1
  32. data/lib/arel_extensions/nodes/concat.rb +6 -13
  33. data/lib/arel_extensions/nodes/date_diff.rb +3 -5
  34. data/lib/arel_extensions/nodes/duration.rb +0 -2
  35. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  36. data/lib/arel_extensions/nodes/floor.rb +0 -0
  37. data/lib/arel_extensions/nodes/format.rb +8 -8
  38. data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
  39. data/lib/arel_extensions/nodes/function.rb +2 -0
  40. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  41. data/lib/arel_extensions/nodes/json.rb +28 -30
  42. data/lib/arel_extensions/nodes/length.rb +0 -0
  43. data/lib/arel_extensions/nodes/locate.rb +0 -0
  44. data/lib/arel_extensions/nodes/matches.rb +4 -4
  45. data/lib/arel_extensions/nodes/power.rb +6 -5
  46. data/lib/arel_extensions/nodes/rand.rb +0 -0
  47. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  48. data/lib/arel_extensions/nodes/replace.rb +24 -6
  49. data/lib/arel_extensions/nodes/round.rb +5 -5
  50. data/lib/arel_extensions/nodes/soundex.rb +16 -15
  51. data/lib/arel_extensions/nodes/std.rb +19 -21
  52. data/lib/arel_extensions/nodes/substring.rb +8 -15
  53. data/lib/arel_extensions/nodes/sum.rb +7 -0
  54. data/lib/arel_extensions/nodes/trim.rb +3 -3
  55. data/lib/arel_extensions/nodes/union.rb +2 -3
  56. data/lib/arel_extensions/nodes/union_all.rb +0 -1
  57. data/lib/arel_extensions/nodes/wday.rb +0 -0
  58. data/lib/arel_extensions/null_functions.rb +2 -2
  59. data/lib/arel_extensions/predications.rb +35 -33
  60. data/lib/arel_extensions/set_functions.rb +2 -2
  61. data/lib/arel_extensions/string_functions.rb +34 -12
  62. data/lib/arel_extensions/tasks.rb +5 -5
  63. data/lib/arel_extensions/version.rb +1 -1
  64. data/lib/arel_extensions/visitors.rb +1 -1
  65. data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
  66. data/lib/arel_extensions/visitors/mssql.rb +14 -13
  67. data/lib/arel_extensions/visitors/mysql.rb +90 -37
  68. data/lib/arel_extensions/visitors/oracle.rb +15 -15
  69. data/lib/arel_extensions/visitors/oracle12.rb +1 -1
  70. data/lib/arel_extensions/visitors/postgresql.rb +78 -32
  71. data/lib/arel_extensions/visitors/sqlite.rb +61 -53
  72. data/lib/arel_extensions/visitors/to_sql.rb +70 -58
  73. data/test/arelx_test_helper.rb +28 -0
  74. data/test/real_db_test.rb +1 -1
  75. data/test/support/fake_record.rb +1 -1
  76. data/test/test_comparators.rb +9 -8
  77. data/test/visitors/test_bulk_insert_oracle.rb +8 -7
  78. data/test/visitors/test_bulk_insert_sqlite.rb +9 -8
  79. data/test/visitors/test_bulk_insert_to_sql.rb +8 -10
  80. data/test/visitors/test_oracle.rb +41 -40
  81. data/test/visitors/test_to_sql.rb +367 -193
  82. data/test/with_ar/all_agnostic_test.rb +68 -35
  83. data/test/with_ar/insert_agnostic_test.rb +3 -2
  84. data/test/with_ar/test_bulk_sqlite.rb +6 -5
  85. data/test/with_ar/test_math_sqlite.rb +4 -4
  86. data/test/with_ar/test_string_mysql.rb +4 -6
  87. data/test/with_ar/test_string_sqlite.rb +3 -7
  88. data/version_v1.rb +3 -0
  89. data/version_v2.rb +3 -0
  90. metadata +14 -7
  91. data/test/helper.rb +0 -18
@@ -23,10 +23,10 @@ module ArelExtensions
23
23
  end
24
24
  end
25
25
 
26
- Arel::Nodes::Union.class_eval do
26
+ class Arel::Nodes::Union
27
27
  include ArelExtensions::SetFunctions
28
28
  end
29
29
 
30
- Arel::Nodes::UnionAll.class_eval do
30
+ class Arel::Nodes::UnionAll
31
31
  include ArelExtensions::SetFunctions
32
32
  end
@@ -64,6 +64,19 @@ module ArelExtensions
64
64
  grouping_any :imatches, others, escape
65
65
  end
66
66
 
67
+ # def grouping_any method, others, *extra
68
+ # puts "*******************"
69
+ # puts method
70
+ # puts others.inspect
71
+ # puts extra.inspect
72
+ # puts "-------------------"
73
+ # res = super(method,others,*extra)
74
+ # puts res.to_sql
75
+ # puts res.inspect
76
+ # puts "*******************"
77
+ # res
78
+ # end
79
+
67
80
  def imatches_all others, escape = nil
68
81
  grouping_all :imatches, others, escape, escape
69
82
  end
@@ -92,7 +105,7 @@ module ArelExtensions
92
105
  ArelExtensions::Nodes::SMatches.new(self,other)
93
106
  end
94
107
 
95
- def ai_collate
108
+ def ai_collate
96
109
  ArelExtensions::Nodes::Collate.new(self,nil,true,false)
97
110
  end
98
111
 
@@ -100,31 +113,40 @@ module ArelExtensions
100
113
  ArelExtensions::Nodes::Collate.new(self,nil,false,true)
101
114
  end
102
115
 
103
- def collate ai=false,ci=false, option=nil
116
+ def collate ai = false,ci = false, option = nil
104
117
  ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
105
118
  end
106
119
 
107
120
  #REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
108
- def replace left, right
109
- ArelExtensions::Nodes::Replace.new [self, left, right]
121
+ def replace pattern, substitute
122
+ if pattern.is_a? Regexp
123
+ ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
124
+ else
125
+ ArelExtensions::Nodes::Replace.new self, pattern, substitute
126
+ end
127
+ end
128
+
129
+ def regexp_replace pattern, substitute
130
+ ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
110
131
  end
111
-
132
+
112
133
  def concat other
113
134
  ArelExtensions::Nodes::Concat.new [self, other]
114
135
  end
115
136
 
116
137
  #concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
117
- def group_concat sep = nil, *orders
138
+ def group_concat(sep = nil, *orders, group: nil, order: nil)
139
+ if orders.present?
140
+ warn("Warning : ArelExtensions: group_concat: you should now use the kwarg 'order' to specify an order in the group_concat.")
141
+ end
118
142
  order_tabs = [orders].flatten.map{ |o|
119
143
  if o.is_a?(Arel::Nodes::Ascending) || o.is_a?(Arel::Nodes::Descending)
120
144
  o
121
145
  elsif o.respond_to?(:asc)
122
146
  o.asc
123
- else
124
- nil
125
147
  end
126
148
  }.compact
127
- ArelExtensions::Nodes::GroupConcat.new [self, sep, order_tabs]
149
+ ArelExtensions::Nodes::GroupConcat.new(self, sep, group: group, order: (order || order_tabs))
128
150
  end
129
151
 
130
152
  #Function returns a string after removing left, right or the both prefixes or suffixes int argument
@@ -155,11 +177,11 @@ module ArelExtensions
155
177
  def not_blank
156
178
  ArelExtensions::Nodes::NotBlank.new [self]
157
179
  end
158
-
159
- def repeat other = 1
180
+
181
+ def repeat other = 1
160
182
  ArelExtensions::Nodes::Repeat.new [self, other]
161
183
  end
162
-
184
+
163
185
  def levenshtein_distance other
164
186
  ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
165
187
  end
@@ -1,12 +1,12 @@
1
1
  namespace :arel_extensions do
2
- desc 'Install DB functions into current DB'
3
- task :install_functions => :environment do
4
- @env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
2
+ desc 'Install DB functions into current DB'
3
+ task :install_functions => :environment do
4
+ @env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
5
5
  (RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
6
6
  else
7
7
  ENV['DB'] || ActiveRecord::Base.connection.adapter_name
8
8
  end
9
- ActiveRecord::Base.establish_connection(Rails.env)
9
+ ActiveRecord::Base.establish_connection(Rails.env.to_sym)
10
10
  CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions(@env_db)
11
- end
11
+ end
12
12
  end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "2.0.0".freeze
2
+ VERSION = "2.0.10".freeze
3
3
  end
@@ -6,7 +6,7 @@ require 'arel_extensions/visitors/postgresql'
6
6
  require 'arel_extensions/visitors/sqlite'
7
7
  require 'arel_extensions/visitors/mssql'
8
8
 
9
- Arel::Visitors::MSSQL.class_eval do
9
+ class Arel::Visitors::MSSQL
10
10
  include ArelExtensions::Visitors::MSSQL
11
11
 
12
12
  alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
@@ -1,6 +1,6 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- Arel::Visitors::IBM_DB.class_eval do
3
+ class Arel::Visitors::IBM_DB
4
4
 
5
5
  def visit_ArelExtensions_Nodes_Ceil o, collector
6
6
  collector << "CEILING("
@@ -400,14 +400,15 @@ module ArelExtensions
400
400
  collector << "(STRING_AGG("
401
401
  collector = visit o.left, collector
402
402
  collector << Arel::Visitors::Oracle::COMMA
403
- if o.right && o.right != 'NULL'
404
- collector = visit o.right, collector
405
- else
406
- collector = visit Arel::Nodes.build_quoted(','), collector
407
- end
403
+ collector =
404
+ if o.separator && o.separator != 'NULL'
405
+ visit o.separator, collector
406
+ else
407
+ visit Arel::Nodes.build_quoted(','), collector
408
+ end
408
409
  collector << ") WITHIN GROUP (ORDER BY "
409
- if !o.orders.blank?
410
- o.orders.each_with_index do |order,i|
410
+ if o.order.present?
411
+ o.order.each_with_index do |order,i|
411
412
  collector << Arel::Visitors::Oracle::COMMA unless i == 0
412
413
  collector = visit order, collector
413
414
  end
@@ -466,8 +467,9 @@ module ArelExtensions
466
467
  Arel::Nodes.build_quoted(1) :
467
468
  ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
468
469
 
469
- if o.scientific_notation
470
- number = ArelExtensions::Nodes::Concat.new([
470
+ number =
471
+ if o.scientific_notation
472
+ ArelExtensions::Nodes::Concat.new([
471
473
  Arel::Nodes::NamedFunction.new('FORMAT',[
472
474
  col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
473
475
  param,
@@ -480,13 +482,13 @@ module ArelExtensions
480
482
  locale
481
483
  ])
482
484
  ])
483
- else
484
- number = Arel::Nodes::NamedFunction.new('FORMAT',[
485
+ else
486
+ Arel::Nodes::NamedFunction.new('FORMAT',[
485
487
  Arel::Nodes.build_quoted(col.abs),
486
488
  param,
487
489
  locale
488
490
  ])
489
- end
491
+ end
490
492
 
491
493
  repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
492
494
  when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
@@ -548,7 +550,6 @@ module ArelExtensions
548
550
  collector
549
551
  end
550
552
 
551
-
552
553
  end
553
554
  end
554
555
  end
@@ -1,7 +1,6 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- Arel::Visitors::MySQL.class_eval do
4
- Arel::Visitors::MySQL::COMMA = ", "
3
+ class Arel::Visitors::MySQL
5
4
  Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
6
5
  Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
7
6
  '%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
@@ -98,26 +97,28 @@ module ArelExtensions
98
97
  end
99
98
 
100
99
  def visit_ArelExtensions_Nodes_Collate o, collector
101
- case o.expressions.first
102
- when Arel::Attributes::Attribute
103
- charset = case o.option
100
+ charset =
101
+ case o.expressions.first
102
+ when Arel::Attributes::Attribute
103
+ case o.option
104
104
  when 'latin1','utf8'
105
105
  o.option
106
106
  else
107
107
  Arel::Table.engine.connection.charset || 'utf8'
108
108
  end
109
- else
110
- charset = (o.option == 'latin1') ? 'latin1' : 'utf8'
111
- end
109
+ else
110
+ (o.option == 'latin1') ? 'latin1' : 'utf8'
111
+ end
112
112
  collector = visit o.expressions.first, collector
113
- if o.ai
114
- collector << " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
113
+ collector <<
114
+ if o.ai
115
+ " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
115
116
  #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
117
+ elsif o.ci
118
+ " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
119
+ else
120
+ " COLLATE #{charset}_bin"
121
+ end
121
122
  collector
122
123
  end
123
124
 
@@ -140,16 +141,16 @@ module ArelExtensions
140
141
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
141
142
  collector << "GROUP_CONCAT("
142
143
  collector = visit o.left, collector
143
- if !o.orders.blank?
144
+ if !o.order.blank?
144
145
  collector << ' ORDER BY '
145
- o.orders.each_with_index do |order,i|
146
+ o.order.each_with_index do |order,i|
146
147
  collector << Arel::Visitors::ToSql::COMMA unless i == 0
147
148
  collector = visit order, collector
148
149
  end
149
150
  end
150
- if o.right && o.right != 'NULL'
151
+ if o.separator && o.separator != 'NULL'
151
152
  collector << ' SEPARATOR '
152
- collector = visit o.right, collector
153
+ collector = visit o.separator, collector
153
154
  end
154
155
  collector << ")"
155
156
  collector
@@ -192,6 +193,13 @@ module ArelExtensions
192
193
  collector
193
194
  end
194
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
+
195
203
  def visit_ArelExtensions_Nodes_Format o, collector
196
204
  case o.col_type
197
205
  when :date, :datetime
@@ -263,7 +271,7 @@ module ArelExtensions
263
271
  else
264
272
  if o.with_interval
265
273
  case o.left
266
- when 'd','m','y'
274
+ when 'd','m','y'
267
275
  interval = 'DAY'
268
276
  when 'h','mn','s'
269
277
  interval = 'SECOND'
@@ -363,20 +371,21 @@ module ArelExtensions
363
371
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
364
372
  sign_length = ArelExtensions::Nodes::Length.new([sign])
365
373
 
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
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
+ ])
375
385
  ])
376
- ])
377
- else
378
- number = Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
379
- end
386
+ else
387
+ Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
388
+ end
380
389
 
381
390
  repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
382
391
  when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
@@ -399,10 +408,34 @@ module ArelExtensions
399
408
  collector
400
409
  end
401
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
+
402
434
  def visit_ArelExtensions_Nodes_Std o, collector
403
435
  collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
404
436
  visit o.left, collector
405
437
  collector << ")"
438
+ visit_Aggregate_For_AggregateFunction o, collector
406
439
  collector
407
440
  end
408
441
 
@@ -410,15 +443,35 @@ module ArelExtensions
410
443
  collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
411
444
  visit o.left, collector
412
445
  collector << ")"
446
+ visit_Aggregate_For_AggregateFunction o, collector
413
447
  collector
414
448
  end
415
449
 
416
450
  # JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
417
451
  def json_supported?
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'
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)
422
475
  end
423
476
 
424
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.class_eval do
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
- if o.right && o.right != 'NULL'
135
- collector = visit o.right, collector
136
- else
137
- collector = visit Arel::Nodes.build_quoted(','), collector
138
- end
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.orders.blank?
141
- o.orders.each_with_index do |order,i|
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,7 +155,7 @@ 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 == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
158
+ if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
158
159
  collector << "NULL"
159
160
  else
160
161
  collector << 'TO_CLOB('
@@ -466,14 +467,12 @@ module ArelExtensions
466
467
  o.left.each_with_index do |row, idx| # values
467
468
  collector << " UNION ALL " if idx != 0
468
469
  collector << "(SELECT "
469
- v = Arel::Nodes::Values.new(row, o.cols)
470
- len = v.expressions.length - 1
471
- v.expressions.each_with_index { |value, i|
470
+ len = row.length - 1
471
+ row.zip(o.cols).each_with_index { |(value, attr), i|
472
472
  case value
473
473
  when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
474
474
  collector = visit value, collector
475
475
  else
476
- attr = v.columns[i]
477
476
  collector << quote(value, attr && column_for(attr)).to_s
478
477
  end
479
478
  collector << Arel::Visitors::Oracle::COMMA unless i == len
@@ -490,11 +489,12 @@ module ArelExtensions
490
489
  collector << " UNION ALL " if idx != 0
491
490
  collector << "(SELECT "
492
491
  len = row.length - 1
493
- row.each_with_index { |value, i|
494
- attr = o.cols[i]
492
+ row.zip(o.cols).each_with_index { |(value, attr), i|
495
493
  case value
496
494
  when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
497
495
  collector = visit value, collector
496
+ when Integer
497
+ collector << value.to_s
498
498
  else
499
499
  collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
500
500
  end