arel_extensions 1.5.2 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -7
  4. data/.rubocop.yml +3 -67
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +28 -2
  13. data/README.md +90 -239
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +10 -10
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +21 -21
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -7
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -27
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +19 -20
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +37 -48
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +7 -5
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +5 -19
  75. data/lib/arel_extensions/predications.rb +43 -44
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +35 -78
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +192 -423
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -354
  84. data/lib/arel_extensions/visitors/oracle.rb +178 -221
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -257
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -299
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -226
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +117 -120
  94. data/test/support/fake_record.rb +3 -9
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +11 -11
  97. data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +366 -711
  102. data/test/with_ar/insert_agnostic_test.rb +21 -27
  103. data/test/with_ar/test_bulk_sqlite.rb +16 -17
  104. data/test/with_ar/test_math_sqlite.rb +26 -26
  105. data/test/with_ar/test_string_mysql.rb +33 -31
  106. data/test/with_ar/test_string_sqlite.rb +34 -30
  107. metadata +37 -47
  108. data/.github/workflows/publish.yml +0 -29
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -403
  111. data/CONTRIBUTING.md +0 -102
  112. data/NEWS.md +0 -104
  113. data/bin/build +0 -15
  114. data/bin/compose +0 -6
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -44
  117. data/dev/compose.yaml +0 -71
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails4_2.gemfile +0 -38
  121. data/gemfiles/rails5.gemfile +0 -29
  122. data/gemfiles/rails6.gemfile +0 -33
  123. data/gemfiles/rails6_1.gemfile +0 -41
  124. data/gemfiles/rails7.gemfile +0 -41
  125. data/gemfiles/rails7_1.gemfile +0 -42
  126. data/gemfiles/rails7_2.gemfile +0 -41
  127. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  128. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  129. data/generate_gems.sh +0 -15
  130. data/lib/arel_extensions/aliases.rb +0 -14
  131. data/lib/arel_extensions/helpers.rb +0 -62
  132. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  133. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  134. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  135. data/lib/arel_extensions/nodes/select.rb +0 -10
  136. data/lib/arel_extensions/nodes/sum.rb +0 -7
  137. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  138. data/lib/arel_extensions/warning.rb +0 -42
  139. data/test/arelx_test_helper.rb +0 -92
  140. data/version_v1.rb +0 -3
  141. data/version_v2.rb +0 -3
@@ -1,53 +1,43 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- class Arel::Visitors::PostgreSQL
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' => 'YYYY', '%C' => 'CC', '%y' => 'YY',
11
- '%m' => 'MM', '%B' => 'TMMonth', '%^B' => 'TMMONTH', '%b' => 'TMMon', '%^b' => 'TMMON',
12
- '%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
13
- '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'TMDy', '%A' => 'TMDay', # day, weekday
14
- '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
15
- '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
16
- '%%' => '%',
17
- }.freeze
18
-
19
- NUMBER_COMMA_MAPPING = {
20
- 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '
21
- }.freeze
3
+ Arel::Visitors::PostgreSQL.class_eval do
4
+ Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
5
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
6
+ '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
7
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
8
+ '%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
+ Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
22
12
 
23
13
  def visit_ArelExtensions_Nodes_Rand o, collector
24
- collector << 'RANDOM('
25
- if (o.left != nil && o.right != nil)
14
+ collector << "RANDOM("
15
+ if(o.left != nil && o.right != nil)
26
16
  collector = visit o.left, collector
27
- collector << COMMA
17
+ collector << Arel::Visitors::PostgreSQL::COMMA
28
18
  collector = isit o.right, collector
29
19
  end
30
- collector << ')'
20
+ collector << ")"
31
21
  collector
32
22
  end
33
23
 
34
24
  def visit_ArelExtensions_Nodes_Power o, collector
35
- collector << 'POWER('
25
+ collector << "POWER("
36
26
  o.expressions.each_with_index { |arg, i|
37
- collector << Arel::Visitors::ToSql::COMMA if i != 0
27
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
38
28
  collector = visit arg, collector
39
29
  }
40
- collector << ')'
30
+ collector << ")"
41
31
  collector
42
32
  end
43
33
 
44
34
  def visit_ArelExtensions_Nodes_Log10 o, collector
45
- collector << 'LOG('
35
+ collector << "LOG("
46
36
  o.expressions.each_with_index { |arg, i|
47
- collector << Arel::Visitors::ToSql::COMMA if i != 0
37
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
48
38
  collector = visit arg, collector
49
39
  }
