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,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,121 +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
|
-
collector << 'TO_CHAR('
|
|
179
|
-
collector << '(' if o.time_zone
|
|
135
|
+
collector << "TO_CHAR("
|
|
180
136
|
collector = visit o.left, collector
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
when String
|
|
189
|
-
collector << ') AT TIME ZONE '
|
|
190
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
|
191
|
-
end
|
|
192
|
-
collector << COMMA
|
|
193
|
-
collector = visit Arel.quoted(fmt), collector
|
|
194
|
-
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 << ")"
|
|
195
144
|
collector
|
|
196
145
|
end
|
|
197
146
|
|
|
198
147
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
|
199
|
-
collector <<
|
|
148
|
+
collector << "REPEAT("
|
|
200
149
|
o.expressions.each_with_index { |arg, i|
|
|
201
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
150
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
202
151
|
collector = visit arg, collector
|
|
203
152
|
}
|
|
204
|
-
collector <<
|
|
153
|
+
collector << ")"
|
|
205
154
|
collector
|
|
206
155
|
end
|
|
207
156
|
|
|
@@ -243,9 +192,9 @@ module ArelExtensions
|
|
|
243
192
|
|
|
244
193
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
|
245
194
|
if o.ai
|
|
246
|
-
collector <<
|
|
195
|
+
collector << "unaccent("
|
|
247
196
|
collector = visit o.expressions.first, collector
|
|
248
|
-
collector <<
|
|
197
|
+
collector << ")"
|
|
249
198
|
elsif o.ci
|
|
250
199
|
collector = visit o.expressions.first, collector
|
|
251
200
|
else
|
|
@@ -256,7 +205,7 @@ module ArelExtensions
|
|
|
256
205
|
|
|
257
206
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
|
258
207
|
collector = visit o.left, collector
|
|
259
|
-
collector << ' + ' #
|
|
208
|
+
collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
|
|
260
209
|
collector = visit o.postgresql_value(o.right), collector
|
|
261
210
|
collector
|
|
262
211
|
end
|
|
@@ -264,16 +213,16 @@ module ArelExtensions
|
|
|
264
213
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
|
265
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
|
|
266
215
|
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
|
267
|
-
|
|
216
|
+
"DATEDIFF('second', "
|
|
268
217
|
else
|
|
269
|
-
|
|
218
|
+
"DATEDIFF('day', "
|
|
270
219
|
end
|
|
271
220
|
collector = visit o.right, collector
|
|
272
221
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
|
273
|
-
collector << COMMA
|
|
222
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
274
223
|
collector = visit o.left, collector
|
|
275
224
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
|
276
|
-
collector <<
|
|
225
|
+
collector << ")"
|
|
277
226
|
else
|
|
278
227
|
collector << '('
|
|
279
228
|
collector = visit o.left, collector
|
|
@@ -290,57 +239,41 @@ module ArelExtensions
|
|
|
290
239
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
|
291
240
|
if o.with_interval
|
|
292
241
|
interval = case o.left
|
|
293
|
-
when 'd',
|
|
242
|
+
when 'd','m','y'
|
|
294
243
|
'DAY'
|
|
295
|
-
when 'h',
|
|
244
|
+
when 'h','mn','s'
|
|
296
245
|
'SECOND'
|
|
297
246
|
when /i\z/
|
|
298
|
-
collector <<
|
|
247
|
+
collector << "("
|
|
299
248
|
collector = visit o.right, collector
|
|
300
|
-
collector <<
|
|
301
|
-
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
|
249
|
+
collector << ")"
|
|
250
|
+
collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
|
|
302
251
|
return collector
|
|
303
252
|
end
|
|
304
253
|
end
|
|
305
|
-
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM
|
|
254
|
+
collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
|
|
306
255
|
collector = visit o.right, collector
|
|
307
|
-
collector <<
|
|
256
|
+
collector << ")"
|
|
308
257
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
|
309
258
|
collector
|
|
310
259
|
end
|
|
311
260
|
|
|
312
261
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
|
313
|
-
collector <<
|
|
262
|
+
collector << "POSITION("
|
|
314
263
|
collector = visit o.right, collector
|
|
315
|
-
collector <<
|
|
264
|
+
collector << " IN "
|
|
316
265
|
collector = visit o.left, collector
|
|
317
|
-
collector <<
|
|
266
|
+
collector << ")"
|
|
318
267
|
collector
|
|
319
268
|
end
|
|
320
269
|
|
|
321
270
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
|
322
|
-
collector <<
|
|
271
|
+
collector << "SUBSTR("
|
|
323
272
|
o.expressions.each_with_index { |arg, i|
|
|
324
|
-
collector << COMMA
|
|
273
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
|
325
274
|
collector = visit arg, collector
|
|
326
275
|
}
|
|
327
|
-
collector <<
|
|
328
|
-
collector
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
|
332
|
-
collector << 'REGEXP_REPLACE('
|
|
333
|
-
visit o.left, collector
|
|
334
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
335
|
-
tab = o.pattern.inspect + 'g' # Make it always global
|
|
336
|
-
pattern = tab.split('/')[1..-2].join('/')
|
|
337
|
-
flags = tab.split('/')[-1]
|
|
338
|
-
visit Arel.quoted(pattern), collector
|
|
339
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
340
|
-
visit o.substitute, collector
|
|
341
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
342
|
-
visit Arel.quoted(flags + 'g'), collector
|
|
343
|
-
collector << ')'
|
|
276
|
+
collector << ")"
|
|
344
277
|
collector
|
|
345
278
|
end
|
|
346
279
|
|
|
@@ -351,111 +284,98 @@ module ArelExtensions
|
|
|
351
284
|
end
|
|
352
285
|
|
|
353
286
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
|
354
|
-
|
|
287
|
+
collector = visit o.expr, collector
|
|
355
288
|
collector << ' IS NOT NULL'
|
|
356
289
|
collector
|
|
357
290
|
end
|
|
358
291
|
|
|
359
292
|
def visit_ArelExtensions_Nodes_Sum o, collector
|
|
360
|
-
collector <<
|
|
293
|
+
collector << "sum("
|
|
361
294
|
collector = visit o.expr, collector
|
|
362
|
-
collector <<
|
|
363
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
295
|
+
collector << ")"
|
|
364
296
|
collector
|
|
365
297
|
end
|
|
366
298
|
|
|
367
299
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
|
368
|
-
collector <<
|
|
300
|
+
collector << "EXRTACT(DOW, "
|
|
369
301
|
collector = visit o.date, collector
|
|
370
302
|
collector << ')'
|
|
371
303
|
collector
|
|
372
304
|
end
|
|
373
305
|
|
|
374
306
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
|
375
|
-
as_attr =
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
'jsonb'
|
|
398
|
-
else
|
|
399
|
-
o.as_attr.to_s
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
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("
|
|
403
329
|
collector = visit o.left, collector
|
|
404
|
-
collector <<
|
|
405
|
-
collector = visit
|
|
406
|
-
collector <<
|
|
330
|
+
collector << " AS "
|
|
331
|
+
collector = visit as_attr, collector
|
|
332
|
+
collector << ")"
|
|
407
333
|
collector
|
|
408
334
|
end
|
|
409
335
|
|
|
410
336
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
|
411
337
|
col = o.left.coalesce(0)
|
|
412
|
-
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
|
413
|
-
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')
|
|
414
340
|
nines_after = (1..o.precision).map{'9'}.join('')
|
|
415
|
-
nines_before = ("999#{thousand_separator}"
|
|
341
|
+
nines_before = ("999#{thousand_separator}"*4+"990")
|
|
416
342
|
|
|
417
|
-
sign =
|
|
343
|
+
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
|
418
344
|
then('-').
|
|
419
345
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
|
420
346
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
|
421
347
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
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
|
|
444
369
|
|
|
445
|
-
repeated_char =
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
Arel
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
)
|
|
455
|
-
.else('')
|
|
456
|
-
end
|
|
457
|
-
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
458
|
-
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 : ''
|
|
459
379
|
after = o.flags.include?('-') ? repeated_char : ''
|
|
460
380
|
full_number = ArelExtensions::Nodes::Concat.new([
|
|
461
381
|
before,
|
|
@@ -464,30 +384,30 @@ module ArelExtensions
|
|
|
464
384
|
number,
|
|
465
385
|
after
|
|
466
386
|
])
|
|
467
|
-
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
|
|
468
388
|
collector
|
|
469
389
|
end
|
|
470
390
|
|
|
471
391
|
|
|
472
|
-
alias_method
|
|
392
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
|
473
393
|
def visit_Arel_Nodes_SelectStatement o, collector
|
|
474
394
|
|
|
475
395
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
|
476
396
|
o = o.dup
|
|
477
397
|
o.orders = []
|
|
478
398
|
end
|
|
479
|
-
old_visit_Arel_Nodes_SelectStatement(o,
|
|
399
|
+
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
|
480
400
|
end
|
|
481
401
|
|
|
482
|
-
alias_method
|
|
402
|
+
alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
|
|
483
403
|
def visit_Arel_Nodes_TableAlias o, collector
|
|
484
404
|
if o.name.length > 63
|
|
485
405
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
|
486
406
|
end
|
|
487
|
-
old_visit_Arel_Nodes_TableAlias(o,
|
|
407
|
+
old_visit_Arel_Nodes_TableAlias(o,collector)
|
|
488
408
|
end
|
|
489
409
|
|
|
490
|
-
alias_method
|
|
410
|
+
alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
|
|
491
411
|
def visit_Arel_Attributes_Attribute o, collector
|
|
492
412
|
join_name = o.relation.table_alias || o.relation.name
|
|
493
413
|
if join_name.length > 63
|
|
@@ -497,35 +417,33 @@ module ArelExtensions
|
|
|
497
417
|
end
|
|
498
418
|
|
|
499
419
|
def visit_ArelExtensions_Nodes_Std o, collector
|
|
500
|
-
collector << (o.unbiased_estimator ?
|
|
420
|
+
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
|
501
421
|
visit o.left, collector
|
|
502
|
-
collector <<
|
|
503
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
422
|
+
collector << ")"
|
|
504
423
|
collector
|
|
505
424
|
end
|
|
506
425
|
|
|
507
426
|
def visit_ArelExtensions_Nodes_Variance o, collector
|
|
508
|
-
collector << (o.unbiased_estimator ?
|
|
427
|
+
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
|
509
428
|
visit o.left, collector
|
|
510
|
-
collector <<
|
|
511
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
429
|
+
collector << ")"
|
|
512
430
|
collector
|
|
513
431
|
end
|
|
514
432
|
|
|
515
|
-
def visit_ArelExtensions_Nodes_Json o,
|
|
433
|
+
def visit_ArelExtensions_Nodes_Json o,collector
|
|
516
434
|
case o.dict
|
|
517
435
|
when Array
|
|
518
436
|
collector << 'to_jsonb(array['
|
|
519
|
-
o.dict.each.with_index do |v,
|
|
437
|
+
o.dict.each.with_index do |v,i|
|
|
520
438
|
if i != 0
|
|
521
439
|
collector << Arel::Visitors::MySQL::COMMA
|
|
522
440
|
end
|
|
523
|
-
collector
|
|
441
|
+
collector = visit v, collector
|
|
524
442
|
end
|
|
525
443
|
collector << '])'
|
|
526
444
|
when Hash
|
|
527
445
|
collector << 'jsonb_build_object('
|
|
528
|
-
o.dict.each.with_index do |(k,
|
|
446
|
+
o.dict.each.with_index do |(k,v),i|
|
|
529
447
|
if i != 0
|
|
530
448
|
collector << Arel::Visitors::MySQL::COMMA
|
|
531
449
|
end
|
|
@@ -534,11 +452,13 @@ module ArelExtensions
|
|
|
534
452
|
collector = visit v, collector
|
|
535
453
|
end
|
|
536
454
|
collector << ')'
|
|
537
|
-
when String,
|
|
538
|
-
collector = visit Arel.
|
|
455
|
+
when String,Numeric,TrueClass,FalseClass
|
|
456
|
+
collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
|
|
539
457
|
collector << '::jsonb'
|
|
540
458
|
when NilClass
|
|
541
|
-
collector
|
|
459
|
+
collector << %Q['null'::jsonb]
|
|
460
|
+
when Arel::Attributes::Attribute
|
|
461
|
+
collector = visit o.dict.cast(:jsonb), collector
|
|
542
462
|
else
|
|
543
463
|
collector = visit o.dict, collector
|
|
544
464
|
collector << '::jsonb'
|
|
@@ -546,8 +466,8 @@ module ArelExtensions
|
|
|
546
466
|
collector
|
|
547
467
|
end
|
|
548
468
|
|
|
549
|
-
def visit_ArelExtensions_Nodes_JsonMerge o,
|
|
550
|
-
o.expressions.each.with_index do |v,
|
|
469
|
+
def visit_ArelExtensions_Nodes_JsonMerge o,collector
|
|
470
|
+
o.expressions.each.with_index do |v,i|
|
|
551
471
|
if i != 0
|
|
552
472
|
collector << ' || '
|
|
553
473
|
end
|
|
@@ -556,14 +476,14 @@ module ArelExtensions
|
|
|
556
476
|
collector
|
|
557
477
|
end
|
|
558
478
|
|
|
559
|
-
def visit_ArelExtensions_Nodes_JsonGet o,
|
|
479
|
+
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
|
560
480
|
collector = visit o.dict, collector
|
|
561
|
-
collector << '
|
|
481
|
+
collector << ' -> '
|
|
562
482
|
collector = visit o.key, collector
|
|
563
483
|
collector
|
|
564
484
|
end
|
|
565
485
|
|
|
566
|
-
def visit_ArelExtensions_Nodes_JsonSet o,
|
|
486
|
+
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
|
567
487
|
collector << 'jsonb_set('
|
|
568
488
|
collector = visit o.dict, collector
|
|
569
489
|
collector << Arel::Visitors::MySQL::COMMA
|
|
@@ -585,7 +505,7 @@ module ArelExtensions
|
|
|
585
505
|
else
|
|
586
506
|
case o.dict
|
|
587
507
|
when Hash
|
|
588
|
-
o.dict.each.with_index do |(k,
|
|
508
|
+
o.dict.each.with_index do |(k,v),i|
|
|
589
509
|
if i != 0
|
|
590
510
|
collector << ' || '
|
|
591
511
|
end
|
|
@@ -603,6 +523,7 @@ module ArelExtensions
|
|
|
603
523
|
end
|
|
604
524
|
collector
|
|
605
525
|
end
|
|
526
|
+
|
|
606
527
|
end
|
|
607
528
|
end
|
|
608
529
|
end
|