arel_extensions 1.3.9 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- 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 +90 -282
- data/Rakefile +30 -48
- data/TODO +1 -0
- data/appveyor.yml +22 -60
- data/arel_extensions.gemspec +14 -13
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4.gemfile +29 -0
- data/gemfiles/rails5_0.gemfile +29 -0
- 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 +13 -17
- 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 +19 -20
- 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 -52
- 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 +5 -19
- 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 -59
- 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 +180 -375
- data/lib/arel_extensions/visitors/mysql.rb +212 -350
- data/lib/arel_extensions/visitors/oracle.rb +178 -220
- data/lib/arel_extensions/visitors/oracle12.rb +31 -18
- data/lib/arel_extensions/visitors/postgresql.rb +173 -256
- data/lib/arel_extensions/visitors/sqlite.rb +126 -140
- data/lib/arel_extensions/visitors/to_sql.rb +237 -298
- data/lib/arel_extensions/visitors.rb +58 -82
- data/lib/arel_extensions.rb +31 -202
- 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 +365 -709
- 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 +34 -37
- data/.github/workflows/publish.yml +0 -29
- data/.github/workflows/release.yml +0 -30
- data/.github/workflows/ruby.yml +0 -345
- data/NEWS.md +0 -62
- data/bin/build +0 -15
- data/bin/publish +0 -8
- data/dev/compose.yaml +0 -29
- data/gemfiles/rails4_2.gemfile +0 -38
- data/gemfiles/rails5.gemfile +0 -29
- data/gemfiles/rails6.gemfile +0 -30
- data/gemfiles/rails6_1.gemfile +0 -30
- data/gemfiles/rails7.gemfile +0 -23
- data/gemfiles/rails7_1.gemfile +0 -22
- data/gemspecs/arel_extensions-v1.gemspec +0 -27
- data/gemspecs/arel_extensions-v2.gemspec +0 -27
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/aliases.rb +0 -14
- data/lib/arel_extensions/helpers.rb +0 -57
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
- data/lib/arel_extensions/nodes/rollup.rb +0 -36
- data/lib/arel_extensions/nodes/select.rb +0 -10
- 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 -67
- data/version_v1.rb +0 -3
- data/version_v2.rb +0 -3
@@ -1,53 +1,43 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
|
-
DATE_MAPPING = {
|
5
|
-
|
6
|
-
'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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 <<
|
25
|
-
if
|
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 <<
|
25
|
+
collector << "POWER("
|
36
26
|
o.expressions.each_with_index { |arg, i|
|
37
|
-
collector << Arel::Visitors::ToSql::COMMA
|
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 <<
|
35
|
+
collector << "LOG("
|
46
36
|
o.expressions.each_with_index { |arg, i|
|
47
|
-
collector << Arel::Visitors::ToSql::COMMA
|
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
|
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,125 +77,80 @@ module ArelExtensions
|
|
87
77
|
else
|
88
78
|
collector = visit o.left, collector
|
89
79
|
end
|
90
|
-
collector <<
|
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 <<
|
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 <<
|
87
|
+
collector << "array_to_string(array_agg("
|
126
88
|
collector = visit o.left, collector
|
127
|
-
if
|
128
|
-
collector << ' ORDER BY'
|
129
|
-
o.
|
130
|
-
collector << COMMA
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
visit Arel.quoted(','), collector
|
144
|
-
end
|
145
|
-
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 << ")"
|
146
104
|
collector
|
147
105
|
end
|
148
106
|
|
149
107
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
108
|
+
collector << 'TRIM(BOTH '
|
109
|
+
collector = visit o.right, collector
|
110
|
+
collector << " FROM "
|
111
|
+
collector = visit o.left, collector
|
112
|
+
collector << ")"
|
113
|
+
collector
|
156
114
|
end
|
157
115
|
|
158
116
|
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
117
|
+
collector << 'TRIM(LEADING '
|
118
|
+
collector = visit o.right, collector
|
119
|
+
collector << " FROM "
|
120
|
+
collector = visit o.left, collector
|
121
|
+
collector << ")"
|
122
|
+
collector
|
165
123
|
end
|
166
124
|
|
167
125
|
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
168
126
|
collector << 'TRIM(TRAILING '
|
169
127
|
collector = visit o.right, collector
|
170
|
-
collector <<
|
128
|
+
collector << " FROM "
|
171
129
|
collector = visit o.left, collector
|
172
|
-
collector <<
|
130
|
+
collector << ")"
|
173
131
|
collector
|
174
132
|
end
|
175
133
|
|
176
134
|
def visit_ArelExtensions_Nodes_Format o, collector
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
|
-
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
181
|
-
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
182
|
-
collector << 'TO_CHAR('
|
183
|
-
collector << '(' if o.time_zone
|
135
|
+
collector << "TO_CHAR("
|
184
136
|
collector = visit o.left, collector
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
when String
|
193
|
-
collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
|
194
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
195
|
-
end
|
196
|
-
collector << COMMA
|
197
|
-
collector = visit Arel.quoted(fmt), collector
|
198
|
-
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 << ")"
|
199
144
|
collector
|
200
145
|
end
|
201
146
|
|
202
147
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
203
|
-
collector <<
|
148
|
+
collector << "REPEAT("
|
204
149
|
o.expressions.each_with_index { |arg, i|
|
205
|
-
collector << Arel::Visitors::ToSql::COMMA
|
150
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
206
151
|
collector = visit arg, collector
|
207
152
|
}
|
208
|
-
collector <<
|
153
|
+
collector << ")"
|
209
154
|
collector
|
210
155
|
end
|
211
156
|
|
@@ -247,9 +192,9 @@ module ArelExtensions
|
|
247
192
|
|
248
193
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
249
194
|
if o.ai
|
250
|
-
collector <<
|
195
|
+
collector << "unaccent("
|
251
196
|
collector = visit o.expressions.first, collector
|
252
|
-
collector <<
|
197
|
+
collector << ")"
|
253
198
|
elsif o.ci
|
254
199
|
collector = visit o.expressions.first, collector
|
255
200
|
else
|
@@ -260,7 +205,7 @@ module ArelExtensions
|
|
260
205
|
|
261
206
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
262
207
|
collector = visit o.left, collector
|
263
|
-
collector << ' + ' #
|
208
|
+
collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
|
264
209
|
collector = visit o.postgresql_value(o.right), collector
|
265
210
|
collector
|
266
211
|
end
|
@@ -268,16 +213,16 @@ module ArelExtensions
|
|
268
213
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
269
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
|
270
215
|
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
271
|
-
|
216
|
+
"DATEDIFF('second', "
|
272
217
|
else
|
273
|
-
|
218
|
+
"DATEDIFF('day', "
|
274
219
|
end
|
275
220
|
collector = visit o.right, collector
|
276
221
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
277
|
-
collector << COMMA
|
222
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
278
223
|
collector = visit o.left, collector
|
279
224
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
280
|
-
collector <<
|
225
|
+
collector << ")"
|
281
226
|
else
|
282
227
|
collector << '('
|
283
228
|
collector = visit o.left, collector
|
@@ -294,57 +239,41 @@ module ArelExtensions
|
|
294
239
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
295
240
|
if o.with_interval
|
296
241
|
interval = case o.left
|
297
|
-
when 'd',
|
242
|
+
when 'd','m','y'
|
298
243
|
'DAY'
|
299
|
-
when 'h',
|
244
|
+
when 'h','mn','s'
|
300
245
|
'SECOND'
|
301
246
|
when /i\z/
|
302
|
-
collector <<
|
247
|
+
collector << "("
|
303
248
|
collector = visit o.right, collector
|
304
|
-
collector <<
|
305
|
-
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
249
|
+
collector << ")"
|
250
|
+
collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
|
306
251
|
return collector
|
307
252
|
end
|
308
253
|
end
|
309
|
-
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM
|
254
|
+
collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
|
310
255
|
collector = visit o.right, collector
|
311
|
-
collector <<
|
256
|
+
collector << ")"
|
312
257
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
313
258
|
collector
|
314
259
|
end
|
315
260
|
|
316
261
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
317
|
-
collector <<
|
262
|
+
collector << "POSITION("
|
318
263
|
collector = visit o.right, collector
|
319
|
-
collector <<
|
264
|
+
collector << " IN "
|
320
265
|
collector = visit o.left, collector
|
321
|
-
collector <<
|
266
|
+
collector << ")"
|
322
267
|
collector
|
323
268
|
end
|
324
269
|
|
325
270
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
326
|
-
collector <<
|
271
|
+
collector << "SUBSTR("
|
327
272
|
o.expressions.each_with_index { |arg, i|
|
328
|
-
collector << COMMA
|
273
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
329
274
|
collector = visit arg, collector
|
330
275
|
}
|
331
|
-
collector <<
|
332
|
-
collector
|
333
|
-
end
|
334
|
-
|
335
|
-
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
336
|
-
collector << 'REGEXP_REPLACE('
|
337
|
-
visit o.left, collector
|
338
|
-
collector << Arel::Visitors::ToSql::COMMA
|
339
|
-
tab = o.pattern.inspect + 'g' # Make it always global
|
340
|
-
pattern = tab.split('/')[1..-2].join('/')
|
341
|
-
flags = tab.split('/')[-1]
|
342
|
-
visit Arel.quoted(pattern), collector
|
343
|
-
collector << Arel::Visitors::ToSql::COMMA
|
344
|
-
visit o.substitute, collector
|
345
|
-
collector << Arel::Visitors::ToSql::COMMA
|
346
|
-
visit Arel.quoted(flags + 'g'), collector
|
347
|
-
collector << ')'
|
276
|
+
collector << ")"
|
348
277
|
collector
|
349
278
|
end
|
350
279
|
|
@@ -355,111 +284,98 @@ module ArelExtensions
|
|
355
284
|
end
|
356
285
|
|
357
286
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
358
|
-
|
287
|
+
collector = visit o.expr, collector
|
359
288
|
collector << ' IS NOT NULL'
|
360
289
|
collector
|
361
290
|
end
|
362
291
|
|
363
292
|
def visit_ArelExtensions_Nodes_Sum o, collector
|
364
|
-
collector <<
|
293
|
+
collector << "sum("
|
365
294
|
collector = visit o.expr, collector
|
366
|
-
collector <<
|
367
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
295
|
+
collector << ")"
|
368
296
|
collector
|
369
297
|
end
|
370
298
|
|
371
299
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
372
|
-
collector <<
|
300
|
+
collector << "EXRTACT(DOW, "
|
373
301
|
collector = visit o.date, collector
|
374
302
|
collector << ')'
|
375
303
|
collector
|
376
304
|
end
|
377
305
|
|
378
306
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
379
|
-
as_attr =
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
'jsonb'
|
402
|
-
else
|
403
|
-
o.as_attr.to_s
|
404
|
-
end
|
405
|
-
|
406
|
-
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("
|
407
329
|
collector = visit o.left, collector
|
408
|
-
collector <<
|
409
|
-
collector = visit
|
410
|
-
collector <<
|
330
|
+
collector << " AS "
|
331
|
+
collector = visit as_attr, collector
|
332
|
+
collector << ")"
|
411
333
|
collector
|
412
334
|
end
|
413
335
|
|
414
336
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
415
337
|
col = o.left.coalesce(0)
|
416
|
-
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
417
|
-
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')
|
418
340
|
nines_after = (1..o.precision).map{'9'}.join('')
|
419
|
-
nines_before = ("999#{thousand_separator}"
|
341
|
+
nines_before = ("999#{thousand_separator}"*4+"990")
|
420
342
|
|
421
|
-
sign =
|
343
|
+
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
422
344
|
then('-').
|
423
345
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
424
346
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
425
347
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
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
|
448
369
|
|
449
|
-
repeated_char =
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
Arel
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
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 : ''
|
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 : ''
|
463
379
|
after = o.flags.include?('-') ? repeated_char : ''
|
464
380
|
full_number = ArelExtensions::Nodes::Concat.new([
|
465
381
|
before,
|
@@ -468,30 +384,30 @@ module ArelExtensions
|
|
468
384
|
number,
|
469
385
|
after
|
470
386
|
])
|
471
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel.
|
387
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
472
388
|
collector
|
473
389
|
end
|
474
390
|
|
475
391
|
|
476
|
-
alias_method
|
392
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
477
393
|
def visit_Arel_Nodes_SelectStatement o, collector
|
478
394
|
|
479
395
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
480
396
|
o = o.dup
|
481
397
|
o.orders = []
|
482
398
|
end
|
483
|
-
old_visit_Arel_Nodes_SelectStatement(o,
|
399
|
+
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
484
400
|
end
|
485
401
|
|
486
|
-
alias_method
|
402
|
+
alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
|
487
403
|
def visit_Arel_Nodes_TableAlias o, collector
|
488
404
|
if o.name.length > 63
|
489
405
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
490
406
|
end
|
491
|
-
old_visit_Arel_Nodes_TableAlias(o,
|
407
|
+
old_visit_Arel_Nodes_TableAlias(o,collector)
|
492
408
|
end
|
493
409
|
|
494
|
-
alias_method
|
410
|
+
alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
|
495
411
|
def visit_Arel_Attributes_Attribute o, collector
|
496
412
|
join_name = o.relation.table_alias || o.relation.name
|
497
413
|
if join_name.length > 63
|
@@ -501,35 +417,33 @@ module ArelExtensions
|
|
501
417
|
end
|
502
418
|
|
503
419
|
def visit_ArelExtensions_Nodes_Std o, collector
|
504
|
-
collector << (o.unbiased_estimator ?
|
420
|
+
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
505
421
|
visit o.left, collector
|
506
|
-
collector <<
|
507
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
422
|
+
collector << ")"
|
508
423
|
collector
|
509
424
|
end
|
510
425
|
|
511
426
|
def visit_ArelExtensions_Nodes_Variance o, collector
|
512
|
-
collector << (o.unbiased_estimator ?
|
427
|
+
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
513
428
|
visit o.left, collector
|
514
|
-
collector <<
|
515
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
429
|
+
collector << ")"
|
516
430
|
collector
|
517
431
|
end
|
518
432
|
|
519
|
-
def visit_ArelExtensions_Nodes_Json o,
|
433
|
+
def visit_ArelExtensions_Nodes_Json o,collector
|
520
434
|
case o.dict
|
521
435
|
when Array
|
522
436
|
collector << 'to_jsonb(array['
|
523
|
-
o.dict.each.with_index do |v,
|
437
|
+
o.dict.each.with_index do |v,i|
|
524
438
|
if i != 0
|
525
439
|
collector << Arel::Visitors::MySQL::COMMA
|
526
440
|
end
|
527
|
-
collector
|
441
|
+
collector = visit v, collector
|
528
442
|
end
|
529
443
|
collector << '])'
|
530
444
|
when Hash
|
531
445
|
collector << 'jsonb_build_object('
|
532
|
-
o.dict.each.with_index do |(k,
|
446
|
+
o.dict.each.with_index do |(k,v),i|
|
533
447
|
if i != 0
|
534
448
|
collector << Arel::Visitors::MySQL::COMMA
|
535
449
|
end
|
@@ -538,11 +452,13 @@ module ArelExtensions
|
|
538
452
|
collector = visit v, collector
|
539
453
|
end
|
540
454
|
collector << ')'
|
541
|
-
when String,
|
542
|
-
collector = visit Arel.
|
455
|
+
when String,Numeric,TrueClass,FalseClass
|
456
|
+
collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
|
543
457
|
collector << '::jsonb'
|
544
458
|
when NilClass
|
545
|
-
collector
|
459
|
+
collector << %Q['null'::jsonb]
|
460
|
+
when Arel::Attributes::Attribute
|
461
|
+
collector = visit o.dict.cast(:jsonb), collector
|
546
462
|
else
|
547
463
|
collector = visit o.dict, collector
|
548
464
|
collector << '::jsonb'
|
@@ -550,8 +466,8 @@ module ArelExtensions
|
|
550
466
|
collector
|
551
467
|
end
|
552
468
|
|
553
|
-
def visit_ArelExtensions_Nodes_JsonMerge o,
|
554
|
-
o.expressions.each.with_index do |v,
|
469
|
+
def visit_ArelExtensions_Nodes_JsonMerge o,collector
|
470
|
+
o.expressions.each.with_index do |v,i|
|
555
471
|
if i != 0
|
556
472
|
collector << ' || '
|
557
473
|
end
|
@@ -560,14 +476,14 @@ module ArelExtensions
|
|
560
476
|
collector
|
561
477
|
end
|
562
478
|
|
563
|
-
def visit_ArelExtensions_Nodes_JsonGet o,
|
479
|
+
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
564
480
|
collector = visit o.dict, collector
|
565
|
-
collector << '
|
481
|
+
collector << ' -> '
|
566
482
|
collector = visit o.key, collector
|
567
483
|
collector
|
568
484
|
end
|
569
485
|
|
570
|
-
def visit_ArelExtensions_Nodes_JsonSet o,
|
486
|
+
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
571
487
|
collector << 'jsonb_set('
|
572
488
|
collector = visit o.dict, collector
|
573
489
|
collector << Arel::Visitors::MySQL::COMMA
|
@@ -589,7 +505,7 @@ module ArelExtensions
|
|
589
505
|
else
|
590
506
|
case o.dict
|
591
507
|
when Hash
|
592
|
-
o.dict.each.with_index do |(k,
|
508
|
+
o.dict.each.with_index do |(k,v),i|
|
593
509
|
if i != 0
|
594
510
|
collector << ' || '
|
595
511
|
end
|
@@ -607,6 +523,7 @@ module ArelExtensions
|
|
607
523
|
end
|
608
524
|
collector
|
609
525
|
end
|
526
|
+
|
610
527
|
end
|
611
528
|
end
|
612
529
|
end
|