50
- collector << ')'
40
+ collector << ")"
51
41
  collector
52
42
  end
53
43
 
@@ -55,7 +45,7 @@ module ArelExtensions
55
45
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil
56
46
  def visit_Arel_Nodes_Regexp o, collector
57
47
  collector = visit o.left, collector
58
- collector << ' ~ '
48
+ collector << " ~ "
59
49
  collector = visit o.right, collector
60
50
  collector
61
51
  end
@@ -63,7 +53,7 @@ module ArelExtensions
63
53
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
64
54
  def visit_Arel_Nodes_NotRegexp o, collector
65
55
  collector = visit o.left, collector
66
- collector << ' !~ '
56
+ collector << " !~ "
67
57
  collector = visit o.right, collector
68
58
  collector
69
59
  end
@@ -74,11 +64,11 @@ module ArelExtensions
74
64
  collector = visit arg, collector
75
65
  collector << ' || ' unless i == o.expressions.length - 1
76
66
  }
77
- collector << ')'
67
+ collector << ")"
78
68
  collector
79
69
  end
80
70
 
81
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
71
+ alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
82
72
  def visit_Arel_Nodes_As o, collector
83
73
  if o.left.is_a?(Arel::Nodes::Binary)
84
74
  collector << '('
@@ -87,126 +77,80 @@ module ArelExtensions
87
77
  else
88
78
  collector = visit o.left, collector
89
79
  end
90
- collector << ' AS '
91
-
92
- # sometimes these values are already quoted, if they are, don't double quote it
93
- quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
94
-
95
- collector << '"' if quote
80
+ collector << " AS \""
96
81
  collector = visit o.right, collector
97
- collector << '"' if quote
98
-
99
- collector
100
- end
101
-
102
- def visit_Aggregate_For_AggregateFunction o, collector
103
- if !o.order.blank? || !o.group.blank?
104
- collector << ' OVER ('
105
- if !o.group.blank?
106
- collector << ' PARTITION BY '
107
- o.group.each_with_index do |group, i|
108
- collector << COMMA if i != 0
109
- visit group, collector
110
- end
111
- end
112
- if !o.order.blank?
113
- collector << ' ORDER BY '
114
- o.order.each_with_index do |order, i|
115
- collector << COMMA if i != 0
116
- visit order, collector
117
- end
118
- end
119
- collector << ')'
120
- end
82
+ collector << "\""
121
83
  collector
122
84
  end
123
85
 
124
86
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
125
- collector << 'array_to_string(array_agg('
87
+ collector << "array_to_string(array_agg("
126
88
  collector = visit o.left, collector
127
- if o.order && !o.order.blank?
128
- collector << ' ORDER BY'
129
- o.order.each_with_index do |order, i|
130
- collector << COMMA if i != 0
131
- collector << ' '
132
- visit order, collector
89
+ if !o.orders.blank?
90
+ collector << ' ORDER BY '
91
+ o.orders.each_with_index do |order,i|
92
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
+ collector = visit order, collector
133
94
  end
134
95
  end
135
- collector << ')'
136
- o.order = nil
137
- visit_Aggregate_For_AggregateFunction o, collector
138
- collector << COMMA
139
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
140
- collector =
141
- if 'NULL' != sep
142
- visit o.separator, collector
143
- else
144
- visit Arel.quoted(','), collector
145
- end
146
- collector << ')'
96
+ collector << ")"
97
+ collector << Arel::Visitors::PostgreSQL::COMMA
98
+ if o.right && o.right != 'NULL'
99
+ collector = visit o.right, collector
100
+ else
101
+ collector = visit Arel::Nodes.build_quoted(','), collector
102
+ end
103
+ collector << ")"
147
104
  collector
148
105
  end
149
106
 
150
107
  def visit_ArelExtensions_Nodes_Trim o, collector
151
- collector << 'TRIM(BOTH '
152
- collector = visit o.right, collector
153
- collector << ' FROM '
154
- collector = visit o.left, collector
155
- collector << ')'
156
- collector
108
+ collector << 'TRIM(BOTH '
109
+ collector = visit o.right, collector
110
+ collector << " FROM "
111
+ collector = visit o.left, collector
112
+ collector << ")"
113
+ collector
157
114
  end
158
115
 
159
116
  def visit_ArelExtensions_Nodes_Ltrim o, collector
