arel_extensions 2.0.21 → 2.2.2
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/.codeclimate.yml +1 -2
- data/.github/workflows/publish.yml +29 -0
- data/.github/workflows/release.yml +30 -0
- data/.github/workflows/ruby.yml +377 -80
- data/.gitignore +7 -6
- data/.rubocop.yml +62 -1
- data/CONTRIBUTING.md +102 -0
- data/Gemfile +2 -23
- data/NEWS.md +89 -0
- data/README.md +228 -84
- data/Rakefile +11 -4
- data/TODO +0 -1
- data/appveyor.yml +60 -22
- data/arel_extensions.gemspec +11 -12
- data/bin/build +15 -0
- data/bin/compose +6 -0
- data/bin/publish +8 -0
- data/dev/arelx.dockerfile +44 -0
- data/dev/compose.yaml +71 -0
- data/dev/postgres.dockerfile +5 -0
- data/dev/rbenv +189 -0
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4_2.gemfile +38 -0
- data/gemfiles/rails5.gemfile +29 -0
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +16 -14
- data/gemfiles/rails6.gemfile +18 -15
- data/gemfiles/rails6_1.gemfile +18 -15
- data/gemfiles/rails7.gemfile +33 -0
- data/gemfiles/rails7_1.gemfile +33 -0
- data/gemfiles/rails7_2.gemfile +33 -0
- data/gemspecs/arel_extensions-v1.gemspec +12 -13
- data/gemspecs/arel_extensions-v2.gemspec +11 -12
- data/init/mssql.sql +0 -0
- data/init/mysql.sql +0 -0
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +0 -0
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +10 -2
- data/lib/arel_extensions/boolean_functions.rb +2 -4
- data/lib/arel_extensions/common_sql_functions.rb +12 -12
- data/lib/arel_extensions/comparators.rb +14 -14
- data/lib/arel_extensions/date_duration.rb +14 -9
- data/lib/arel_extensions/helpers.rb +62 -0
- data/lib/arel_extensions/insert_manager.rb +19 -17
- data/lib/arel_extensions/math.rb +48 -45
- data/lib/arel_extensions/math_functions.rb +18 -18
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -1
- data/lib/arel_extensions/nodes/case.rb +10 -12
- data/lib/arel_extensions/nodes/cast.rb +6 -6
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +9 -9
- data/lib/arel_extensions/nodes/concat.rb +2 -2
- data/lib/arel_extensions/nodes/date_diff.rb +33 -14
- data/lib/arel_extensions/nodes/duration.rb +0 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +3 -2
- data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
- data/lib/arel_extensions/nodes/function.rb +22 -26
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +15 -9
- data/lib/arel_extensions/nodes/length.rb +6 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/log10.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +1 -1
- data/lib/arel_extensions/nodes/md5.rb +0 -0
- data/lib/arel_extensions/nodes/power.rb +0 -0
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +2 -10
- data/lib/arel_extensions/nodes/rollup.rb +36 -0
- data/lib/arel_extensions/nodes/round.rb +0 -0
- data/lib/arel_extensions/nodes/select.rb +10 -0
- data/lib/arel_extensions/nodes/soundex.rb +2 -2
- data/lib/arel_extensions/nodes/std.rb +0 -0
- data/lib/arel_extensions/nodes/substring.rb +1 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +5 -5
- data/lib/arel_extensions/nodes/union_all.rb +4 -4
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/nodes.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +16 -0
- data/lib/arel_extensions/predications.rb +10 -10
- data/lib/arel_extensions/railtie.rb +1 -1
- data/lib/arel_extensions/set_functions.rb +3 -3
- data/lib/arel_extensions/string_functions.rb +19 -10
- data/lib/arel_extensions/tasks.rb +2 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/convert_format.rb +0 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
- data/lib/arel_extensions/visitors/mssql.rb +394 -169
- data/lib/arel_extensions/visitors/mysql.rb +238 -151
- data/lib/arel_extensions/visitors/oracle.rb +170 -131
- data/lib/arel_extensions/visitors/oracle12.rb +16 -16
- data/lib/arel_extensions/visitors/postgresql.rb +170 -140
- data/lib/arel_extensions/visitors/sqlite.rb +88 -87
- data/lib/arel_extensions/visitors/to_sql.rb +185 -156
- data/lib/arel_extensions/visitors.rb +73 -60
- data/lib/arel_extensions.rb +173 -36
- data/test/arelx_test_helper.rb +49 -1
- data/test/database.yml +13 -7
- data/test/real_db_test.rb +101 -83
- data/test/support/fake_record.rb +8 -2
- data/test/test_comparators.rb +5 -5
- data/test/visitors/test_bulk_insert_oracle.rb +5 -5
- data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
- data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
- data/test/visitors/test_oracle.rb +14 -14
- data/test/visitors/test_to_sql.rb +121 -93
- data/test/with_ar/all_agnostic_test.rb +630 -320
- data/test/with_ar/insert_agnostic_test.rb +25 -18
- data/test/with_ar/test_bulk_sqlite.rb +11 -7
- data/test/with_ar/test_math_sqlite.rb +18 -14
- data/test/with_ar/test_string_mysql.rb +26 -22
- data/test/with_ar/test_string_sqlite.rb +26 -22
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +24 -26
- data/.travis/oracle/download.js +0 -152
- data/.travis/oracle/download.sh +0 -30
- data/.travis/oracle/download_ojdbc.js +0 -116
- data/.travis/oracle/install.sh +0 -34
- data/.travis/setup_accounts.sh +0 -9
- data/.travis/sqlite3/extension-functions.sh +0 -6
- data/.travis.yml +0 -193
- data/gemfiles/rails4.gemfile +0 -29
- data/gemfiles/rails5_0.gemfile +0 -29
@@ -6,30 +6,31 @@ module ArelExtensions
|
|
6
6
|
DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
7
7
|
DATE_FORMAT_DIRECTIVES = {
|
8
8
|
'%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
9
|
-
'%
|
9
|
+
'%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
|
10
|
+
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'Dy', '%A' => 'Day', # day, weekday
|
10
11
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
11
12
|
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
12
13
|
}
|
13
|
-
NUMBER_COMMA_MAPPING = {
|
14
|
+
NUMBER_COMMA_MAPPING = {'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '}
|
14
15
|
|
15
16
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
collector << 'LOG('
|
18
|
+
o.expressions.each_with_index { |arg, i|
|
19
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
20
|
+
collector = visit arg, collector
|
21
|
+
}
|
22
|
+
collector << ',10)'
|
23
|
+
collector
|
23
24
|
end
|
24
25
|
|
25
26
|
def visit_ArelExtensions_Nodes_Power o, collector
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
collector << 'POWER('
|
28
|
+
o.expressions.each_with_index { |arg, i|
|
29
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
30
|
+
collector = visit arg, collector
|
31
|
+
}
|
32
|
+
collector << ')'
|
33
|
+
collector
|
33
34
|
end
|
34
35
|
|
35
36
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
@@ -107,54 +108,59 @@ module ArelExtensions
|
|
107
108
|
end
|
108
109
|
|
109
110
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
111
|
+
if o.ai
|
112
|
+
collector << 'NLSSORT('
|
113
|
+
collector = visit o.expressions.first, collector
|
114
|
+
collector << COMMA
|
115
|
+
collector << "'NLS_SORT = BINARY_AI NLS_COMP = LINGUISTIC'"
|
116
|
+
collector << ')'
|
117
|
+
elsif o.ci
|
118
|
+
collector << 'NLSSORT('
|
119
|
+
collector = visit o.expressions.first, collector
|
120
|
+
collector << COMMA
|
121
|
+
collector << "'NLS_SORT = BINARY_CI NLS_COMP = LINGUISTIC'"
|
122
|
+
collector << ')'
|
123
|
+
else
|
124
|
+
collector = visit o.expressions.first, collector
|
125
|
+
end
|
125
126
|
collector
|
126
127
|
end
|
127
128
|
|
129
|
+
def visit_Arel_Nodes_RollUp(o, collector)
|
130
|
+
collector << "ROLLUP"
|
131
|
+
grouping_array_or_grouping_element o, collector
|
132
|
+
end
|
133
|
+
|
128
134
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
129
|
-
collector <<
|
135
|
+
collector << '(LISTAGG('
|
130
136
|
collector = visit o.left, collector
|
131
137
|
collector << COMMA
|
132
138
|
collector =
|
133
139
|
if o.separator && o.separator != 'NULL'
|
134
140
|
visit o.separator, collector
|
135
141
|
else
|
136
|
-
visit Arel
|
142
|
+
visit Arel.quoted(','), collector
|
137
143
|
end
|
138
|
-
collector <<
|
144
|
+
collector << ') WITHIN GROUP (ORDER BY '
|
139
145
|
if !o.order.blank?
|
140
|
-
o.order.each_with_index do |order,i|
|
146
|
+
o.order.each_with_index do |order, i|
|
141
147
|
collector << COMMA if i != 0
|
142
148
|
collector = visit order, collector
|
143
149
|
end
|
144
150
|
else
|
145
151
|
collector = visit o.left, collector
|
146
152
|
end
|
147
|
-
collector <<
|
153
|
+
collector << '))'
|
148
154
|
collector
|
149
155
|
end
|
150
156
|
|
151
157
|
def visit_ArelExtensions_Nodes_Coalesce o, collector
|
152
|
-
collector <<
|
158
|
+
collector << 'COALESCE('
|
153
159
|
o.expressions.each_with_index { |arg, i|
|
154
160
|
collector << COMMA if i != 0
|
155
161
|
if i > 0 && o.left_node_type == :text
|
156
162
|
if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
|
157
|
-
collector <<
|
163
|
+
collector << 'NULL'
|
158
164
|
else
|
159
165
|
collector << 'TO_CLOB('
|
160
166
|
collector = visit arg, collector
|
@@ -164,12 +170,12 @@ module ArelExtensions
|
|
164
170
|
collector = visit arg, collector
|
165
171
|
end
|
166
172
|
}
|
167
|
-
collector <<
|
173
|
+
collector << ')'
|
168
174
|
collector
|
169
175
|
end
|
170
176
|
|
171
177
|
def visit_ArelExtensions_Nodes_MD5 o, collector
|
172
|
-
collector <<
|
178
|
+
collector << 'LOWER (RAWTOHEX (DBMS_OBFUSCATION_TOOLKIT.md5(input => UTL_I18N.STRING_TO_RAW('
|
173
179
|
collector = visit o.left, collector
|
174
180
|
collector << ", 'AL32UTF8'))))"
|
175
181
|
collector
|
@@ -184,7 +190,7 @@ module ArelExtensions
|
|
184
190
|
collector << 'TO_DATE(' if lc
|
185
191
|
collector = visit o.left, collector
|
186
192
|
collector << ')' if lc
|
187
|
-
collector <<
|
193
|
+
collector << ' - '
|
188
194
|
collector << 'TO_DATE(' if rc
|
189
195
|
collector = visit o.right, collector
|
190
196
|
collector << ')' if rc
|
@@ -218,16 +224,16 @@ module ArelExtensions
|
|
218
224
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
219
225
|
case o.left
|
220
226
|
when 'wd', 'w'
|
221
|
-
collector <<
|
227
|
+
collector << 'TO_CHAR('
|
222
228
|
collector = visit o.right, collector
|
223
229
|
collector << COMMA
|
224
|
-
collector = visit Arel
|
230
|
+
collector = visit Arel.quoted(DATE_MAPPING[o.left]), collector
|
225
231
|
else
|
226
232
|
right = case o.left
|
227
|
-
when 'd','m','y'
|
233
|
+
when 'd', 'm', 'y'
|
228
234
|
interval = 'DAY'
|
229
235
|
o.right.cast(:date)
|
230
|
-
when 'h','mn','s'
|
236
|
+
when 'h', 'mn', 's'
|
231
237
|
interval = 'SECOND'
|
232
238
|
o.right.cast(:datetime)
|
233
239
|
when /i\z/
|
@@ -243,7 +249,7 @@ module ArelExtensions
|
|
243
249
|
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
|
244
250
|
collector = visit right, collector
|
245
251
|
end
|
246
|
-
collector <<
|
252
|
+
collector << ')'
|
247
253
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
248
254
|
collector
|
249
255
|
end
|
@@ -251,45 +257,45 @@ module ArelExtensions
|
|
251
257
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
252
258
|
case o.as_attr
|
253
259
|
when :string
|
254
|
-
collector <<
|
260
|
+
collector << 'TO_CHAR('
|
255
261
|
collector = visit o.left, collector
|
256
|
-
collector <<
|
262
|
+
collector << ')'
|
257
263
|
return collector
|
258
264
|
when :text
|
259
|
-
collector <<
|
265
|
+
collector << 'TO_CLOB('
|
260
266
|
collector = visit o.left, collector
|
261
|
-
collector <<
|
267
|
+
collector << ')'
|
262
268
|
return collector
|
263
269
|
when :ntext
|
264
|
-
collector <<
|
270
|
+
collector << 'TO_NCLOB('
|
265
271
|
collector = visit o.left, collector
|
266
|
-
collector <<
|
272
|
+
collector << ')'
|
267
273
|
return collector
|
268
274
|
when :time
|
269
275
|
if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
|
270
|
-
collector <<
|
276
|
+
collector << 'TO_DATE('
|
271
277
|
collector = visit o.left, collector
|
272
278
|
collector << ",'HH24:MI:SS')"
|
273
279
|
else
|
274
|
-
collector <<
|
280
|
+
collector << 'TO_DATE(TO_CHAR('
|
275
281
|
collector = visit o.left, collector
|
276
282
|
collector << ",'HH24:MI:SS'),'HH24:MI:SS')"
|
277
283
|
end
|
278
284
|
return collector
|
279
285
|
when :number, :decimal
|
280
|
-
collector <<
|
286
|
+
collector << 'TO_NUMBER('
|
281
287
|
collector = visit o.left, collector
|
282
|
-
collector <<
|
288
|
+
collector << ')'
|
283
289
|
return collector
|
284
290
|
when :datetime
|
285
291
|
as_attr = Arel::Nodes::SqlLiteral.new('timestamp')
|
286
292
|
when :date
|
287
293
|
if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
|
288
|
-
collector <<
|
294
|
+
collector << 'TO_DATE('
|
289
295
|
collector = visit o.left, collector
|
290
296
|
collector << ",'YYYY-MM-DD')"
|
291
297
|
else
|
292
|
-
collector <<
|
298
|
+
collector << 'TO_DATE(TO_CHAR('
|
293
299
|
collector = visit o.left, collector
|
294
300
|
collector << ",'YYYY-MM-DD'),'YYYY-MM-DD')"
|
295
301
|
end
|
@@ -299,18 +305,18 @@ module ArelExtensions
|
|
299
305
|
else
|
300
306
|
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
301
307
|
end
|
302
|
-
collector <<
|
308
|
+
collector << 'CAST('
|
303
309
|
collector = visit o.left, collector
|
304
|
-
collector <<
|
310
|
+
collector << ' AS '
|
305
311
|
collector = visit as_attr, collector
|
306
|
-
collector <<
|
312
|
+
collector << ')'
|
307
313
|
collector
|
308
314
|
end
|
309
315
|
|
310
316
|
def visit_ArelExtensions_Nodes_Length o, collector
|
311
|
-
collector << "LENGTH("
|
317
|
+
collector << "LENGTH#{o.bytewise ? 'B' : ''}("
|
312
318
|
collector = visit o.expr, collector
|
313
|
-
collector <<
|
319
|
+
collector << ')'
|
314
320
|
collector
|
315
321
|
end
|
316
322
|
|
@@ -327,18 +333,18 @@ module ArelExtensions
|
|
327
333
|
end
|
328
334
|
|
329
335
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
330
|
-
collector <<
|
336
|
+
collector << 'DBMS_RANDOM.VALUE('
|
331
337
|
if o.left && o.right
|
332
338
|
collector = visit o.left, collector
|
333
339
|
collector << COMMA
|
334
340
|
collector = visit o.right, collector
|
335
341
|
end
|
336
|
-
collector <<
|
342
|
+
collector << ')'
|
337
343
|
collector
|
338
344
|
end
|
339
345
|
|
340
346
|
def visit_Arel_Nodes_Regexp o, collector
|
341
|
-
collector <<
|
347
|
+
collector << ' REGEXP_LIKE('
|
342
348
|
collector = visit o.left, collector
|
343
349
|
collector << COMMA
|
344
350
|
collector = visit o.right, collector
|
@@ -347,7 +353,7 @@ module ArelExtensions
|
|
347
353
|
end
|
348
354
|
|
349
355
|
def visit_Arel_Nodes_NotRegexp o, collector
|
350
|
-
collector <<
|
356
|
+
collector << ' NOT REGEXP_LIKE('
|
351
357
|
collector = visit o.left, collector
|
352
358
|
collector << COMMA
|
353
359
|
collector = visit o.right, collector
|
@@ -356,22 +362,22 @@ module ArelExtensions
|
|
356
362
|
end
|
357
363
|
|
358
364
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
359
|
-
collector <<
|
365
|
+
collector << 'INSTR('
|
360
366
|
o.expressions.each_with_index { |arg, i|
|
361
367
|
collector << COMMA if i != 0
|
362
368
|
collector = visit arg, collector
|
363
369
|
}
|
364
|
-
collector <<
|
370
|
+
collector << ')'
|
365
371
|
collector
|
366
372
|
end
|
367
373
|
|
368
374
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
369
|
-
collector <<
|
375
|
+
collector << 'SUBSTR('
|
370
376
|
o.expressions.each_with_index { |arg, i|
|
371
377
|
collector << COMMA if i != 0
|
372
378
|
collector = visit arg, collector
|
373
379
|
}
|
374
|
-
collector <<
|
380
|
+
collector << ')'
|
375
381
|
collector
|
376
382
|
end
|
377
383
|
|
@@ -390,14 +396,14 @@ module ArelExtensions
|
|
390
396
|
collector << COMMA
|
391
397
|
collector << 'COALESCE(dbms_lob.GETLENGTH('
|
392
398
|
collector = visit o.left, collector
|
393
|
-
collector <<
|
399
|
+
collector << '), 0)'
|
394
400
|
collector << COMMA
|
395
401
|
collector << '1)'
|
396
402
|
else
|
397
403
|
collector = visit o.left, collector
|
398
404
|
end
|
399
405
|
collector << ')' if o.left.is_a? ArelExtensions::Nodes::Trim
|
400
|
-
collector <<
|
406
|
+
collector << ')'
|
401
407
|
collector
|
402
408
|
end
|
403
409
|
|
@@ -410,7 +416,7 @@ module ArelExtensions
|
|
410
416
|
end
|
411
417
|
collector << ' FROM '
|
412
418
|
collector = visit o.left, collector
|
413
|
-
collector <<
|
419
|
+
collector << ')'
|
414
420
|
collector
|
415
421
|
end
|
416
422
|
|
@@ -423,7 +429,7 @@ module ArelExtensions
|
|
423
429
|
end
|
424
430
|
collector << ' FROM '
|
425
431
|
collector = visit o.left, collector
|
426
|
-
collector <<
|
432
|
+
collector << ')'
|
427
433
|
collector
|
428
434
|
end
|
429
435
|
|
@@ -445,35 +451,51 @@ module ArelExtensions
|
|
445
451
|
end
|
446
452
|
|
447
453
|
def visit_ArelExtensions_Nodes_Format o, collector
|
454
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
455
|
+
end
|
456
|
+
|
457
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
448
458
|
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
449
|
-
collector <<
|
459
|
+
collector << 'TO_CHAR('
|
460
|
+
collector << 'CAST(' if o.time_zone
|
450
461
|
collector = visit o.left, collector
|
462
|
+
case o.time_zone
|
463
|
+
when Hash
|
464
|
+
src_tz, dst_tz = o.time_zone.first
|
465
|
+
collector << ' as timestamp) at time zone '
|
466
|
+
collector = visit Arel.quoted(src_tz), collector
|
467
|
+
collector < ' at time zone '
|
468
|
+
collector = visit Arel.quoted(dst_tz), collector
|
469
|
+
when String
|
470
|
+
collector << ' as timestamp) at time zone '
|
471
|
+
collector = visit Arel.quoted(o.time_zone), collector
|
472
|
+
end
|
451
473
|
collector << COMMA
|
452
|
-
collector = visit Arel
|
453
|
-
collector <<
|
474
|
+
collector = visit Arel.quoted(fmt), collector
|
475
|
+
collector << ')'
|
454
476
|
collector
|
455
477
|
end
|
456
478
|
|
457
479
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
458
|
-
collector <<
|
480
|
+
collector << 'LPAD('
|
459
481
|
collector = visit o.expressions[0], collector # can't put empty string, otherwise it wouldn't work
|
460
482
|
collector << Arel::Visitors::ToSql::COMMA
|
461
483
|
collector = visit o.expressions[1], collector
|
462
484
|
collector << Arel::Visitors::ToSql::COMMA
|
463
485
|
collector = visit o.expressions[0], collector
|
464
|
-
collector <<
|
486
|
+
collector << ')'
|
465
487
|
collector
|
466
488
|
end
|
467
489
|
|
468
490
|
# add primary_key if not present, avoid zip
|
469
491
|
if Arel::VERSION.to_i < 7
|
470
492
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
471
|
-
collector <<
|
493
|
+
collector << '('
|
472
494
|
o.left.each_with_index do |row, idx| # values
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
495
|
+
collector << ' UNION ALL ' if idx != 0
|
496
|
+
collector << '(SELECT '
|
497
|
+
len = row.length - 1
|
498
|
+
row.zip(o.cols).each_with_index { |(value, attr), i|
|
477
499
|
case value
|
478
500
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
479
501
|
collector = visit value, collector
|
@@ -481,18 +503,18 @@ module ArelExtensions
|
|
481
503
|
collector << quote(value, attr && column_for(attr)).to_s
|
482
504
|
end
|
483
505
|
collector << COMMA unless i == len
|
484
|
-
|
485
|
-
|
506
|
+
}
|
507
|
+
collector << ' FROM DUAL)'
|
486
508
|
end
|
487
|
-
collector <<
|
509
|
+
collector << ')'
|
488
510
|
collector
|
489
511
|
end
|
490
512
|
else
|
491
513
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
492
|
-
collector <<
|
514
|
+
collector << '('
|
493
515
|
o.left.each_with_index do |row, idx|
|
494
|
-
collector <<
|
495
|
-
collector <<
|
516
|
+
collector << ' UNION ALL ' if idx != 0
|
517
|
+
collector << '(SELECT '
|
496
518
|
len = row.length - 1
|
497
519
|
row.zip(o.cols).each_with_index { |(value, attr), i|
|
498
520
|
case value
|
@@ -507,7 +529,7 @@ module ArelExtensions
|
|
507
529
|
}
|
508
530
|
collector << ' FROM DUAL)'
|
509
531
|
end
|
510
|
-
collector <<
|
532
|
+
collector << ')'
|
511
533
|
collector
|
512
534
|
end
|
513
535
|
end
|
@@ -517,7 +539,7 @@ module ArelExtensions
|
|
517
539
|
if element.is_a?(Time)
|
518
540
|
ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
|
519
541
|
elsif element.is_a?(Arel::Attributes::Attribute)
|
520
|
-
col = Arel
|
542
|
+
col = Arel.column_of(element.relation.table_name, element.name.to_s)
|
521
543
|
if col && (col.type == :time)
|
522
544
|
ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
|
523
545
|
else
|
@@ -532,7 +554,7 @@ module ArelExtensions
|
|
532
554
|
remove_method(:visit_Arel_Nodes_GreaterThanOrEqual) rescue nil
|
533
555
|
def visit_Arel_Nodes_GreaterThanOrEqual o, collector
|
534
556
|
collector = visit get_time_converted(o.left), collector
|
535
|
-
collector <<
|
557
|
+
collector << ' >= '
|
536
558
|
collector = visit get_time_converted(o.right), collector
|
537
559
|
collector
|
538
560
|
end
|
@@ -540,7 +562,7 @@ module ArelExtensions
|
|
540
562
|
remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
|
541
563
|
def visit_Arel_Nodes_GreaterThan o, collector
|
542
564
|
collector = visit get_time_converted(o.left), collector
|
543
|
-
collector <<
|
565
|
+
collector << ' > '
|
544
566
|
collector = visit get_time_converted(o.right), collector
|
545
567
|
collector
|
546
568
|
end
|
@@ -548,7 +570,7 @@ module ArelExtensions
|
|
548
570
|
remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
|
549
571
|
def visit_Arel_Nodes_LessThanOrEqual o, collector
|
550
572
|
collector = visit get_time_converted(o.left), collector
|
551
|
-
collector <<
|
573
|
+
collector << ' <= '
|
552
574
|
collector = visit get_time_converted(o.right), collector
|
553
575
|
collector
|
554
576
|
end
|
@@ -556,7 +578,7 @@ module ArelExtensions
|
|
556
578
|
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
557
579
|
def visit_Arel_Nodes_LessThan o, collector
|
558
580
|
collector = visit get_time_converted(o.left), collector
|
559
|
-
collector <<
|
581
|
+
collector << ' < '
|
560
582
|
collector = visit get_time_converted(o.right), collector
|
561
583
|
collector
|
562
584
|
end
|
@@ -568,15 +590,15 @@ module ArelExtensions
|
|
568
590
|
o = o.dup
|
569
591
|
o.orders = []
|
570
592
|
end
|
571
|
-
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
593
|
+
old_visit_Arel_Nodes_SelectStatement(o, collector)
|
572
594
|
end
|
573
595
|
|
574
596
|
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
575
597
|
def visit_Arel_Nodes_TableAlias o, collector
|
576
598
|
if o.name.length > 30
|
577
|
-
o = Arel::Table.new(o.table_name).alias(
|
599
|
+
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
578
600
|
end
|
579
|
-
old_visit_Arel_Nodes_TableAlias(o,collector)
|
601
|
+
old_visit_Arel_Nodes_TableAlias(o, collector)
|
580
602
|
end
|
581
603
|
|
582
604
|
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
@@ -588,7 +610,7 @@ module ArelExtensions
|
|
588
610
|
else
|
589
611
|
collector = visit o.left, collector
|
590
612
|
end
|
591
|
-
quote =
|
613
|
+
quote = /(\A".*"\z)|\A[a-zA-Z_]*\z/.match?(o.right.to_s) ? '' : '"'
|
592
614
|
collector << " AS #{quote}"
|
593
615
|
collector = visit o.right, collector
|
594
616
|
collector << "#{quote}"
|
@@ -612,47 +634,52 @@ module ArelExtensions
|
|
612
634
|
col = o.left.coalesce(0)
|
613
635
|
comma = NUMBER_COMMA_MAPPING[o.locale] || '.,'
|
614
636
|
comma_in_format = o.precision == 0 ? '' : 'D'
|
615
|
-
nines_after = (1..o.precision-1).map{'9'}.join('')+'0'
|
637
|
+
nines_after = (1..o.precision - 1).map{'9'}.join('') + '0'
|
616
638
|
if comma.length == 1
|
617
|
-
options = Arel
|
618
|
-
nines_before = (
|
639
|
+
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma} '")
|
640
|
+
nines_before = ('999' * 4 + '990')
|
619
641
|
else
|
620
|
-
options = Arel
|
621
|
-
nines_before = (
|
642
|
+
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma}'")
|
643
|
+
nines_before = ('999G' * 4 + '990')
|
622
644
|
end
|
623
|
-
sign =
|
645
|
+
sign = Arel.when(col < 0).
|
624
646
|
then('-').
|
625
647
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
626
648
|
sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
|
627
|
-
Arel
|
628
|
-
|
649
|
+
Arel.quoted(1) :
|
650
|
+
Arel.when(col < 0).then(1).else(0)
|
629
651
|
|
630
652
|
if o.scientific_notation
|
631
|
-
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
632
|
-
Arel
|
633
|
-
Arel
|
653
|
+
number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
654
|
+
Arel.quoted(col.abs),
|
655
|
+
Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}EEEE"),
|
634
656
|
options
|
635
657
|
])
|
636
658
|
if o.type == 'e'
|
637
|
-
number = number.replace('E','e')
|
659
|
+
number = number.replace('E', 'e')
|
638
660
|
end
|
639
661
|
else
|
640
|
-
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
641
|
-
Arel
|
642
|
-
Arel
|
662
|
+
number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
663
|
+
Arel.quoted(col.abs),
|
664
|
+
Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}"),
|
643
665
|
options
|
644
666
|
])
|
645
667
|
end
|
646
668
|
|
647
|
-
repeated_char =
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
669
|
+
repeated_char =
|
670
|
+
if o.width == 0
|
671
|
+
Arel.quoted('')
|
672
|
+
else
|
673
|
+
Arel
|
674
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
675
|
+
.then(Arel.quoted(
|
676
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
677
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
678
|
+
)
|
679
|
+
.else('')
|
680
|
+
end
|
681
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
682
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
656
683
|
after = o.flags.include?('-') ? repeated_char : ''
|
657
684
|
full_number = ArelExtensions::Nodes::Concat.new([
|
658
685
|
before,
|
@@ -661,32 +688,44 @@ module ArelExtensions
|
|
661
688
|
number,
|
662
689
|
after
|
663
690
|
])
|
664
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel
|
691
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
|
665
692
|
collector
|
666
693
|
end
|
667
694
|
|
668
695
|
def visit_ArelExtensions_Nodes_Std o, collector
|
669
|
-
collector << (o.unbiased_estimator ?
|
696
|
+
collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
|
670
697
|
visit o.left, collector
|
671
|
-
collector <<
|
698
|
+
collector << ')'
|
672
699
|
collector
|
673
700
|
end
|
674
701
|
|
675
702
|
def visit_ArelExtensions_Nodes_Variance o, collector
|
676
|
-
collector << (o.unbiased_estimator ?
|
703
|
+
collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
|
677
704
|
visit o.left, collector
|
678
|
-
collector <<
|
705
|
+
collector << ')'
|
679
706
|
collector
|
680
707
|
end
|
681
708
|
|
682
709
|
def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
|
683
|
-
collector <<
|
710
|
+
collector << 'UTL_MATCH.edit_distance('
|
684
711
|
collector = visit o.left, collector
|
685
712
|
collector << Arel::Visitors::ToSql::COMMA
|
686
713
|
collector = visit o.right, collector
|
687
714
|
collector << ')'
|
688
715
|
collector
|
689
716
|
end
|
717
|
+
|
718
|
+
# Utilized by GroupingSet, Cube & RollUp visitors to
|
719
|
+
# handle grouping aggregation semantics
|
720
|
+
def grouping_array_or_grouping_element(o, collector)
|
721
|
+
if o.expr.is_a? Array
|
722
|
+
collector << "( "
|
723
|
+
visit o.expr, collector
|
724
|
+
collector << " )"
|
725
|
+
else
|
726
|
+
visit o.expr, collector
|
727
|
+
end
|
728
|
+
end
|
690
729
|
end
|
691
730
|
end
|
692
731
|
end
|