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
@@ -8,10 +8,11 @@ module ArelExtensions
|
|
8
8
|
|
9
9
|
DATE_FORMAT_DIRECTIVES = {
|
10
10
|
'%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY',
|
11
|
-
'%m' => 'MM', '%B' => '
|
12
|
-
'%
|
13
|
-
'%
|
14
|
-
'%
|
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
|
15
16
|
'%%' => '%',
|
16
17
|
}.freeze
|
17
18
|
|
@@ -20,33 +21,33 @@ module ArelExtensions
|
|
20
21
|
}.freeze
|
21
22
|
|
22
23
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
23
|
-
collector <<
|
24
|
+
collector << 'RANDOM('
|
24
25
|
if (o.left != nil && o.right != nil)
|
25
26
|
collector = visit o.left, collector
|
26
27
|
collector << COMMA
|
27
28
|
collector = isit o.right, collector
|
28
29
|
end
|
29
|
-
collector <<
|
30
|
+
collector << ')'
|
30
31
|
collector
|
31
32
|
end
|
32
33
|
|
33
34
|
def visit_ArelExtensions_Nodes_Power o, collector
|
34
|
-
collector <<
|
35
|
+
collector << 'POWER('
|
35
36
|
o.expressions.each_with_index { |arg, i|
|
36
37
|
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
37
38
|
collector = visit arg, collector
|
38
39
|
}
|
39
|
-
collector <<
|
40
|
+
collector << ')'
|
40
41
|
collector
|
41
42
|
end
|
42
43
|
|
43
44
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
44
|
-
collector <<
|
45
|
+
collector << 'LOG('
|
45
46
|
o.expressions.each_with_index { |arg, i|
|
46
47
|
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
47
48
|
collector = visit arg, collector
|
48
49
|
}
|
49
|
-
collector <<
|
50
|
+
collector << ')'
|
50
51
|
collector
|
51
52
|
end
|
52
53
|
|
@@ -54,7 +55,7 @@ module ArelExtensions
|
|
54
55
|
remove_method(:visit_Arel_Nodes_Regexp) rescue nil
|
55
56
|
def visit_Arel_Nodes_Regexp o, collector
|
56
57
|
collector = visit o.left, collector
|
57
|
-
collector <<
|
58
|
+
collector << ' ~ '
|
58
59
|
collector = visit o.right, collector
|
59
60
|
collector
|
60
61
|
end
|
@@ -62,7 +63,7 @@ module ArelExtensions
|
|
62
63
|
remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
|
63
64
|
def visit_Arel_Nodes_NotRegexp o, collector
|
64
65
|
collector = visit o.left, collector
|
65
|
-
collector <<
|
66
|
+
collector << ' !~ '
|
66
67
|
collector = visit o.right, collector
|
67
68
|
collector
|
68
69
|
end
|
@@ -73,7 +74,7 @@ module ArelExtensions
|
|
73
74
|
collector = visit arg, collector
|
74
75
|
collector << ' || ' unless i == o.expressions.length - 1
|
75
76
|
}
|
76
|
-
collector <<
|
77
|
+
collector << ')'
|
77
78
|
collector
|
78
79
|
end
|
79
80
|
|
@@ -86,46 +87,52 @@ module ArelExtensions
|
|
86
87
|
else
|
87
88
|
collector = visit o.left, collector
|
88
89
|
end
|
89
|
-
collector <<
|
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
|
90
96
|
collector = visit o.right, collector
|
91
|
-
collector << "
|
97
|
+
collector << '"' if quote
|
98
|
+
|
92
99
|
collector
|
93
100
|
end
|
94
101
|
|
95
102
|
def visit_Aggregate_For_AggregateFunction o, collector
|
96
103
|
if !o.order.blank? || !o.group.blank?
|
97
|
-
collector <<
|
104
|
+
collector << ' OVER ('
|
98
105
|
if !o.group.blank?
|
99
|
-
collector <<
|
106
|
+
collector << ' PARTITION BY '
|
100
107
|
o.group.each_with_index do |group, i|
|
101
108
|
collector << COMMA if i != 0
|
102
109
|
visit group, collector
|
103
110
|
end
|
104
111
|
end
|
105
112
|
if !o.order.blank?
|
106
|
-
collector <<
|
113
|
+
collector << ' ORDER BY '
|
107
114
|
o.order.each_with_index do |order, i|
|
108
115
|
collector << COMMA if i != 0
|
109
116
|
visit order, collector
|
110
117
|
end
|
111
118
|
end
|
112
|
-
collector <<
|
119
|
+
collector << ')'
|
113
120
|
end
|
114
121
|
collector
|
115
122
|
end
|
116
123
|
|
117
124
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
118
|
-
collector <<
|
125
|
+
collector << 'array_to_string(array_agg('
|
119
126
|
collector = visit o.left, collector
|
120
127
|
if o.order && !o.order.blank?
|
121
|
-
collector <<
|
128
|
+
collector << ' ORDER BY'
|
122
129
|
o.order.each_with_index do |order, i|
|
123
130
|
collector << COMMA if i != 0
|
124
|
-
collector <<
|
131
|
+
collector << ' '
|
125
132
|
visit order, collector
|
126
133
|
end
|
127
134
|
end
|
128
|
-
collector <<
|
135
|
+
collector << ')'
|
129
136
|
o.order = nil
|
130
137
|
visit_Aggregate_For_AggregateFunction o, collector
|
131
138
|
collector << COMMA
|
@@ -133,56 +140,72 @@ module ArelExtensions
|
|
133
140
|
if o.separator && o.separator != 'NULL'
|
134
141
|
visit o.separator, collector
|
135
142
|
else
|
136
|
-
visit Arel
|
143
|
+
visit Arel.quoted(','), collector
|
137
144
|
end
|
138
|
-
collector <<
|
145
|
+
collector << ')'
|
139
146
|
collector
|
140
147
|
end
|
141
148
|
|
142
149
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
150
|
+
collector << 'TRIM(BOTH '
|
151
|
+
collector = visit o.right, collector
|
152
|
+
collector << ' FROM '
|
153
|
+
collector = visit o.left, collector
|
154
|
+
collector << ')'
|
155
|
+
collector
|
149
156
|
end
|
150
157
|
|
151
158
|
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
159
|
+
collector << 'TRIM(LEADING '
|
160
|
+
collector = visit o.right, collector
|
161
|
+
collector << ' FROM '
|
162
|
+
collector = visit o.left, collector
|
163
|
+
collector << ')'
|
164
|
+
collector
|
158
165
|
end
|
159
166
|
|
160
167
|
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
161
168
|
collector << 'TRIM(TRAILING '
|
162
169
|
collector = visit o.right, collector
|
163
|
-
collector <<
|
170
|
+
collector << ' FROM '
|
164
171
|
collector = visit o.left, collector
|
165
|
-
collector <<
|
172
|
+
collector << ')'
|
166
173
|
collector
|
167
174
|
end
|
168
175
|
|
169
176
|
def visit_ArelExtensions_Nodes_Format o, collector
|
177
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
178
|
+
end
|
179
|
+
|
180
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
170
181
|
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
171
|
-
collector <<
|
182
|
+
collector << 'TO_CHAR('
|
183
|
+
collector << '(' if o.time_zone
|
172
184
|
collector = visit o.left, collector
|
185
|
+
case o.time_zone
|
186
|
+
when Hash
|
187
|
+
src_tz, dst_tz = o.time_zone.first
|
188
|
+
collector << ') AT TIME ZONE '
|
189
|
+
collector = visit Arel.quoted(src_tz), collector
|
190
|
+
collector << ' AT TIME ZONE '
|
191
|
+
collector = visit Arel.quoted(dst_tz), collector
|
192
|
+
when String
|
193
|
+
collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
|
194
|
+
collector = visit Arel.quoted(o.time_zone), collector
|
195
|
+
end
|
173
196
|
collector << COMMA
|
174
|
-
collector = visit Arel
|
175
|
-
collector <<
|
197
|
+
collector = visit Arel.quoted(fmt), collector
|
198
|
+
collector << ')'
|
176
199
|
collector
|
177
200
|
end
|
178
201
|
|
179
202
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
180
|
-
collector <<
|
203
|
+
collector << 'REPEAT('
|
181
204
|
o.expressions.each_with_index { |arg, i|
|
182
205
|
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
183
206
|
collector = visit arg, collector
|
184
207
|
}
|
185
|
-
collector <<
|
208
|
+
collector << ')'
|
186
209
|
collector
|
187
210
|
end
|
188
211
|
|
@@ -224,9 +247,9 @@ module ArelExtensions
|
|
224
247
|
|
225
248
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
226
249
|
if o.ai
|
227
|
-
collector <<
|
250
|
+
collector << 'unaccent('
|
228
251
|
collector = visit o.expressions.first, collector
|
229
|
-
collector <<
|
252
|
+
collector << ')'
|
230
253
|
elsif o.ci
|
231
254
|
collector = visit o.expressions.first, collector
|
232
255
|
else
|
@@ -245,16 +268,16 @@ module ArelExtensions
|
|
245
268
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
246
269
|
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
|
247
270
|
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
248
|
-
|
271
|
+
"DATEDIFF('second', "
|
249
272
|
else
|
250
|
-
|
273
|
+
"DATEDIFF('day', "
|
251
274
|
end
|
252
275
|
collector = visit o.right, collector
|
253
276
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
254
277
|
collector << COMMA
|
255
278
|
collector = visit o.left, collector
|
256
279
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
257
|
-
collector <<
|
280
|
+
collector << ')'
|
258
281
|
else
|
259
282
|
collector << '('
|
260
283
|
collector = visit o.left, collector
|
@@ -271,57 +294,57 @@ module ArelExtensions
|
|
271
294
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
272
295
|
if o.with_interval
|
273
296
|
interval = case o.left
|
274
|
-
when 'd','m','y'
|
297
|
+
when 'd', 'm', 'y'
|
275
298
|
'DAY'
|
276
|
-
when 'h','mn','s'
|
299
|
+
when 'h', 'mn', 's'
|
277
300
|
'SECOND'
|
278
301
|
when /i\z/
|
279
|
-
collector <<
|
302
|
+
collector << '('
|
280
303
|
collector = visit o.right, collector
|
281
|
-
collector <<
|
304
|
+
collector << ')'
|
282
305
|
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
283
306
|
return collector
|
284
307
|
end
|
285
308
|
end
|
286
|
-
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
|
309
|
+
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM CAST("
|
287
310
|
collector = visit o.right, collector
|
288
|
-
collector <<
|
311
|
+
collector << ' AS TIMESTAMP WITH TIME ZONE))'
|
289
312
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
290
313
|
collector
|
291
314
|
end
|
292
315
|
|
293
316
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
294
|
-
collector <<
|
317
|
+
collector << 'POSITION('
|
295
318
|
collector = visit o.right, collector
|
296
|
-
collector <<
|
319
|
+
collector << ' IN '
|
297
320
|
collector = visit o.left, collector
|
298
|
-
collector <<
|
321
|
+
collector << ')'
|
299
322
|
collector
|
300
323
|
end
|
301
324
|
|
302
325
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
303
|
-
collector <<
|
326
|
+
collector << 'SUBSTR('
|
304
327
|
o.expressions.each_with_index { |arg, i|
|
305
328
|
collector << COMMA if i != 0
|
306
329
|
collector = visit arg, collector
|
307
330
|
}
|
308
|
-
collector <<
|
331
|
+
collector << ')'
|
309
332
|
collector
|
310
333
|
end
|
311
334
|
|
312
335
|
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
313
|
-
collector <<
|
336
|
+
collector << 'REGEXP_REPLACE('
|
314
337
|
visit o.left, collector
|
315
338
|
collector << Arel::Visitors::ToSql::COMMA
|
316
|
-
tab = o.pattern.inspect+ 'g' # Make it always global
|
339
|
+
tab = o.pattern.inspect + 'g' # Make it always global
|
317
340
|
pattern = tab.split('/')[1..-2].join('/')
|
318
341
|
flags = tab.split('/')[-1]
|
319
|
-
visit Arel
|
342
|
+
visit Arel.quoted(pattern), collector
|
320
343
|
collector << Arel::Visitors::ToSql::COMMA
|
321
344
|
visit o.substitute, collector
|
322
345
|
collector << Arel::Visitors::ToSql::COMMA
|
323
|
-
visit Arel
|
324
|
-
collector <<
|
346
|
+
visit Arel.quoted(flags + 'g'), collector
|
347
|
+
collector << ')'
|
325
348
|
collector
|
326
349
|
end
|
327
350
|
|
@@ -332,55 +355,59 @@ module ArelExtensions
|
|
332
355
|
end
|
333
356
|
|
334
357
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
335
|
-
|
358
|
+
collector = visit o.expr, collector
|
336
359
|
collector << ' IS NOT NULL'
|
337
360
|
collector
|
338
361
|
end
|
339
362
|
|
340
363
|
def visit_ArelExtensions_Nodes_Sum o, collector
|
341
|
-
collector <<
|
364
|
+
collector << 'sum('
|
342
365
|
collector = visit o.expr, collector
|
343
|
-
collector <<
|
366
|
+
collector << ')'
|
344
367
|
visit_Aggregate_For_AggregateFunction o, collector
|
345
368
|
collector
|
346
369
|
end
|
347
370
|
|
348
371
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
349
|
-
collector <<
|
372
|
+
collector << 'EXRTACT(DOW, '
|
350
373
|
collector = visit o.date, collector
|
351
374
|
collector << ')'
|
352
375
|
collector
|
353
376
|
end
|
354
377
|
|
355
378
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
356
|
-
as_attr =
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
379
|
+
as_attr =
|
380
|
+
case o.as_attr
|
381
|
+
when :string
|
382
|
+
'varchar'
|
383
|
+
when :text, :ntext
|
384
|
+
'text'
|
385
|
+
when :time
|
386
|
+
'time'
|
387
|
+
when :int
|
388
|
+
collector << 'CAST(CAST('
|
389
|
+
collector = visit o.left, collector
|
390
|
+
collector << ' AS numeric) AS int)'
|
391
|
+
return collector
|
392
|
+
when :number, :decimal, :float
|
393
|
+
'numeric'
|
394
|
+
when :datetime
|
395
|
+
'timestamp without time zone'
|
396
|
+
when :date
|
397
|
+
'date'
|
398
|
+
when :binary
|
399
|
+
'binary'
|
400
|
+
when :jsonb
|
401
|
+
'jsonb'
|
402
|
+
else
|
403
|
+
o.as_attr.to_s
|
404
|
+
end
|
405
|
+
|
406
|
+
collector << 'CAST('
|
380
407
|
collector = visit o.left, collector
|
381
|
-
collector <<
|
382
|
-
collector = visit as_attr, collector
|
383
|
-
collector <<
|
408
|
+
collector << ' AS '
|
409
|
+
collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
|
410
|
+
collector << ')'
|
384
411
|
collector
|
385
412
|
end
|
386
413
|
|
@@ -389,9 +416,9 @@ module ArelExtensions
|
|
389
416
|
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
390
417
|
thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
|
391
418
|
nines_after = (1..o.precision).map{'9'}.join('')
|
392
|
-
nines_before = ("999#{thousand_separator}"*4+
|
419
|
+
nines_before = ("999#{thousand_separator}" * 4 + '990')
|
393
420
|
|
394
|
-
sign =
|
421
|
+
sign = Arel.when(col < 0).
|
395
422
|
then('-').
|
396
423
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
397
424
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
@@ -399,35 +426,40 @@ module ArelExtensions
|
|
399
426
|
number =
|
400
427
|
if o.scientific_notation
|
401
428
|
ArelExtensions::Nodes::Concat.new([
|
402
|
-
Arel::Nodes::NamedFunction.new('TRIM',[
|
403
|
-
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
404
|
-
col.abs/Arel
|
405
|
-
Arel
|
429
|
+
Arel::Nodes::NamedFunction.new('TRIM', [
|
430
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
431
|
+
Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
|
432
|
+
Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
|
406
433
|
])]),
|
407
434
|
o.type,
|
408
|
-
Arel::Nodes::NamedFunction.new('TRIM',[
|
409
|
-
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
410
|
-
col.abs.log10.floor,
|
411
|
-
Arel
|
435
|
+
Arel::Nodes::NamedFunction.new('TRIM', [
|
436
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
437
|
+
Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
|
438
|
+
Arel.quoted("FM#{nines_before}")
|
412
439
|
])])
|
413
440
|
])
|
414
441
|
else
|
415
|
-
Arel::Nodes::NamedFunction.new('TRIM',[
|
416
|
-
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
417
|
-
Arel
|
418
|
-
Arel
|
442
|
+
Arel::Nodes::NamedFunction.new('TRIM', [
|
443
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
444
|
+
Arel.quoted(col.abs),
|
445
|
+
Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
|
419
446
|
])])
|
420
447
|
end
|
421
448
|
|
422
|
-
repeated_char =
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
449
|
+
repeated_char =
|
450
|
+
if o.width == 0
|
451
|
+
Arel.quoted('')
|
452
|
+
else
|
453
|
+
Arel
|
454
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
455
|
+
.then(Arel.quoted(
|
456
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
457
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
458
|
+
)
|
459
|
+
.else('')
|
460
|
+
end
|
461
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
462
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
431
463
|
after = o.flags.include?('-') ? repeated_char : ''
|
432
464
|
full_number = ArelExtensions::Nodes::Concat.new([
|
433
465
|
before,
|
@@ -436,7 +468,7 @@ module ArelExtensions
|
|
436
468
|
number,
|
437
469
|
after
|
438
470
|
])
|
439
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel
|
471
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
|
440
472
|
collector
|
441
473
|
end
|
442
474
|
|
@@ -448,7 +480,7 @@ module ArelExtensions
|
|
448
480
|
o = o.dup
|
449
481
|
o.orders = []
|
450
482
|
end
|
451
|
-
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
483
|
+
old_visit_Arel_Nodes_SelectStatement(o, collector)
|
452
484
|
end
|
453
485
|
|
454
486
|
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
@@ -456,7 +488,7 @@ module ArelExtensions
|
|
456
488
|
if o.name.length > 63
|
457
489
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
458
490
|
end
|
459
|
-
old_visit_Arel_Nodes_TableAlias(o,collector)
|
491
|
+
old_visit_Arel_Nodes_TableAlias(o, collector)
|
460
492
|
end
|
461
493
|
|
462
494
|
alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
|
@@ -469,26 +501,26 @@ module ArelExtensions
|
|
469
501
|
end
|
470
502
|
|
471
503
|
def visit_ArelExtensions_Nodes_Std o, collector
|
472
|
-
collector << (o.unbiased_estimator ?
|
504
|
+
collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
|
473
505
|
visit o.left, collector
|
474
|
-
collector <<
|
506
|
+
collector << ')'
|
475
507
|
visit_Aggregate_For_AggregateFunction o, collector
|
476
508
|
collector
|
477
509
|
end
|
478
510
|
|
479
511
|
def visit_ArelExtensions_Nodes_Variance o, collector
|
480
|
-
collector << (o.unbiased_estimator ?
|
512
|
+
collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
|
481
513
|
visit o.left, collector
|
482
|
-
collector <<
|
514
|
+
collector << ')'
|
483
515
|
visit_Aggregate_For_AggregateFunction o, collector
|
484
516
|
collector
|
485
517
|
end
|
486
518
|
|
487
|
-
def visit_ArelExtensions_Nodes_Json o,collector
|
519
|
+
def visit_ArelExtensions_Nodes_Json o, collector
|
488
520
|
case o.dict
|
489
521
|
when Array
|
490
522
|
collector << 'to_jsonb(array['
|
491
|
-
o.dict.each.with_index do |v,i|
|
523
|
+
o.dict.each.with_index do |v, i|
|
492
524
|
if i != 0
|
493
525
|
collector << Arel::Visitors::MySQL::COMMA
|
494
526
|
end
|
@@ -497,7 +529,7 @@ module ArelExtensions
|
|
497
529
|
collector << '])'
|
498
530
|
when Hash
|
499
531
|
collector << 'jsonb_build_object('
|
500
|
-
o.dict.each.with_index do |(k,v),i|
|
532
|
+
o.dict.each.with_index do |(k, v), i|
|
501
533
|
if i != 0
|
502
534
|
collector << Arel::Visitors::MySQL::COMMA
|
503
535
|
end
|
@@ -506,13 +538,11 @@ module ArelExtensions
|
|
506
538
|
collector = visit v, collector
|
507
539
|
end
|
508
540
|
collector << ')'
|
509
|
-
when String,Numeric,TrueClass,FalseClass
|
510
|
-
collector = visit Arel
|
541
|
+
when String, Numeric, TrueClass, FalseClass
|
542
|
+
collector = visit Arel.quoted("#{o.dict}"), collector
|
511
543
|
collector << '::jsonb'
|
512
544
|
when NilClass
|
513
|
-
collector
|
514
|
-
when Arel::Attributes::Attribute
|
515
|
-
collector = visit o.dict.cast(:jsonb), collector
|
545
|
+
collector << %Q['null'::jsonb]
|
516
546
|
else
|
517
547
|
collector = visit o.dict, collector
|
518
548
|
collector << '::jsonb'
|
@@ -520,8 +550,8 @@ module ArelExtensions
|
|
520
550
|
collector
|
521
551
|
end
|
522
552
|
|
523
|
-
def visit_ArelExtensions_Nodes_JsonMerge o,collector
|
524
|
-
o.expressions.each.with_index do |v,i|
|
553
|
+
def visit_ArelExtensions_Nodes_JsonMerge o, collector
|
554
|
+
o.expressions.each.with_index do |v, i|
|
525
555
|
if i != 0
|
526
556
|
collector << ' || '
|
527
557
|
end
|
@@ -530,14 +560,14 @@ module ArelExtensions
|
|
530
560
|
collector
|
531
561
|
end
|
532
562
|
|
533
|
-
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
563
|
+
def visit_ArelExtensions_Nodes_JsonGet o, collector
|
534
564
|
collector = visit o.dict, collector
|
535
|
-
collector << '
|
565
|
+
collector << ' ->> '
|
536
566
|
collector = visit o.key, collector
|
537
567
|
collector
|
538
568
|
end
|
539
569
|
|
540
|
-
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
570
|
+
def visit_ArelExtensions_Nodes_JsonSet o, collector
|
541
571
|
collector << 'jsonb_set('
|
542
572
|
collector = visit o.dict, collector
|
543
573
|
collector << Arel::Visitors::MySQL::COMMA
|
@@ -559,7 +589,7 @@ module ArelExtensions
|
|
559
589
|
else
|
560
590
|
case o.dict
|
561
591
|
when Hash
|
562
|
-
o.dict.each.with_index do |(k,v),i|
|
592
|
+
o.dict.each.with_index do |(k, v), i|
|
563
593
|
if i != 0
|
564
594
|
collector << ' || '
|
565
595
|
end
|