160
- collector << 'TRIM(LEADING '
161
- collector = visit o.right, collector
162
- collector << ' FROM '
163
- collector = visit o.left, collector
164
- collector << ')'
165
- collector
117
+ collector << 'TRIM(LEADING '
118
+ collector = visit o.right, collector
119
+ collector << " FROM "
120
+ collector = visit o.left, collector
121
+ collector << ")"
122
+ collector
166
123
  end
167
124
 
168
125
  def visit_ArelExtensions_Nodes_Rtrim o, collector
169
126
  collector << 'TRIM(TRAILING '
170
127
  collector = visit o.right, collector
171
- collector << ' FROM '
128
+ collector << " FROM "
172
129
  collector = visit o.left, collector
173
- collector << ')'
130
+ collector << ")"
174
131
  collector
175
132
  end
176
133
 
177
134
  def visit_ArelExtensions_Nodes_Format o, collector
178
- visit_ArelExtensions_Nodes_FormattedDate o, collector
179
- end
180
-
181
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
182
- fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
183
- collector << 'TO_CHAR('
184
- collector << '(' if o.time_zone
135
+ collector << "TO_CHAR("
185
136
  collector = visit o.left, collector
186
- case o.time_zone
187
- when Hash
188
- src_tz, dst_tz = o.time_zone.first
189
- collector << ') AT TIME ZONE '
190
- collector = visit Arel.quoted(src_tz), collector
191
- collector << ' AT TIME ZONE '
192
- collector = visit Arel.quoted(dst_tz), collector
193
- when String
194
- collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
195
- collector = visit Arel.quoted(o.time_zone), collector
196
- end
197
- collector << COMMA
198
- collector = visit Arel.quoted(fmt), collector
199
- collector << ')'
137
+ collector << Arel::Visitors::PostgreSQL::COMMA
138
+
139
+ f = o.iso_format.dup
140
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
141
+ collector = visit Arel::Nodes.build_quoted(f), collector
142
+
143
+ collector << ")"
200
144
  collector
201
145
  end
202
146
 
203
147
  def visit_ArelExtensions_Nodes_Repeat o, collector
204
- collector << 'REPEAT('
148
+ collector << "REPEAT("
205
149
  o.expressions.each_with_index { |arg, i|
206
- collector << Arel::Visitors::ToSql::COMMA if i != 0
150
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
207
151
  collector = visit arg, collector
208
152
  }
209
- collector << ')'
153
+ collector << ")"
210
154
  collector
211
155
  end
212
156
 
@@ -248,9 +192,9 @@ module ArelExtensions
248
192
 
249
193
  def visit_ArelExtensions_Nodes_Collate o, collector
250
194
  if o.ai
251
- collector << 'unaccent('
195
+ collector << "unaccent("
252
196
  collector = visit o.expressions.first, collector
253
- collector << ')'
197
+ collector << ")"
254
198
  elsif o.ci
255
199
  collector = visit o.expressions.first, collector
256
200
  else
@@ -261,7 +205,7 @@ module ArelExtensions
261
205
 
262
206
  def visit_ArelExtensions_Nodes_DateAdd o, collector
263
207
  collector = visit o.left, collector
264
- collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
208
+ collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
265
209
  collector = visit o.postgresql_value(o.right), collector
266
210
  collector
267
211
  end
@@ -269,16 +213,16 @@ module ArelExtensions
269
213
  def visit_ArelExtensions_Nodes_DateDiff o, collector
270
214
  if o.right_node_type == :ruby_date || o.right_node_type == :ruby_time || o.right_node_type == :date || o.right_node_type == :datetime || o.right_node_type == :time
271
215
  collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
272
- "DATEDIFF('second', "
216
+ "DATEDIFF('second', "
273
217
  else
274
- "DATEDIFF('day', "
218
+ "DATEDIFF('day', "
275
219
  end
276
220
  collector = visit o.right, collector
277
221
  collector << (o.right_node_type == :date ? '::date' : '::timestamp')
278
- collector << COMMA
222
+ collector << Arel::Visitors::PostgreSQL::COMMA
279
223
  collector = visit o.left, collector
280
224
  collector << (o.left_node_type == :date ? '::date' : '::timestamp')
281
- collector << ')'
225
+ collector << ")"
282
226
  else
283
227
  collector << '('
284
228
  collector = visit o.left, collector
