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