arel_extensions 1.7.0 → 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 -8
- data/.rubocop.yml +4 -194
- 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 +28 -2
- data/README.md +89 -265
- data/Rakefile +30 -50
- data/TODO +1 -0
- data/appveyor.yml +22 -60
- data/arel_extensions.gemspec +17 -14
- data/functions.html +3 -3
- data/gemfiles/rails3.gemfile +20 -0
- data/gemfiles/rails4.gemfile +29 -0
- data/gemfiles/rails5_0.gemfile +29 -0
- data/gemfiles/rails5_1_4.gemfile +17 -19
- data/gemfiles/rails5_2.gemfile +17 -26
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +25 -24
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/attributes.rb +3 -9
- data/lib/arel_extensions/boolean_functions.rb +16 -57
- data/lib/arel_extensions/common_sql_functions.rb +20 -21
- data/lib/arel_extensions/comparators.rb +28 -31
- data/lib/arel_extensions/date_duration.rb +13 -19
- data/lib/arel_extensions/insert_manager.rb +15 -22
- data/lib/arel_extensions/math.rb +70 -68
- data/lib/arel_extensions/math_functions.rb +52 -57
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +5 -6
- data/lib/arel_extensions/nodes/case.rb +27 -31
- data/lib/arel_extensions/nodes/cast.rb +12 -12
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/coalesce.rb +5 -4
- data/lib/arel_extensions/nodes/collate.rb +10 -9
- data/lib/arel_extensions/nodes/concat.rb +22 -13
- data/lib/arel_extensions/nodes/date_diff.rb +70 -77
- data/lib/arel_extensions/nodes/duration.rb +5 -2
- 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 +39 -50
- data/lib/arel_extensions/nodes/is_null.rb +0 -2
- data/lib/arel_extensions/nodes/json.rb +47 -72
- data/lib/arel_extensions/nodes/length.rb +0 -5
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
- data/lib/arel_extensions/nodes/locate.rb +3 -2
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +8 -6
- 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 +3 -2
- data/lib/arel_extensions/nodes/repeat.rb +6 -4
- data/lib/arel_extensions/nodes/replace.rb +8 -16
- data/lib/arel_extensions/nodes/round.rb +7 -6
- 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 -58
- data/lib/arel_extensions/nodes/then.rb +2 -2
- data/lib/arel_extensions/nodes/trim.rb +7 -5
- data/lib/arel_extensions/nodes/union.rb +9 -6
- data/lib/arel_extensions/nodes/union_all.rb +8 -5
- data/lib/arel_extensions/nodes/wday.rb +6 -2
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +6 -18
- data/lib/arel_extensions/predications.rb +49 -54
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +7 -5
- data/lib/arel_extensions/string_functions.rb +55 -110
- data/lib/arel_extensions/tasks.rb +6 -6
- data/lib/arel_extensions/version.rb +1 -3
- data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
- data/lib/arel_extensions/visitors/mssql.rb +248 -493
- data/lib/arel_extensions/visitors/mysql.rb +244 -420
- data/lib/arel_extensions/visitors/oracle.rb +258 -311
- data/lib/arel_extensions/visitors/oracle12.rb +34 -20
- data/lib/arel_extensions/visitors/postgresql.rb +239 -350
- data/lib/arel_extensions/visitors/sqlite.rb +169 -191
- data/lib/arel_extensions/visitors/to_sql.rb +299 -371
- data/lib/arel_extensions/visitors.rb +62 -83
- data/lib/arel_extensions.rb +32 -243
- data/test/database.yml +10 -20
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +120 -123
- data/test/support/fake_record.rb +3 -11
- data/test/test_comparators.rb +17 -14
- data/test/visitors/test_bulk_insert_oracle.rb +12 -12
- data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
- 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 +375 -912
- data/test/with_ar/insert_agnostic_test.rb +22 -28
- data/test/with_ar/test_bulk_sqlite.rb +17 -18
- data/test/with_ar/test_math_sqlite.rb +27 -27
- data/test/with_ar/test_string_mysql.rb +34 -32
- data/test/with_ar/test_string_sqlite.rb +35 -31
- metadata +64 -50
- data/.github/workflows/publish.yml +0 -30
- data/.github/workflows/release.yml +0 -30
- data/.github/workflows/ruby.yml +0 -452
- data/CONTRIBUTING.md +0 -102
- data/Makefile +0 -48
- data/NEWS.md +0 -131
- data/bin/build +0 -15
- data/bin/publish +0 -8
- data/dev/arelx.dockerfile +0 -41
- data/dev/compose.yaml +0 -69
- data/dev/postgres.dockerfile +0 -5
- data/dev/rbenv +0 -189
- data/gemfiles/rails5.gemfile +0 -36
- data/gemfiles/rails6.gemfile +0 -40
- data/gemfiles/rails6_1.gemfile +0 -48
- data/gemfiles/rails7.gemfile +0 -48
- data/gemfiles/rails7_1.gemfile +0 -48
- data/gemfiles/rails7_2.gemfile +0 -47
- data/gemfiles/rails8.gemfile +0 -40
- data/gemfiles/rails8_1.gemfile +0 -41
- data/gemspecs/arel_extensions-v1.gemspec +0 -25
- data/gemspecs/arel_extensions-v2.gemspec +0 -25
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/aliases.rb +0 -14
- data/lib/arel_extensions/constants.rb +0 -13
- data/lib/arel_extensions/helpers.rb +0 -61
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/byte_size.rb +0 -11
- data/lib/arel_extensions/nodes/char_length.rb +0 -11
- 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/lib/arel_extensions/warning.rb +0 -42
- data/test/arelx_test_helper.rb +0 -94
- data/test/config_loader.rb +0 -9
- data/version_v1.rb +0 -5
- data/version_v2.rb +0 -5
|
@@ -1,106 +1,39 @@
|
|
|
1
1
|
module ArelExtensions
|
|
2
2
|
module Visitors
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}.freeze
|
|
8
|
-
|
|
9
|
-
DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
|
3
|
+
Arel::Visitors::MySQL.class_eval do
|
|
4
|
+
Arel::Visitors::MySQL::COMMA = ", "
|
|
5
|
+
Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
|
6
|
+
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
|
10
7
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
|
11
|
-
'%
|
|
12
|
-
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%a' => '%a', '%A' => '%W', # day, weekday
|
|
8
|
+
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
|
|
13
9
|
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
|
|
14
10
|
'%M' => '%i', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
# This helper method did not exist in rails < 5.2
|
|
18
|
-
if !Arel::Visitors::MySQL.method_defined?(:collect_nodes_for)
|
|
19
|
-
def collect_nodes_for(nodes, collector, spacer, connector = ', ')
|
|
20
|
-
if nodes&.any?
|
|
21
|
-
collector << spacer
|
|
22
|
-
inject_join nodes, collector, connector
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
if private_method_defined?(:visit_Arel_Nodes_SelectCore) || method_defined?(:visit_Arel_Nodes_SelectCore)
|
|
28
|
-
alias old_visit_Arel_Nodes_SelectCore visit_Arel_Nodes_SelectCore
|
|
29
|
-
end
|
|
30
|
-
# The whole purpose of this override is to fix the behavior of RollUp.
|
|
31
|
-
# All other databases treat RollUp sanely, execpt MySQL which requires
|
|
32
|
-
# that it figures as the last element of a GROUP BY.
|
|
33
|
-
def visit_Arel_Nodes_SelectCore(o, collector)
|
|
34
|
-
collector << 'SELECT'
|
|
35
|
-
|
|
36
|
-
collector = collect_optimizer_hints(o, collector) if respond_to?(:collect_optimizer_hints, true)
|
|
37
|
-
collector = maybe_visit o.set_quantifier, collector
|
|
11
|
+
}
|
|
38
12
|
|
|
39
|
-
collect_nodes_for o.projections, collector, ' '
|
|
40
13
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
collector
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if rollup && !rollup.empty?
|
|
50
|
-
groups = o.groups.reject { |g| g.expr.class == Arel::Nodes::RollUp }
|
|
51
|
-
groups << Arel::Nodes::RollUp.new(rollup)
|
|
52
|
-
end
|
|
53
|
-
# FIN
|
|
54
|
-
|
|
55
|
-
collect_nodes_for o.wheres, collector, ' WHERE ', ' AND '
|
|
56
|
-
collect_nodes_for groups, collector, ' GROUP BY '
|
|
57
|
-
collect_nodes_for o.havings, collector, ' HAVING ', ' AND '
|
|
58
|
-
collect_nodes_for o.windows, collector, ' WINDOW '
|
|
59
|
-
|
|
60
|
-
if o.respond_to?(:comment)
|
|
61
|
-
maybe_visit o.comment, collector
|
|
62
|
-
else
|
|
14
|
+
#Math functions
|
|
15
|
+
def visit_ArelExtensions_Nodes_Log10 o, collector
|
|
16
|
+
collector << "LOG10("
|
|
17
|
+
o.expressions.each_with_index { |arg, i|
|
|
18
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
19
|
+
collector = visit arg, collector
|
|
20
|
+
}
|
|
21
|
+
collector << ")"
|
|
63
22
|
collector
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Math functions
|
|
68
|
-
def visit_ArelExtensions_Nodes_Log10(o, collector)
|
|
69
|
-
collector << 'LOG10('
|
|
70
|
-
o.expressions.each_with_index { |arg, i|
|
|
71
|
-
collector << COMMA if i != 0
|
|
72
|
-
collector = visit arg, collector
|
|
73
|
-
}
|
|
74
|
-
collector << ')'
|
|
75
|
-
collector
|
|
76
23
|
end
|
|
77
24
|
|
|
78
|
-
def visit_ArelExtensions_Nodes_Power
|
|
79
|
-
collector <<
|
|
25
|
+
def visit_ArelExtensions_Nodes_Power o, collector
|
|
26
|
+
collector << "POW("
|
|
80
27
|
o.expressions.each_with_index { |arg, i|
|
|
81
|
-
collector << COMMA
|
|
28
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
82
29
|
collector = visit arg, collector
|
|
83
30
|
}
|
|
84
|
-
collector <<
|
|
85
|
-
collector
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# String functions
|
|
89
|
-
def visit_ArelExtensions_Nodes_ByteSize(o, collector)
|
|
90
|
-
collector << 'LENGTH('
|
|
91
|
-
collector = visit o.expr.coalesce(''), collector
|
|
92
|
-
collector << ')'
|
|
31
|
+
collector << ")"
|
|
93
32
|
collector
|
|
94
33
|
end
|
|
95
34
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
collector = visit o.expr.coalesce(''), collector
|
|
99
|
-
collector << ')'
|
|
100
|
-
collector
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def visit_ArelExtensions_Nodes_IMatches(o, collector) # insensitive on ASCII
|
|
35
|
+
#String functions
|
|
36
|
+
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
|
104
37
|
collector << 'LOWER('
|
|
105
38
|
collector = visit o.left, collector
|
|
106
39
|
collector << ') LIKE LOWER('
|
|
@@ -108,45 +41,49 @@ module ArelExtensions
|
|
|
108
41
|
collector << ')'
|
|
109
42
|
if o.escape
|
|
110
43
|
collector << ' ESCAPE '
|
|
111
|
-
|
|
44
|
+
visit o.escape, collector
|
|
45
|
+
else
|
|
46
|
+
collector
|
|
112
47
|
end
|
|
113
|
-
collector
|
|
114
48
|
end
|
|
115
49
|
|
|
116
|
-
def visit_ArelExtensions_Nodes_AiMatches
|
|
50
|
+
def visit_ArelExtensions_Nodes_AiMatches o, collector
|
|
117
51
|
collector = visit o.left.ai_collate, collector
|
|
118
52
|
collector << ' LIKE '
|
|
119
53
|
collector = visit o.right.ai_collate, collector
|
|
120
54
|
if o.escape
|
|
121
55
|
collector << ' ESCAPE '
|
|
122
|
-
|
|
56
|
+
visit o.escape, collector
|
|
57
|
+
else
|
|
58
|
+
collector
|
|
123
59
|
end
|
|
124
|
-
collector
|
|
125
60
|
end
|
|
126
61
|
|
|
127
|
-
def visit_ArelExtensions_Nodes_AiIMatches
|
|
62
|
+
def visit_ArelExtensions_Nodes_AiIMatches o, collector
|
|
128
63
|
collector = visit o.left.ai_collate, collector
|
|
129
64
|
collector << ' LIKE '
|
|
130
65
|
collector = visit o.right.ai_collate, collector
|
|
131
66
|
if o.escape
|
|
132
67
|
collector << ' ESCAPE '
|
|
133
|
-
|
|
68
|
+
visit o.escape, collector
|
|
69
|
+
else
|
|
70
|
+
collector
|
|
134
71
|
end
|
|
135
|
-
collector
|
|
136
72
|
end
|
|
137
73
|
|
|
138
|
-
def visit_ArelExtensions_Nodes_SMatches
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
74
|
+
def visit_ArelExtensions_Nodes_SMatches o, collector
|
|
75
|
+
collector = visit o.left.collate, collector
|
|
76
|
+
collector << ' LIKE '
|
|
77
|
+
collector = visit o.right.collate, collector
|
|
78
|
+
if o.escape
|
|
79
|
+
collector << ' ESCAPE '
|
|
80
|
+
visit o.escape, collector
|
|
81
|
+
else
|
|
82
|
+
collector
|
|
83
|
+
end
|
|
147
84
|
end
|
|
148
85
|
|
|
149
|
-
def visit_ArelExtensions_Nodes_IDoesNotMatch
|
|
86
|
+
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
|
150
87
|
collector << 'LOWER('
|
|
151
88
|
collector = visit o.left, collector
|
|
152
89
|
collector << ') NOT LIKE LOWER('
|
|
@@ -154,189 +91,142 @@ module ArelExtensions
|
|
|
154
91
|
collector << ')'
|
|
155
92
|
if o.escape
|
|
156
93
|
collector << ' ESCAPE '
|
|
157
|
-
|
|
94
|
+
visit o.escape, collector
|
|
95
|
+
else
|
|
96
|
+
collector
|
|
158
97
|
end
|
|
159
|
-
collector
|
|
160
98
|
end
|
|
161
99
|
|
|
162
|
-
def visit_ArelExtensions_Nodes_Collate
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
when 'latin1', 'utf8'
|
|
100
|
+
def visit_ArelExtensions_Nodes_Collate o, collector
|
|
101
|
+
case o.expressions.first
|
|
102
|
+
when Arel::Attributes::Attribute
|
|
103
|
+
charset = case o.option
|
|
104
|
+
when 'latin1','utf8'
|
|
168
105
|
o.option
|
|
169
106
|
else
|
|
170
107
|
Arel::Table.engine.connection.charset || 'utf8'
|
|
171
108
|
end
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
109
|
+
else
|
|
110
|
+
charset = (o.option == 'latin1') ? 'latin1' : 'utf8'
|
|
111
|
+
end
|
|
175
112
|
collector = visit o.expressions.first, collector
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
end
|
|
113
|
+
if o.ai
|
|
114
|
+
collector << " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
|
115
|
+
#doesn't work in latin1
|
|
116
|
+
elsif o.ci
|
|
117
|
+
collector << " COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
|
118
|
+
else
|
|
119
|
+
collector << " COLLATE #{charset}_bin"
|
|
120
|
+
end
|
|
185
121
|
collector
|
|
186
122
|
end
|
|
187
123
|
|
|
188
|
-
def visit_ArelExtensions_Nodes_Concat
|
|
189
|
-
collector <<
|
|
124
|
+
def visit_ArelExtensions_Nodes_Concat o, collector
|
|
125
|
+
collector << "CONCAT("
|
|
190
126
|
o.expressions.each_with_index { |arg, i|
|
|
191
|
-
collector << COMMA
|
|
192
|
-
if arg.is_a?(Numeric) || arg.is_a?(Arel::Attributes::Attribute)
|
|
193
|
-
collector <<
|
|
127
|
+
collector << Arel::Visitors::MySQL::COMMA unless i == 0
|
|
128
|
+
if (arg.is_a?(Numeric)) || (arg.is_a?(Arel::Attributes::Attribute))
|
|
129
|
+
collector << "CAST("
|
|
194
130
|
collector = visit arg, collector
|
|
195
|
-
collector <<
|
|
131
|
+
collector << " AS char)"
|
|
196
132
|
else
|
|
197
133
|
collector = visit arg, collector
|
|
198
134
|
end
|
|
199
135
|
}
|
|
200
|
-
collector <<
|
|
136
|
+
collector << ")"
|
|
201
137
|
collector
|
|
202
138
|
end
|
|
203
139
|
|
|
204
|
-
def
|
|
205
|
-
|
|
206
|
-
collector << ' WITH ROLLUP'
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def visit_ArelExtensions_Nodes_GroupConcat(o, collector)
|
|
210
|
-
collector << 'GROUP_CONCAT('
|
|
140
|
+
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
141
|
+
collector << "GROUP_CONCAT("
|
|
211
142
|
collector = visit o.left, collector
|
|
212
|
-
if !o.
|
|
143
|
+
if !o.orders.blank?
|
|
213
144
|
collector << ' ORDER BY '
|
|
214
|
-
o.
|
|
215
|
-
collector << COMMA
|
|
145
|
+
o.orders.each_with_index do |order,i|
|
|
146
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
216
147
|
collector = visit order, collector
|
|
217
148
|
end
|
|
218
149
|
end
|
|
219
|
-
|
|
220
|
-
if 'NULL' != sep
|
|
150
|
+
if o.right && o.right != 'NULL'
|
|
221
151
|
collector << ' SEPARATOR '
|
|
222
|
-
collector = visit o.
|
|
152
|
+
collector = visit o.right, collector
|
|
223
153
|
end
|
|
224
|
-
collector <<
|
|
154
|
+
collector << ")"
|
|
225
155
|
collector
|
|
226
156
|
end
|
|
227
157
|
|
|
228
|
-
def visit_ArelExtensions_Nodes_Trim
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
158
|
+
def visit_ArelExtensions_Nodes_Trim o, collector
|
|
159
|
+
collector << 'TRIM(' # BOTH
|
|
160
|
+
collector = visit o.right, collector
|
|
161
|
+
collector << " FROM "
|
|
162
|
+
collector = visit o.left, collector
|
|
163
|
+
collector << ")"
|
|
164
|
+
collector
|
|
235
165
|
end
|
|
236
166
|
|
|
237
|
-
def visit_ArelExtensions_Nodes_Ltrim
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
167
|
+
def visit_ArelExtensions_Nodes_Ltrim o , collector
|
|
168
|
+
collector << 'TRIM(LEADING '
|
|
169
|
+
collector = visit o.right, collector
|
|
170
|
+
collector << " FROM "
|
|
171
|
+
collector = visit o.left, collector
|
|
172
|
+
collector << ")"
|
|
173
|
+
collector
|
|
244
174
|
end
|
|
245
175
|
|
|
246
|
-
def visit_ArelExtensions_Nodes_Rtrim
|
|
176
|
+
def visit_ArelExtensions_Nodes_Rtrim o , collector
|
|
247
177
|
collector << 'TRIM(TRAILING '
|
|
248
178
|
collector = visit o.right, collector
|
|
249
|
-
collector <<
|
|
179
|
+
collector << " FROM "
|
|
250
180
|
collector = visit o.left, collector
|
|
251
|
-
collector <<
|
|
181
|
+
collector << ")"
|
|
252
182
|
collector
|
|
253
183
|
end
|
|
254
184
|
|
|
255
|
-
def visit_ArelExtensions_Nodes_Repeat
|
|
256
|
-
collector <<
|
|
185
|
+
def visit_ArelExtensions_Nodes_Repeat o, collector
|
|
186
|
+
collector << "REPEAT("
|
|
257
187
|
o.expressions.each_with_index { |arg, i|
|
|
258
|
-
collector << COMMA
|
|
188
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
259
189
|
collector = visit arg, collector
|
|
260
190
|
}
|
|
261
|
-
collector <<
|
|
191
|
+
collector << ")"
|
|
262
192
|
collector
|
|
263
193
|
end
|
|
264
194
|
|
|
265
|
-
def
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
#
|
|
276
|
-
# In this case, `o.col_type` is `nil` but we have a legitimate type in
|
|
277
|
-
# the expression to be formatted. The following is a best effort to
|
|
278
|
-
# infer the proper type.
|
|
279
|
-
first = o.expressions[0]
|
|
280
|
-
type =
|
|
281
|
-
if o.col_type.nil? \
|
|
282
|
-
&& first.respond_to?(:return_type) && !first&.return_type.nil?
|
|
283
|
-
first&.return_type
|
|
284
|
-
else
|
|
285
|
-
o.col_type
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
case type
|
|
289
|
-
when :date, :datetime, :time
|
|
290
|
-
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
|
195
|
+
def visit_ArelExtensions_Nodes_Format o, collector
|
|
196
|
+
case o.col_type
|
|
197
|
+
when :date, :datetime
|
|
198
|
+
collector << "DATE_FORMAT("
|
|
199
|
+
collector = visit o.left, collector
|
|
200
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
201
|
+
f = o.iso_format.dup
|
|
202
|
+
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
|
203
|
+
collector = visit Arel::Nodes.build_quoted(f), collector
|
|
204
|
+
collector << ")"
|
|
291
205
|
when :integer, :float, :decimal
|
|
292
|
-
collector <<
|
|
206
|
+
collector << "FORMAT("
|
|
293
207
|
collector = visit o.left, collector
|
|
294
|
-
collector << COMMA
|
|
208
|
+
collector << Arel::Visitors::ToSql::COMMA
|
|
295
209
|
collector << '2'
|
|
296
|
-
collector << COMMA
|
|
210
|
+
collector << Arel::Visitors::ToSql::COMMA
|
|
297
211
|
collector = visit o.right, collector
|
|
298
|
-
collector <<
|
|
212
|
+
collector << ")"
|
|
299
213
|
else
|
|
300
214
|
collector = visit o.left, collector
|
|
301
215
|
end
|
|
302
216
|
collector
|
|
303
217
|
end
|
|
304
218
|
|
|
305
|
-
def
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
src_tz, dst_tz = o.time_zone.first
|
|
313
|
-
collector << COMMA
|
|
314
|
-
collector = visit Arel.quoted(src_tz), collector
|
|
315
|
-
collector << COMMA
|
|
316
|
-
collector = visit Arel.quoted(dst_tz), collector
|
|
317
|
-
collector << ')'
|
|
318
|
-
when String
|
|
319
|
-
collector << COMMA << "'UTC'" << COMMA
|
|
320
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
|
321
|
-
collector << ')'
|
|
322
|
-
end
|
|
323
|
-
collector << COMMA
|
|
324
|
-
collector = visit Arel.quoted(fmt), collector
|
|
325
|
-
collector << ')'
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
def visit_ArelExtensions_Nodes_DateDiff(o, collector)
|
|
329
|
-
case o.right_node_type
|
|
330
|
-
when :ruby_date, :ruby_time, :date, :datetime, :time
|
|
331
|
-
collector <<
|
|
332
|
-
case o.left_node_type
|
|
333
|
-
when :ruby_time, :datetime, :time then 'TIMESTAMPDIFF(SECOND, '
|
|
334
|
-
else 'DATEDIFF('
|
|
335
|
-
end
|
|
219
|
+
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
|
220
|
+
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
|
|
221
|
+
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
|
222
|
+
'TIMESTAMPDIFF(SECOND, '
|
|
223
|
+
else
|
|
224
|
+
'DATEDIFF('
|
|
225
|
+
end
|
|
336
226
|
collector = visit o.right, collector
|
|
337
|
-
collector << COMMA
|
|
227
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
338
228
|
collector = visit o.left, collector
|
|
339
|
-
collector <<
|
|
229
|
+
collector << ")"
|
|
340
230
|
else
|
|
341
231
|
collector << '('
|
|
342
232
|
collector = visit o.left, collector
|
|
@@ -355,94 +245,103 @@ module ArelExtensions
|
|
|
355
245
|
collector
|
|
356
246
|
end
|
|
357
247
|
|
|
358
|
-
def visit_ArelExtensions_Nodes_DateAdd
|
|
359
|
-
collector <<
|
|
248
|
+
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
|
249
|
+
collector << "DATE_ADD("
|
|
360
250
|
collector = visit o.left, collector
|
|
361
|
-
collector << COMMA
|
|
251
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
362
252
|
collector = visit o.mysql_value(o.right), collector
|
|
363
|
-
collector <<
|
|
253
|
+
collector << ")"
|
|
364
254
|
collector
|
|
365
255
|
end
|
|
366
256
|
|
|
367
|
-
|
|
257
|
+
|
|
258
|
+
def visit_ArelExtensions_Nodes_Duration o, collector
|
|
368
259
|
if o.left == 'wd'
|
|
369
|
-
collector <<
|
|
260
|
+
collector << "(WEEKDAY("
|
|
370
261
|
collector = visit o.right, collector
|
|
371
|
-
collector <<
|
|
262
|
+
collector << ") + 1) % 7"
|
|
372
263
|
else
|
|
373
264
|
if o.with_interval
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
265
|
+
case o.left
|
|
266
|
+
when 'd','m','y'
|
|
267
|
+
interval = 'DAY'
|
|
268
|
+
when 'h','mn','s'
|
|
269
|
+
interval = 'SECOND'
|
|
270
|
+
when /i\z/
|
|
271
|
+
interval = Arel::Visitors::MySQL::DATE_MAPPING[o.left[0..-2]]
|
|
272
|
+
else
|
|
273
|
+
interval = nil
|
|
274
|
+
end
|
|
383
275
|
end
|
|
384
|
-
collector <<
|
|
385
|
-
collector << "#{DATE_MAPPING[o.left]}("
|
|
276
|
+
collector << " INTERVAL " if o.with_interval && interval
|
|
277
|
+
collector << "#{Arel::Visitors::MySQL::DATE_MAPPING[o.left]}("
|
|
386
278
|
collector = visit o.right, collector
|
|
387
|
-
collector <<
|
|
279
|
+
collector << ")"
|
|
388
280
|
collector << " #{interval} " if o.with_interval && interval
|
|
389
281
|
end
|
|
390
282
|
collector
|
|
391
283
|
end
|
|
392
284
|
|
|
393
|
-
|
|
394
|
-
|
|
285
|
+
|
|
286
|
+
def visit_ArelExtensions_Nodes_IsNull o, collector
|
|
287
|
+
collector << "ISNULL("
|
|
395
288
|
collector = visit o.expr, collector
|
|
396
|
-
collector <<
|
|
289
|
+
collector << ")"
|
|
397
290
|
collector
|
|
398
291
|
end
|
|
399
292
|
|
|
400
|
-
def visit_ArelExtensions_Nodes_IsNotNull
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
293
|
+
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
|
294
|
+
collector << "NOT ISNULL("
|
|
295
|
+
collector = visit o.expr, collector
|
|
296
|
+
collector << ")"
|
|
297
|
+
collector
|
|
405
298
|
end
|
|
406
299
|
|
|
407
|
-
def visit_ArelExtensions_Nodes_Wday
|
|
408
|
-
collector <<
|
|
300
|
+
def visit_ArelExtensions_Nodes_Wday o, collector
|
|
301
|
+
collector << "(WEEKDAY("
|
|
409
302
|
collector = visit o.date, collector
|
|
410
|
-
collector <<
|
|
303
|
+
collector << ") + 1) % 7"
|
|
411
304
|
collector
|
|
412
305
|
end
|
|
413
306
|
|
|
414
|
-
def visit_ArelExtensions_Nodes_Cast
|
|
415
|
-
|
|
416
|
-
case o.as_attr
|
|
417
|
-
when :binary then 'binary'
|
|
418
|
-
when :date then 'date'
|
|
419
|
-
when :datetime then 'datetime'
|
|
420
|
-
when :int then 'signed'
|
|
421
|
-
when :number, :decimal then 'decimal(20,6)'
|
|
422
|
-
when :string then 'char'
|
|
423
|
-
when :time then 'time'
|
|
424
|
-
else o.as_attr.to_s
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
collector << 'CAST('
|
|
307
|
+
def visit_ArelExtensions_Nodes_Cast o, collector
|
|
308
|
+
collector << "CAST("
|
|
428
309
|
collector = visit o.left, collector
|
|
429
|
-
collector <<
|
|
430
|
-
|
|
431
|
-
|
|
310
|
+
collector << " AS "
|
|
311
|
+
case o.as_attr
|
|
312
|
+
when :string
|
|
313
|
+
as_attr = Arel::Nodes::SqlLiteral.new('char')
|
|
314
|
+
when :time
|
|
315
|
+
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
|
316
|
+
when :int
|
|
317
|
+
as_attr = Arel::Nodes::SqlLiteral.new('signed')
|
|
318
|
+
when :number, :decimal
|
|
319
|
+
as_attr = Arel::Nodes::SqlLiteral.new('decimal(20,6)')
|
|
320
|
+
when :datetime
|
|
321
|
+
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
|
322
|
+
when :date
|
|
323
|
+
as_attr = Arel::Nodes::SqlLiteral.new('date')
|
|
324
|
+
when :binary
|
|
325
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
|
326
|
+
else
|
|
327
|
+
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
|
328
|
+
end
|
|
329
|
+
collector = visit as_attr, collector
|
|
330
|
+
collector << ")"
|
|
432
331
|
collector
|
|
433
332
|
end
|
|
434
333
|
|
|
435
|
-
|
|
436
|
-
def visit_Arel_Nodes_SelectStatement
|
|
334
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
|
335
|
+
def visit_Arel_Nodes_SelectStatement o, collector
|
|
437
336
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
|
438
337
|
o = o.dup
|
|
439
338
|
o.orders = []
|
|
440
339
|
end
|
|
441
|
-
old_visit_Arel_Nodes_SelectStatement(o,
|
|
340
|
+
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
|
442
341
|
end
|
|
443
342
|
|
|
444
|
-
|
|
445
|
-
def visit_Arel_Nodes_As
|
|
343
|
+
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
|
344
|
+
def visit_Arel_Nodes_As o, collector
|
|
446
345
|
if o.left.is_a?(Arel::Nodes::Binary)
|
|
447
346
|
collector << '('
|
|
448
347
|
collector = visit o.left, collector
|
|
@@ -450,56 +349,44 @@ module ArelExtensions
|
|
|
450
349
|
else
|
|
451
350
|
collector = visit o.left, collector
|
|
452
351
|
end
|
|
453
|
-
collector <<
|
|
454
|
-
|
|
455
|
-
# sometimes these values are already quoted, if they are, don't double quote it
|
|
456
|
-
quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '`' && o.right[-1] != '`'
|
|
457
|
-
|
|
458
|
-
collector << '`' if quote
|
|
352
|
+
collector << " AS `"
|
|
459
353
|
collector = visit o.right, collector
|
|
460
|
-
collector <<
|
|
461
|
-
|
|
354
|
+
collector << "`"
|
|
462
355
|
collector
|
|
463
356
|
end
|
|
464
357
|
|
|
465
|
-
def visit_ArelExtensions_Nodes_FormattedNumber
|
|
358
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
|
466
359
|
col = o.left.coalesce(0)
|
|
467
|
-
params = o.locale ? [o.precision,
|
|
468
|
-
sign =
|
|
360
|
+
params = o.locale ? [o.precision,Arel::Nodes.build_quoted(o.locale)] : [o.precision]
|
|
361
|
+
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
|
469
362
|
then('-').
|
|
470
363
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
|
471
364
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
|
472
365
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
Arel::Nodes
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
0
|
|
483
|
-
])
|
|
366
|
+
if o.scientific_notation
|
|
367
|
+
number = ArelExtensions::Nodes::Concat.new([
|
|
368
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
|
369
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
|
|
370
|
+
]+params),
|
|
371
|
+
o.type,
|
|
372
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
|
373
|
+
col.abs.log10.floor,
|
|
374
|
+
0
|
|
484
375
|
])
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
376
|
+
])
|
|
377
|
+
else
|
|
378
|
+
number = Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
|
|
379
|
+
end
|
|
488
380
|
|
|
489
|
-
repeated_char =
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
Arel
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
)
|
|
499
|
-
.else('')
|
|
500
|
-
end
|
|
501
|
-
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
502
|
-
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
381
|
+
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
|
382
|
+
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
|
383
|
+
then(Arel::Nodes.build_quoted(
|
|
384
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
|
385
|
+
).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
|
|
386
|
+
).
|
|
387
|
+
else('')
|
|
388
|
+
before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
389
|
+
middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
503
390
|
after = o.flags.include?('-') ? repeated_char : ''
|
|
504
391
|
full_number = ArelExtensions::Nodes::Concat.new([
|
|
505
392
|
before,
|
|
@@ -508,129 +395,66 @@ module ArelExtensions
|
|
|
508
395
|
number,
|
|
509
396
|
after
|
|
510
397
|
])
|
|
511
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel.
|
|
398
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
|
512
399
|
collector
|
|
513
400
|
end
|
|
514
401
|
|
|
515
|
-
def
|
|
516
|
-
|
|
517
|
-
warn('Warning: ArelExtensions: Window Functions are not available in the current version of the DBMS.')
|
|
518
|
-
return collector
|
|
519
|
-
end
|
|
520
|
-
|
|
521
|
-
if !o.order.empty? || !o.group.empty?
|
|
522
|
-
collector << ' OVER ('
|
|
523
|
-
if !o.group.empty?
|
|
524
|
-
collector << ' PARTITION BY ('
|
|
525
|
-
visit o.group, collector
|
|
526
|
-
collector << ')'
|
|
527
|
-
end
|
|
528
|
-
if !o.order.empty?
|
|
529
|
-
collector << ' ORDER BY ('
|
|
530
|
-
visit o.order, collector
|
|
531
|
-
collector << ')'
|
|
532
|
-
end
|
|
533
|
-
collector << ')'
|
|
534
|
-
end
|
|
535
|
-
collector
|
|
536
|
-
end
|
|
537
|
-
|
|
538
|
-
def visit_ArelExtensions_Nodes_Std(o, collector)
|
|
539
|
-
collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
|
|
402
|
+
def visit_ArelExtensions_Nodes_Std o, collector
|
|
403
|
+
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
|
540
404
|
visit o.left, collector
|
|
541
|
-
collector <<
|
|
542
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
405
|
+
collector << ")"
|
|
543
406
|
collector
|
|
544
407
|
end
|
|
545
408
|
|
|
546
|
-
def visit_ArelExtensions_Nodes_Variance
|
|
547
|
-
collector << (o.unbiased_estimator ?
|
|
409
|
+
def visit_ArelExtensions_Nodes_Variance o, collector
|
|
410
|
+
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
|
548
411
|
visit o.left, collector
|
|
549
|
-
collector <<
|
|
550
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
412
|
+
collector << ")"
|
|
551
413
|
collector
|
|
552
414
|
end
|
|
553
415
|
|
|
554
|
-
# JSON if implemented only after 10.2.3
|
|
416
|
+
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
|
555
417
|
def json_supported?
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
version_supported?('10.2.3', '8.0')
|
|
561
|
-
end
|
|
562
|
-
|
|
563
|
-
def regexp_replace_supported?
|
|
564
|
-
version_supported?('10.0.5', '8.0')
|
|
418
|
+
Arel::Table.engine.connection.send(:mariadb?) &&
|
|
419
|
+
Arel::Table.engine.connection.send(:version) >= '10.2.3' ||
|
|
420
|
+
!Arel::Table.engine.connection.send(:mariadb?) &&
|
|
421
|
+
Arel::Table.engine.connection.send(:version) >= '5.7.0'
|
|
565
422
|
end
|
|
566
423
|
|
|
567
|
-
def
|
|
568
|
-
conn = Arel::Table.engine.connection
|
|
569
|
-
conn.send(:mariadb?) &&
|
|
570
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mariadb_v ||
|
|
571
|
-
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v ||
|
|
572
|
-
conn.instance_variable_get(:@version) && conn.instance_variable_get(:@version) >= mariadb_v) ||
|
|
573
|
-
!conn.send(:mariadb?) &&
|
|
574
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v ||
|
|
575
|
-
conn.respond_to?(:version) && conn.send(:version) >= mysql_v ||
|
|
576
|
-
conn.instance_variable_get(:@version) && conn.instance_variable_get(:@version) >= mysql_v)
|
|
577
|
-
# ideally we should parse the instance_variable @full_version because @version contains only the supposedly
|
|
578
|
-
# corresponding mysql version of the current mariadb version (which is not very helpful most of the time)
|
|
579
|
-
end
|
|
580
|
-
|
|
581
|
-
def visit_ArelExtensions_Nodes_Json(o, collector)
|
|
424
|
+
def visit_ArelExtensions_Nodes_Json o,collector
|
|
582
425
|
return super if !json_supported?
|
|
583
|
-
|
|
584
426
|
case o.dict
|
|
585
427
|
when Array
|
|
586
428
|
collector << 'JSON_ARRAY('
|
|
587
|
-
o.dict.each.with_index do |v,
|
|
429
|
+
o.dict.each.with_index do |v,i|
|
|
588
430
|
if i != 0
|
|
589
|
-
collector << COMMA
|
|
431
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
590
432
|
end
|
|
591
|
-
collector =
|
|
433
|
+
collector = visit v, collector
|
|
592
434
|
end
|
|
593
435
|
collector << ')'
|
|
594
436
|
when Hash
|
|
595
437
|
collector << 'JSON_OBJECT('
|
|
596
|
-
o.dict.each.with_index do |(k,
|
|
438
|
+
o.dict.each.with_index do |(k,v),i|
|
|
597
439
|
if i != 0
|
|
598
|
-
collector << COMMA
|
|
440
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
599
441
|
end
|
|
600
442
|
collector = visit k, collector
|
|
601
|
-
collector << COMMA
|
|
602
|
-
collector =
|
|
443
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
444
|
+
collector = visit v, collector
|
|
603
445
|
end
|
|
604
446
|
collector << ')'
|
|
605
447
|
else
|
|
606
|
-
collector =
|
|
607
|
-
end
|
|
608
|
-
collector
|
|
609
|
-
end
|
|
610
|
-
|
|
611
|
-
# A JSON Boolean must render as `true`/`false`, not the integer `1`/`0` that MySQL
|
|
612
|
-
# collapses `TRUE`/`FALSE` into inside JSON functions (MariaDB keeps them boolean).
|
|
613
|
-
def visit_json_value(o, v, collector)
|
|
614
|
-
if o.boolean_literal?(v)
|
|
615
|
-
value = v.is_a?(Arel::Nodes::Quoted) ? v.expr : v
|
|
616
|
-
collector << "JSON_EXTRACT('#{value}', '$')"
|
|
617
|
-
elsif o.type_of_node(v) == :boolean
|
|
618
|
-
collector << 'JSON_EXTRACT(CASE WHEN '
|
|
619
|
-
collector = visit v, collector
|
|
620
|
-
collector << " IS NULL THEN NULL WHEN "
|
|
621
|
-
collector = visit v, collector
|
|
622
|
-
collector << " THEN 'true' ELSE 'false' END, '$')"
|
|
623
|
-
else
|
|
624
|
-
collector = visit v, collector
|
|
448
|
+
collector = visit o.dict, collector
|
|
625
449
|
end
|
|
626
450
|
collector
|
|
627
451
|
end
|
|
628
452
|
|
|
629
|
-
def visit_ArelExtensions_Nodes_JsonMerge
|
|
453
|
+
def visit_ArelExtensions_Nodes_JsonMerge o,collector
|
|
630
454
|
collector << 'JSON_MERGE_PATCH('
|
|
631
|
-
o.expressions.each.with_index do |v,
|
|
455
|
+
o.expressions.each.with_index do |v,i|
|
|
632
456
|
if i != 0
|
|
633
|
-
collector << COMMA
|
|
457
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
634
458
|
end
|
|
635
459
|
collector = visit v, collector
|
|
636
460
|
end
|
|
@@ -638,37 +462,36 @@ module ArelExtensions
|
|
|
638
462
|
collector
|
|
639
463
|
end
|
|
640
464
|
|
|
641
|
-
def visit_ArelExtensions_Nodes_JsonGet
|
|
465
|
+
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
|
642
466
|
collector << 'JSON_EXTRACT('
|
|
643
467
|
collector = visit o.dict, collector
|
|
644
|
-
collector << COMMA
|
|
468
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
645
469
|
if o.key.is_a?(Integer)
|
|
646
470
|
collector << "\"$[#{o.key}]\""
|
|
647
471
|
else
|
|
648
|
-
collector = visit Arel.
|
|
472
|
+
collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
|
|
649
473
|
end
|
|
650
474
|
collector << ')'
|
|
651
475
|
collector
|
|
652
476
|
end
|
|
653
477
|
|
|
654
|
-
def visit_ArelExtensions_Nodes_JsonSet
|
|
478
|
+
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
|
655
479
|
collector << 'JSON_SET('
|
|
656
480
|
collector = visit o.dict, collector
|
|
657
|
-
collector << COMMA
|
|
481
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
658
482
|
if o.key.is_a?(Integer)
|
|
659
483
|
collector << "\"$[#{o.key}]\""
|
|
660
484
|
else
|
|
661
|
-
collector = visit Arel.
|
|
485
|
+
collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
|
|
662
486
|
end
|
|
663
|
-
collector << COMMA
|
|
487
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
664
488
|
collector = visit o.value, collector
|
|
665
489
|
collector << ')'
|
|
666
490
|
collector
|
|
667
491
|
end
|
|
668
492
|
|
|
669
|
-
def visit_ArelExtensions_Nodes_JsonGroup
|
|
493
|
+
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
|
670
494
|
return super if !json_supported?
|
|
671
|
-
|
|
672
495
|
if o.as_array
|
|
673
496
|
collector << 'JSON_ARRAYAGG('
|
|
674
497
|
collector = visit o.dict, collector
|
|
@@ -677,13 +500,13 @@ module ArelExtensions
|
|
|
677
500
|
case o.dict
|
|
678
501
|
when Hash
|
|
679
502
|
collector << 'JSON_MERGE_PATCH(' if o.dict.length > 1
|
|
680
|
-
o.dict.each.with_index do |(k,
|
|
503
|
+
o.dict.each.with_index do |(k,v),i|
|
|
681
504
|
if i != 0
|
|
682
|
-
collector << COMMA
|
|
505
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
683
506
|
end
|
|
684
507
|
collector << 'JSON_OBJECTAGG('
|
|
685
508
|
collector = visit k, collector
|
|
686
|
-
collector << COMMA
|
|
509
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
687
510
|
collector = visit v, collector
|
|
688
511
|
collector << ')'
|
|
689
512
|
end
|
|
@@ -696,6 +519,7 @@ module ArelExtensions
|
|
|
696
519
|
end
|
|
697
520
|
collector
|
|
698
521
|
end
|
|
522
|
+
|
|
699
523
|
end
|
|
700
524
|
end
|
|
701
525
|
end
|