@@ -295,57 +239,41 @@ module ArelExtensions
295
239
  def visit_ArelExtensions_Nodes_Duration o, collector
296
240
  if o.with_interval
297
241
  interval = case o.left
298
- when 'd', 'm', 'y'
242
+ when 'd','m','y'
299
243
  'DAY'
300
- when 'h', 'mn', 's'
244
+ when 'h','mn','s'
301
245
  'SECOND'
302
246
  when /i\z/
303
- collector << '('
247
+ collector << "("
304
248
  collector = visit o.right, collector
305
- collector << ')'
306
- collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
249
+ collector << ")"
250
+ collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
307
251
  return collector
308
252
  end
309
253
  end
310
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM CAST("
254
+ collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
311
255
  collector = visit o.right, collector
312
- collector << ' AS TIMESTAMP WITH TIME ZONE))'
256
+ collector << ")"
313
257
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
314
258
  collector
315
259
  end
316
260
 
317
261
  def visit_ArelExtensions_Nodes_Locate o, collector
318
- collector << 'POSITION('
262
+ collector << "POSITION("
319
263
  collector = visit o.right, collector
320
- collector << ' IN '
264
+ collector << " IN "
321
265
  collector = visit o.left, collector
322
- collector << ')'
266
+ collector << ")"
323
267
  collector
324
268
  end
325
269
 
326
270
  def visit_ArelExtensions_Nodes_Substring o, collector
327
- collector << 'SUBSTR('
271
+ collector << "SUBSTR("
328
272
  o.expressions.each_with_index { |arg, i|
329
- collector << COMMA if i != 0
273
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
330
274
  collector = visit arg, collector
331
275
  }
332
- collector << ')'
333
- collector
334
- end
335
-
336
- def visit_ArelExtensions_Nodes_RegexpReplace o, collector
337
- collector << 'REGEXP_REPLACE('
338
- visit o.left, collector
339
- collector << Arel::Visitors::ToSql::COMMA
340
- tab = o.pattern.inspect + 'g' # Make it always global
341
- pattern = tab.split('/')[1..-2].join('/')
342
- flags = tab.split('/')[-1]
343
- visit Arel.quoted(pattern), collector
344
- collector << Arel::Visitors::ToSql::COMMA
345
- visit o.substitute, collector
346
- collector << Arel::Visitors::ToSql::COMMA
347
- visit Arel.quoted(flags + 'g'), collector
348
- collector << ')'
276
+ collector << ")"
349
277
  collector
350
278
  end
351
279
 
@@ -356,111 +284,98 @@ module ArelExtensions
356
284
  end
357
285
 
358
286
  def visit_ArelExtensions_Nodes_IsNotNull o, collector
359
- collector = visit o.expr, collector
287
+ collector = visit o.expr, collector
360
288
  collector << ' IS NOT NULL'
361
289
  collector
362
290
  end
363
291
 
364
292
  def visit_ArelExtensions_Nodes_Sum o, collector
365
- collector << 'sum('
293
+ collector << "sum("
366
294
  collector = visit o.expr, collector
367
- collector << ')'
368
- visit_Aggregate_For_AggregateFunction o, collector
295
+ collector << ")"
369
296
  collector
370
297
  end
371
298
 
372
299
  def visit_ArelExtensions_Nodes_Wday o, collector
373
- collector << 'EXRTACT(DOW, '
300
+ collector << "EXRTACT(DOW, "
374
301
  collector = visit o.date, collector
375
302
  collector << ')'
376
303
  collector
377
304
  end
378
305
 
379
306
  def visit_ArelExtensions_Nodes_Cast o, collector
380
- as_attr =
381
- case o.as_attr
382
- when :string
383
- 'varchar'
384
- when :text, :ntext
385
- 'text'
386
- when :time
387
- 'time'
388
- when :int
389
- collector << 'CAST(CAST('
390
- collector = visit o.left, collector
391
- collector << ' AS numeric) AS int)'
392
- return collector
393
- when :number, :decimal, :float
394
- 'numeric'
395
- when :datetime
396
- 'timestamp without time zone'
397
- when :date
398
- 'date'
399
- when :binary
400
- 'binary'
401
- when :jsonb
402
- 'jsonb'
403
- else
404
- o.as_attr.to_s
405
- end
406
-
407
- collector << 'CAST('
307
+ as_attr = case o.as_attr
308
+ when :string
309
+ Arel::Nodes::SqlLiteral.new('varchar')
310
+ when :time
311
+ Arel::Nodes::SqlLiteral.new('time')
312
+ when :int
313
+ collector << "CAST(CAST("
314
+ collector = visit o.left, collector
315
+ collector << " AS numeric) AS int)"
316
+ return collector
317
+ when :number, :decimal, :float
318
+ Arel::Nodes::SqlLiteral.new('numeric')
319
+ when :datetime
320
+ Arel::Nodes::SqlLiteral.new('timestamp')
321
+ when :date
322
+ Arel::Nodes::SqlLiteral.new('date')
323
+ when :binary
324
+ Arel::Nodes::SqlLiteral.new('binary')
325
+ else
326
+ Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
327
+ end
328
+ collector << "CAST("
408
329
  collector = visit o.left, collector
409
- collector << ' AS '
410
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
411
- collector << ')'
330
+ collector << " AS "
331
+ collector = visit as_attr, collector
332
+ collector << ")"
412
333
  collector
413
334
  end
414
335
 
415
336
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
416
337
  col = o.left.coalesce(0)
417
- comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
418
- thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
338
+ comma = o.precision == 0 ? '' : (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][0] || '.')
339
+ thousand_separator = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][1] || (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
419
340
  nines_after = (1..o.precision).map{'9'}.join('')
420
- nines_before = ("999#{thousand_separator}" * 4 + '990')
341
+ nines_before = ("999#{thousand_separator}"*4+"990")
421
342
 
422
- sign = Arel.when(col < 0).
343
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
423
344
  then('-').
424
345
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
425
346
  sign_length = ArelExtensions::Nodes::Length.new([sign])
426
347
 
427
- number =
428
- if o.scientific_notation
429
- ArelExtensions::Nodes::Concat.new([
430
- Arel::Nodes::NamedFunction.new('TRIM', [
431
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
432
- Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
433
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
434
- ])]),
435
- o.type,
436
- Arel::Nodes::NamedFunction.new('TRIM', [
437
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
438
- Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
439
- Arel.quoted("FM#{nines_before}")
440
- ])])
441
- ])
442
- else
443
- Arel::Nodes::NamedFunction.new('TRIM', [
444
- Arel::Nodes::NamedFunction.new('TO_CHAR', [
445
- Arel.quoted(col.abs),
446
- Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
447
- ])])
448
- end
348
+ if o.scientific_notation
349
+ number = ArelExtensions::Nodes::Concat.new([
350
+ Arel::Nodes::NamedFunction.new('TRIM',[
351
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
352
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
353
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
354
+ ])]),
355
+ o.type,
356
+ Arel::Nodes::NamedFunction.new('TRIM',[
357
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
358
+ col.abs.log10.floor,
359
+ Arel::Nodes.build_quoted('FM'+nines_before)
360
+ ])])
361
+ ])
362
+ else
363
+ number = Arel::Nodes::NamedFunction.new('TRIM',[
364
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
365
+ Arel::Nodes.build_quoted(col.abs),
366
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
367
+ ])])
368
+ end
449
369
 
