arel_extensions 2.0.0.rc3 → 2.0.9

Sign up to get free protection for your applications and to get access to all the features.
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 +16 -9
  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.rc3".freeze
2
+ VERSION = "2.0.9".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