450
- repeated_char =
451
- if o.width == 0
452
- Arel.quoted('')
453
- else
454
- Arel
455
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
456
- .then(Arel.quoted(
457
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
458
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
459
- )
460
- .else('')
461
- end
462
- before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
463
- middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
370
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
371
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
372
+ then(Arel::Nodes.build_quoted(
373
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
374
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
375
+ ).
376
+ else('')
377
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
378
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
464
379
  after = o.flags.include?('-') ? repeated_char : ''
465
380
  full_number = ArelExtensions::Nodes::Concat.new([
466
381
  before,
@@ -469,30 +384,30 @@ module ArelExtensions
469
384
  number,
470
385
  after
471
386
  ])
472
- collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
387
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
473
388
  collector
474
389
  end
475
390
 
476
391
 
477
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
392
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
478
393
  def visit_Arel_Nodes_SelectStatement o, collector
479
394
 
480
395
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
481
396
  o = o.dup
482
397
  o.orders = []
483
398
  end
484
- old_visit_Arel_Nodes_SelectStatement(o, collector)
399
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
485
400
  end
486
401
 
487
- alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
402
+ alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
488
403
  def visit_Arel_Nodes_TableAlias o, collector
489
404
  if o.name.length > 63
490
405
  o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
491
406
  end
492
- old_visit_Arel_Nodes_TableAlias(o, collector)
407
+ old_visit_Arel_Nodes_TableAlias(o,collector)
493
408
  end
494
409
 
495
- alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
410
+ alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
496
411
  def visit_Arel_Attributes_Attribute o, collector
497
412
  join_name = o.relation.table_alias || o.relation.name
498
413
  if join_name.length > 63
@@ -502,35 +417,33 @@ module ArelExtensions
502
417
  end
503
418
 
504
419
  def visit_ArelExtensions_Nodes_Std o, collector
505
- collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
420
+ collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
506
421
  visit o.left, collector
507
- collector << ')'
508
- visit_Aggregate_For_AggregateFunction o, collector
422
+ collector << ")"
509
423
  collector
510
424
  end
511
425
 
512
426
  def visit_ArelExtensions_Nodes_Variance o, collector
513
- collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
427
+ collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
514
428
  visit o.left, collector
515
- collector << ')'
516
- visit_Aggregate_For_AggregateFunction o, collector
429
+ collector << ")"
517
430
  collector
518
431
  end
519
432
 
520
- def visit_ArelExtensions_Nodes_Json o, collector
433
+ def visit_ArelExtensions_Nodes_Json o,collector
521
434
  case o.dict
522
435
  when Array
523
436
  collector << 'to_jsonb(array['
524
- o.dict.each.with_index do |v, i|
437
+ o.dict.each.with_index do |v,i|
525
438
  if i != 0
526
439
  collector << Arel::Visitors::MySQL::COMMA
527
440
  end
528
- collector = visit v, collector
441
+ collector = visit v, collector
529
442
  end
530
443
  collector << '])'
531
444
  when Hash
532
445
  collector << 'jsonb_build_object('
533
- o.dict.each.with_index do |(k, v), i|
446
+ o.dict.each.with_index do |(k,v),i|
534
447
  if i != 0
535
448
  collector << Arel::Visitors::MySQL::COMMA
536
449
  end
@@ -539,11 +452,13 @@ module ArelExtensions
539
452
  collector = visit v, collector
540
453
  end
541
454
  collector << ')'
542
- when String, Numeric, TrueClass, FalseClass
543
- collector = visit Arel.quoted("#{o.dict}"), collector
455
+ when String,Numeric,TrueClass,FalseClass
456
+ collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
544
457
  collector << '::jsonb'
545
458
  when NilClass
546
- collector << %Q['null'::jsonb]
459
+ collector << %Q['null'::jsonb]
460
+ when Arel::Attributes::Attribute
461
+ collector = visit o.dict.cast(:jsonb), collector
547
462
  else
548
463
  collector = visit o.dict, collector
549
464
  collector << '::jsonb'
@@ -551,8 +466,8 @@ module ArelExtensions
551
466
  collector
552
467
  end
553
468
 
554
- def visit_ArelExtensions_Nodes_JsonMerge o, collector
555
- o.expressions.each.with_index do |v, i|
469
+ def visit_ArelExtensions_Nodes_JsonMerge o,collector
470
+ o.expressions.each.with_index do |v,i|
556
471
  if i != 0
557
472
  collector << ' || '
558
473
  end
@@ -561,14 +476,14 @@ module ArelExtensions
561
476
  collector
562
477
  end
563
478
 
564
- def visit_ArelExtensions_Nodes_JsonGet o, collector
479
+ def visit_ArelExtensions_Nodes_JsonGet o,collector
565
480
  collector = visit o.dict, collector
566
- collector << ' ->> '
481
+ collector << ' -> '
567
482
  collector = visit o.key, collector
568
483
  collector
569
484
  end
570
485
 
571
- def visit_ArelExtensions_Nodes_JsonSet o, collector
486
+ def visit_ArelExtensions_Nodes_JsonSet o,collector
572
487
  collector << 'jsonb_set('
573
488
  collector = visit o.dict, collector
574
489
  collector << Arel::Visitors::MySQL::COMMA
@@ -590,7 +505,7 @@ module ArelExtensions
590
505
  else
591
506
  case o.dict
592
507
  when Hash
593
- o.dict.each.with_index do |(k, v), i|
508
+ o.dict.each.with_index do |(k,v),i|
594
509
  if i != 0
595
510
  collector << ' || '
596
511
  end
@@ -608,6 +523,7 @@ module ArelExtensions
608
523
  end
609
524
  collector
610
525
  end
526
+
611
527
  end
612
528
  end
613
529
  end