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,365 +1,207 @@
|
|
|
1
1
|
module ArelExtensions
|
|
2
2
|
module Visitors
|
|
3
3
|
module MSSQL
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'wd' => 'weekday', 'w' => 'week',
|
|
24
|
-
'h' => 'hour', 'mn' => 'minute', 's' => 'second'
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
|
-
LOADED_VISITOR::DATE_FORMAT_DIRECTIVES = {
|
|
28
|
-
'%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => 'month', '%^B' => '', '%b' => '', '%^b' => '', # year, month
|
|
29
|
-
'%V' => 'iso_week', '%G' => '', # ISO week number and year of week
|
|
30
|
-
'%d' => 'DD', '%e' => '' , '%j' => '' , '%w' => 'dw', %'a' => '', '%A' => 'weekday', # day, weekday
|
|
31
|
-
'%H' => 'hh', '%k' => '' , '%I' => '' , '%l' => '' , '%P' => '', '%p' => '', # hours
|
|
32
|
-
'%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
|
|
33
|
-
}.freeze
|
|
34
|
-
|
|
35
|
-
LOADED_VISITOR::DATE_FORMAT_FORMAT = {
|
|
36
|
-
'YY' => '0#', 'MM' => '0#', 'DD' => '0#',
|
|
37
|
-
'hh' => '0#', 'mi' => '0#', 'ss' => '0#',
|
|
38
|
-
'iso_week' => '0#'
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
LOADED_VISITOR::DATE_NAME = [
|
|
42
|
-
'%B', '%A'
|
|
43
|
-
]
|
|
44
|
-
|
|
45
|
-
LOADED_VISITOR::DATE_FORMAT_REGEX =
|
|
46
|
-
Regexp.new(
|
|
47
|
-
LOADED_VISITOR::DATE_FORMAT_DIRECTIVES
|
|
48
|
-
.keys
|
|
49
|
-
.map { |k| Regexp.escape(k) }
|
|
50
|
-
.join('|')
|
|
51
|
-
).freeze
|
|
52
|
-
|
|
53
|
-
# TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
|
|
54
|
-
LOADED_VISITOR::DATE_CONVERT_FORMATS = {
|
|
55
|
-
'YYYY-MM-DD' => 120,
|
|
56
|
-
'YY-MM-DD' => 120,
|
|
57
|
-
'MM/DD/YYYY' => 101,
|
|
58
|
-
'MM-DD-YYYY' => 110,
|
|
59
|
-
'YYYY/MM/DD' => 111,
|
|
60
|
-
'DD-MM-YYYY' => 105,
|
|
61
|
-
'DD-MM-YY' => 5,
|
|
62
|
-
'DD.MM.YYYY' => 104,
|
|
63
|
-
'YYYY-MM-DDTHH:MM:SS:MMM' => 126
|
|
64
|
-
}.freeze
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Quoting in JRuby + AR < 5 requires special handling for MSSQL.
|
|
68
|
-
#
|
|
69
|
-
# It relied on @connection.quote, which in turn relied on column type for
|
|
70
|
-
# quoting. We need only to rely on the value type.
|
|
71
|
-
#
|
|
72
|
-
# It didn't handle numbers correctly: `quote(1, nil)` translated into
|
|
73
|
-
# `N'1'` which we don't want.
|
|
74
|
-
#
|
|
75
|
-
# The following is adapted from
|
|
76
|
-
# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
|
|
77
|
-
#
|
|
78
|
-
if RUBY_PLATFORM == 'java' && AREL_VERSION <= V6
|
|
79
|
-
def quote_string(s)
|
|
80
|
-
s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def quoted_binary(value) # :nodoc:
|
|
84
|
-
"'#{quote_string(value.to_s)}'"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def quoted_date(value)
|
|
88
|
-
if value.acts_like?(:time)
|
|
89
|
-
if (ActiveRecord.respond_to?(:default_timezone) && ActiveRecord.default_timezone == :utc) || ActiveRecord::Base.default_timezone == :utc
|
|
90
|
-
value = value.getutc if value.respond_to?(:getutc) && !value.utc?
|
|
91
|
-
elsif value.respond_to?(:getlocal)
|
|
92
|
-
value = value.getlocal
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
# new versions of AR use `to_fs`, but we want max compatibility, and we're
|
|
96
|
-
# not going to write it over and over, so it's fine like that.
|
|
97
|
-
result = value.to_formatted_s(:db)
|
|
98
|
-
if value.respond_to?(:usec) && value.usec > 0
|
|
99
|
-
result << '.' << format('%06d', value.usec)
|
|
100
|
-
else
|
|
101
|
-
result
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def quoted_true
|
|
106
|
-
'TRUE'
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def quoted_false
|
|
110
|
-
'FALSE'
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def quoted_time(value) # :nodoc:
|
|
114
|
-
value = value.change(year: 2000, month: 1, day: 1)
|
|
115
|
-
quoted_date(value).sub(/\A\d{4}-\d{2}-\d{2} /, '')
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def quote(value, _column = nil)
|
|
119
|
-
case value
|
|
120
|
-
when Arel::Nodes::SqlLiteral
|
|
121
|
-
value
|
|
122
|
-
when String, Symbol, ActiveSupport::Multibyte::Chars
|
|
123
|
-
"'#{quote_string(value.to_s)}'"
|
|
124
|
-
when true
|
|
125
|
-
quoted_true
|
|
126
|
-
when false
|
|
127
|
-
quoted_false
|
|
128
|
-
when nil
|
|
129
|
-
'NULL'
|
|
130
|
-
# BigDecimals need to be put in a non-normalized form and quoted.
|
|
131
|
-
when BigDecimal
|
|
132
|
-
value.to_s('F')
|
|
133
|
-
when Numeric, ActiveSupport::Duration
|
|
134
|
-
value.to_s
|
|
135
|
-
when AREL_VERSION > V6 && ActiveRecord::Type::Time::Value
|
|
136
|
-
"'#{quoted_time(value)}'"
|
|
137
|
-
when Date, Time
|
|
138
|
-
"'#{quoted_date(value)}'"
|
|
139
|
-
when Class
|
|
140
|
-
"'#{value}'"
|
|
141
|
-
else
|
|
142
|
-
raise TypeError, "can't quote #{value.class.name}"
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
alias old_primary_Key_From_Table primary_Key_From_Table rescue nil
|
|
148
|
-
def primary_Key_From_Table(t)
|
|
149
|
-
return unless t
|
|
150
|
-
|
|
151
|
-
column_name = @connection.schema_cache.primary_keys(t.name) ||
|
|
152
|
-
@connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
|
|
153
|
-
column_name ? t[column_name] : nil
|
|
154
|
-
end
|
|
4
|
+
Arel::Visitors::MSSQL::DATE_MAPPING = {'d' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'}
|
|
5
|
+
Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
|
|
6
|
+
'%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
|
|
7
|
+
'%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
|
|
8
|
+
'%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
|
|
9
|
+
'%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
|
|
10
|
+
}
|
|
11
|
+
# TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
|
|
12
|
+
Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
|
|
13
|
+
'YYYY-MM-DD' => 120,
|
|
14
|
+
'YY-MM-DD' => 120,
|
|
15
|
+
'MM/DD/YYYY' => 101,
|
|
16
|
+
'MM-DD-YYYY' => 110,
|
|
17
|
+
'YYYY/MM/DD' => 111,
|
|
18
|
+
'DD-MM-YYYY' => 105,
|
|
19
|
+
'DD-MM-YY' => 5,
|
|
20
|
+
'DD.MM.YYYY' => 104,
|
|
21
|
+
'YYYY-MM-DDTHH:MM:SS:MMM' => 126
|
|
22
|
+
}
|
|
155
23
|
|
|
156
24
|
# Math Functions
|
|
157
|
-
def visit_ArelExtensions_Nodes_Ceil
|
|
158
|
-
collector <<
|
|
25
|
+
def visit_ArelExtensions_Nodes_Ceil o, collector
|
|
26
|
+
collector << "CEILING("
|
|
159
27
|
collector = visit o.expr, collector
|
|
160
|
-
collector <<
|
|
28
|
+
collector << ")"
|
|
161
29
|
collector
|
|
162
30
|
end
|
|
163
31
|
|
|
164
|
-
def visit_ArelExtensions_Nodes_Log10
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
32
|
+
def visit_ArelExtensions_Nodes_Log10 o, collector
|
|
33
|
+
collector << "LOG10("
|
|
34
|
+
o.expressions.each_with_index { |arg, i|
|
|
35
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
36
|
+
collector = visit arg, collector
|
|
37
|
+
}
|
|
38
|
+
collector << ")"
|
|
39
|
+
collector
|
|
172
40
|
end
|
|
173
41
|
|
|
174
|
-
def visit_ArelExtensions_Nodes_Power
|
|
175
|
-
collector <<
|
|
42
|
+
def visit_ArelExtensions_Nodes_Power o, collector
|
|
43
|
+
collector << "POWER("
|
|
176
44
|
o.expressions.each_with_index { |arg, i|
|
|
177
|
-
collector <<
|
|
45
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
178
46
|
collector = visit arg, collector
|
|
179
47
|
}
|
|
180
|
-
collector <<
|
|
48
|
+
collector << ")"
|
|
181
49
|
collector
|
|
182
50
|
end
|
|
183
51
|
|
|
184
|
-
def visit_ArelExtensions_Nodes_IsNull
|
|
185
|
-
collector <<
|
|
52
|
+
def visit_ArelExtensions_Nodes_IsNull o, collector
|
|
53
|
+
collector << "("
|
|
186
54
|
collector = visit o.expr, collector
|
|
187
|
-
collector <<
|
|
55
|
+
collector << " IS NULL)"
|
|
188
56
|
collector
|
|
189
57
|
end
|
|
190
58
|
|
|
191
|
-
def visit_ArelExtensions_Nodes_IsNotNull
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
59
|
+
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
|
60
|
+
collector << "("
|
|
61
|
+
collector = visit o.expr, collector
|
|
62
|
+
collector << " IS NOT NULL)"
|
|
63
|
+
collector
|
|
196
64
|
end
|
|
197
65
|
|
|
198
|
-
def visit_ArelExtensions_Nodes_Concat
|
|
199
|
-
collector <<
|
|
66
|
+
def visit_ArelExtensions_Nodes_Concat o, collector
|
|
67
|
+
collector << "CONCAT("
|
|
200
68
|
o.expressions.each_with_index { |arg, i|
|
|
201
|
-
collector <<
|
|
69
|
+
collector << Arel::Visitors::MSSQL::COMMA unless i == 0
|
|
202
70
|
collector = visit arg, collector
|
|
203
71
|
}
|
|
204
|
-
collector <<
|
|
72
|
+
collector << ")"
|
|
205
73
|
collector
|
|
206
74
|
end
|
|
207
75
|
|
|
208
|
-
def visit_ArelExtensions_Nodes_Repeat
|
|
209
|
-
collector <<
|
|
76
|
+
def visit_ArelExtensions_Nodes_Repeat o, collector
|
|
77
|
+
collector << "REPLICATE("
|
|
210
78
|
o.expressions.each_with_index { |arg, i|
|
|
211
|
-
collector <<
|
|
79
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
212
80
|
collector = visit arg, collector
|
|
213
81
|
}
|
|
214
|
-
collector <<
|
|
82
|
+
collector << ")"
|
|
215
83
|
collector
|
|
216
84
|
end
|
|
217
85
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
|
89
|
+
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
|
|
90
|
+
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
|
91
|
+
'DATEDIFF(second'
|
|
92
|
+
else
|
|
93
|
+
'DATEDIFF(day'
|
|
94
|
+
end
|
|
95
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
226
96
|
collector = visit o.right, collector
|
|
227
|
-
collector <<
|
|
97
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
228
98
|
collector = visit o.left, collector
|
|
229
99
|
collector << ')'
|
|
230
100
|
else
|
|
231
101
|
da = ArelExtensions::Nodes::DateAdd.new([])
|
|
232
|
-
collector <<
|
|
102
|
+
collector << "DATEADD("
|
|
233
103
|
collector = visit da.mssql_datepart(o.right), collector
|
|
234
|
-
collector <<
|
|
235
|
-
collector <<
|
|
104
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
105
|
+
collector << "-("
|
|
236
106
|
collector = visit da.mssql_value(o.right), collector
|
|
237
|
-
collector <<
|
|
238
|
-
collector <<
|
|
107
|
+
collector << ")"
|
|
108
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
239
109
|
collector = visit o.left, collector
|
|
240
|
-
collector <<
|
|
110
|
+
collector << ")"
|
|
241
111
|
collector
|
|
242
112
|
end
|
|
243
113
|
collector
|
|
244
114
|
end
|
|
245
115
|
|
|
246
|
-
def visit_ArelExtensions_Nodes_DateAdd
|
|
247
|
-
collector <<
|
|
116
|
+
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
|
117
|
+
collector << "DATEADD("
|
|
248
118
|
collector = visit o.mssql_datepart(o.right), collector
|
|
249
|
-
collector <<
|
|
119
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
250
120
|
collector = visit o.mssql_value(o.right), collector
|
|
251
|
-
collector <<
|
|
121
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
252
122
|
collector = visit o.left, collector
|
|
253
|
-
collector <<
|
|
123
|
+
collector << ")"
|
|
254
124
|
collector
|
|
255
125
|
end
|
|
256
126
|
|
|
257
|
-
def visit_ArelExtensions_Nodes_Duration
|
|
127
|
+
def visit_ArelExtensions_Nodes_Duration o, collector
|
|
258
128
|
if o.with_interval && o.left.end_with?('i')
|
|
259
129
|
collector = visit o.right, collector
|
|
260
130
|
else
|
|
261
131
|
left = o.left.end_with?('i') ? o.left[0..-2] : o.left
|
|
262
|
-
conv =
|
|
132
|
+
conv = ['h', 'mn', 's'].include?(o.left)
|
|
263
133
|
collector << 'DATEPART('
|
|
264
|
-
collector <<
|
|
265
|
-
collector <<
|
|
134
|
+
collector << Arel::Visitors::MSSQL::DATE_MAPPING[left]
|
|
135
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
266
136
|
collector << 'CONVERT(datetime,' if conv
|
|
267
137
|
collector = visit o.right, collector
|
|
268
138
|
collector << ')' if conv
|
|
269
|
-
collector <<
|
|
139
|
+
collector << ")"
|
|
270
140
|
end
|
|
271
141
|
collector
|
|
272
142
|
end
|
|
273
143
|
|
|
274
|
-
def
|
|
275
|
-
collector <<
|
|
276
|
-
collector = visit o.expr
|
|
277
|
-
collector <<
|
|
278
|
-
collector
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def visit_ArelExtensions_Nodes_CharLength(o, collector)
|
|
282
|
-
# According to the docs https://learn.microsoft.com/en-us/sql/t-sql/functions/len-transact-sql?view=sql-server-ver17
|
|
283
|
-
# LEN doesn't take into account the trailing white space, and that's why
|
|
284
|
-
# we need to do acrobatics.
|
|
285
|
-
collector << 'LEN('
|
|
286
|
-
collector = visit o.expr.coalesce(''), collector
|
|
287
|
-
collector << " + 'x') - 1"
|
|
144
|
+
def visit_ArelExtensions_Nodes_Length o, collector
|
|
145
|
+
collector << "LEN("
|
|
146
|
+
collector = visit o.expr, collector
|
|
147
|
+
collector << ")"
|
|
288
148
|
collector
|
|
289
149
|
end
|
|
290
150
|
|
|
291
|
-
def
|
|
292
|
-
|
|
293
|
-
collector << '(DATALENGTH('
|
|
294
|
-
collector = visit o.expr, collector
|
|
295
|
-
collector << ') / ISNULL(NULLIF(DATALENGTH(LEFT(COALESCE('
|
|
296
|
-
collector = visit o.expr, collector
|
|
297
|
-
collector << ", '#' ), 1 )), 0), 1))"
|
|
298
|
-
collector
|
|
299
|
-
else
|
|
300
|
-
collector << 'LEN('
|
|
301
|
-
collector = visit o.expr, collector
|
|
302
|
-
collector << ')'
|
|
303
|
-
collector
|
|
304
|
-
end
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
def visit_ArelExtensions_Nodes_Round(o, collector)
|
|
308
|
-
collector << 'ROUND('
|
|
151
|
+
def visit_ArelExtensions_Nodes_Round o, collector
|
|
152
|
+
collector << "ROUND("
|
|
309
153
|
o.expressions.each_with_index { |arg, i|
|
|
310
|
-
collector <<
|
|
154
|
+
collector << Arel::Visitors::MSSQL::COMMA unless i == 0
|
|
311
155
|
collector = visit arg, collector
|
|
312
156
|
}
|
|
313
157
|
if o.expressions.length == 1
|
|
314
|
-
collector <<
|
|
315
|
-
collector <<
|
|
158
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
159
|
+
collector << "0"
|
|
316
160
|
end
|
|
317
|
-
collector <<
|
|
161
|
+
collector << ")"
|
|
318
162
|
collector
|
|
319
163
|
end
|
|
320
164
|
|
|
321
|
-
def visit_ArelExtensions_Nodes_Locate
|
|
322
|
-
collector <<
|
|
165
|
+
def visit_ArelExtensions_Nodes_Locate o, collector
|
|
166
|
+
collector << "CHARINDEX("
|
|
323
167
|
collector = visit o.right, collector
|
|
324
|
-
collector <<
|
|
168
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
325
169
|
collector = visit o.left, collector
|
|
326
|
-
collector <<
|
|
170
|
+
collector << ")"
|
|
327
171
|
collector
|
|
328
172
|
end
|
|
329
173
|
|
|
330
|
-
def visit_ArelExtensions_Nodes_Substring
|
|
331
|
-
return visit(o.range_substring_node, collector) if o.range?
|
|
332
|
-
|
|
174
|
+
def visit_ArelExtensions_Nodes_Substring o, collector
|
|
333
175
|
collector << 'SUBSTRING('
|
|
334
176
|
collector = visit o.expressions[0], collector
|
|
335
|
-
collector <<
|
|
177
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
336
178
|
collector = visit o.expressions[1], collector
|
|
337
|
-
collector <<
|
|
179
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
338
180
|
collector = o.expressions[2] ? visit(o.expressions[2], collector) : visit(o.expressions[0].length, collector)
|
|
339
181
|
collector << ')'
|
|
340
182
|
collector
|
|
341
183
|
end
|
|
342
184
|
|
|
343
|
-
def visit_ArelExtensions_Nodes_Trim
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if o.right && !/\A\s\Z/.match(o.right.expr)
|
|
347
|
-
collector << 'dbo.TrimChar('
|
|
185
|
+
def visit_ArelExtensions_Nodes_Trim o, collector
|
|
186
|
+
if o.right
|
|
187
|
+
collector << "REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE("
|
|
348
188
|
collector = visit o.left, collector
|
|
349
|
-
collector <<
|
|
189
|
+
collector << ", ' ', '~'), "
|
|
350
190
|
collector = visit o.right, collector
|
|
351
|
-
collector << ')'
|
|
191
|
+
collector << ", ' '))), ' ', "
|
|
192
|
+
collector = visit o.right, collector
|
|
193
|
+
collector << "), '~', ' ')"
|
|
352
194
|
else
|
|
353
|
-
collector <<
|
|
195
|
+
collector << "LTRIM(RTRIM("
|
|
354
196
|
collector = visit o.left, collector
|
|
355
|
-
collector <<
|
|
197
|
+
collector << "))"
|
|
356
198
|
end
|
|
357
199
|
collector
|
|
358
200
|
end
|
|
359
201
|
|
|
360
|
-
def visit_ArelExtensions_Nodes_Ltrim
|
|
202
|
+
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
|
361
203
|
if o.right
|
|
362
|
-
collector <<
|
|
204
|
+
collector << "REPLACE(REPLACE(LTRIM(REPLACE(REPLACE("
|
|
363
205
|
collector = visit o.left, collector
|
|
364
206
|
collector << ", ' ', '~'), "
|
|
365
207
|
collector = visit o.right, collector
|
|
@@ -367,16 +209,16 @@ module ArelExtensions
|
|
|
367
209
|
collector = visit o.right, collector
|
|
368
210
|
collector << "), '~', ' ')"
|
|
369
211
|
else
|
|
370
|
-
collector <<
|
|
212
|
+
collector << "LTRIM("
|
|
371
213
|
collector = visit o.left, collector
|
|
372
|
-
collector <<
|
|
214
|
+
collector << ")"
|
|
373
215
|
end
|
|
374
216
|
collector
|
|
375
217
|
end
|
|
376
218
|
|
|
377
|
-
def visit_ArelExtensions_Nodes_Rtrim
|
|
219
|
+
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
|
378
220
|
if o.right
|
|
379
|
-
collector <<
|
|
221
|
+
collector << "REPLACE(REPLACE(RTRIM(REPLACE(REPLACE("
|
|
380
222
|
collector = visit o.left, collector
|
|
381
223
|
collector << ", ' ', '~'), "
|
|
382
224
|
collector = visit o.right, collector
|
|
@@ -384,123 +226,85 @@ module ArelExtensions
|
|
|
384
226
|
collector = visit o.right, collector
|
|
385
227
|
collector << "), '~', ' ')"
|
|
386
228
|
else
|
|
387
|
-
collector <<
|
|
229
|
+
collector << "RTRIM("
|
|
388
230
|
collector = visit o.left, collector
|
|
389
|
-
collector <<
|
|
231
|
+
collector << ")"
|
|
390
232
|
end
|
|
391
233
|
collector
|
|
392
234
|
end
|
|
393
235
|
|
|
394
|
-
def visit_ArelExtensions_Nodes_Blank
|
|
236
|
+
def visit_ArelExtensions_Nodes_Blank o, collector
|
|
395
237
|
visit o.expr.coalesce('').trim.length.eq(0), collector
|
|
396
238
|
end
|
|
397
239
|
|
|
398
|
-
def visit_ArelExtensions_Nodes_NotBlank
|
|
240
|
+
def visit_ArelExtensions_Nodes_NotBlank o, collector
|
|
399
241
|
visit o.expr.coalesce('').trim.length.gt(0), collector
|
|
400
242
|
end
|
|
401
243
|
|
|
402
|
-
def visit_ArelExtensions_Nodes_Format
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
def visit_ArelExtensions_Nodes_FormattedDate(o, collector)
|
|
407
|
-
f = ArelExtensions::Visitors.strftime_to_format(o.iso_format, LOADED_VISITOR::DATE_FORMAT_DIRECTIVES)
|
|
408
|
-
if fmt = LOADED_VISITOR::DATE_CONVERT_FORMATS[f]
|
|
244
|
+
def visit_ArelExtensions_Nodes_Format o, collector
|
|
245
|
+
f = o.iso_format.dup
|
|
246
|
+
Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
|
247
|
+
if Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
|
|
409
248
|
collector << "CONVERT(VARCHAR(#{f.length})"
|
|
410
|
-
collector <<
|
|
411
|
-
if o.time_zone
|
|
412
|
-
collector << 'CONVERT(datetime'
|
|
413
|
-
collector << LOADED_VISITOR::COMMA
|
|
414
|
-
collector << ' '
|
|
415
|
-
end
|
|
249
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
416
250
|
collector = visit o.left, collector
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
src_tz, dst_tz = o.time_zone.first
|
|
420
|
-
collector << ') AT TIME ZONE '
|
|
421
|
-
collector = visit Arel.quoted(src_tz), collector
|
|
422
|
-
collector << ' AT TIME ZONE '
|
|
423
|
-
collector = visit Arel.quoted(dst_tz), collector
|
|
424
|
-
when String
|
|
425
|
-
collector << ') AT TIME ZONE '
|
|
426
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
|
427
|
-
end
|
|
428
|
-
collector << LOADED_VISITOR::COMMA
|
|
429
|
-
collector << fmt.to_s
|
|
251
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
252
|
+
collector << Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f].to_s
|
|
430
253
|
collector << ')'
|
|
431
254
|
collector
|
|
432
255
|
else
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
fmt = LOADED_VISITOR::DATE_FORMAT_FORMAT[dir]
|
|
442
|
-
date_name = LOADED_VISITOR::DATE_NAME.include?(s.matched)
|
|
443
|
-
collector << 'LTRIM(RTRIM('
|
|
444
|
-
collector << 'FORMAT(' if fmt
|
|
445
|
-
collector << 'STR(' if !fmt && !date_name
|
|
446
|
-
collector << (date_name ? 'DATENAME(' : 'DATEPART(')
|
|
447
|
-
collector << dir
|
|
448
|
-
collector << LOADED_VISITOR::COMMA
|
|
449
|
-
if o.time_zone
|
|
450
|
-
collector << 'CONVERT(datetime'
|
|
451
|
-
collector << LOADED_VISITOR::COMMA
|
|
452
|
-
collector << ' '
|
|
256
|
+
collector << "("
|
|
257
|
+
t = o.iso_format.split('%')
|
|
258
|
+
t.each_with_index {|str, i|
|
|
259
|
+
if i == 0 && t[0] != '%'
|
|
260
|
+
collector = visit Arel::Nodes.build_quoted(str), collector
|
|
261
|
+
if str.length > 1
|
|
262
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
263
|
+
collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
|
|
453
264
|
end
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
collector
|
|
460
|
-
collector
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
|
265
|
+
elsif str.length > 0
|
|
266
|
+
if !Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]].blank?
|
|
267
|
+
collector << 'LTRIM(STR(DATEPART('
|
|
268
|
+
collector << Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]]
|
|
269
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
|
270
|
+
collector = visit o.left, collector
|
|
271
|
+
collector << ')))'
|
|
272
|
+
if str.length > 1
|
|
273
|
+
collector << ' + '
|
|
274
|
+
collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
|
|
275
|
+
end
|
|
466
276
|
end
|
|
467
|
-
collector << ')'
|
|
468
|
-
collector << ')' if !fmt && !date_name
|
|
469
|
-
collector << LOADED_VISITOR::COMMA << "'#{fmt}')" if fmt
|
|
470
|
-
collector << '))'
|
|
471
|
-
elsif s.scan(/^%%/)
|
|
472
|
-
collector = visit Arel.quoted('%'), collector
|
|
473
|
-
elsif s.scan(/[^%]+|./)
|
|
474
|
-
collector = visit Arel.quoted(s.matched), collector
|
|
475
277
|
end
|
|
476
|
-
|
|
278
|
+
collector << ' + ' if t[i + 1]
|
|
279
|
+
}
|
|
280
|
+
|
|
477
281
|
collector << ')'
|
|
478
282
|
collector
|
|
479
283
|
end
|
|
480
284
|
end
|
|
481
285
|
|
|
482
|
-
def visit_ArelExtensions_Nodes_Replace
|
|
483
|
-
collector <<
|
|
286
|
+
def visit_ArelExtensions_Nodes_Replace o, collector
|
|
287
|
+
collector << "REPLACE("
|
|
484
288
|
o.expressions.each_with_index { |arg, i|
|
|
485
|
-
collector <<
|
|
289
|
+
collector << Arel::Visitors::MSSQL::COMMA unless i == 0
|
|
486
290
|
collector = visit arg, collector
|
|
487
291
|
}
|
|
488
|
-
collector <<
|
|
292
|
+
collector << ")"
|
|
489
293
|
collector
|
|
490
294
|
end
|
|
491
295
|
|
|
492
|
-
def visit_ArelExtensions_Nodes_FindInSet
|
|
493
|
-
collector <<
|
|
296
|
+
def visit_ArelExtensions_Nodes_FindInSet o, collector
|
|
297
|
+
collector << "dbo.FIND_IN_SET("
|
|
494
298
|
o.expressions.each_with_index { |arg, i|
|
|
495
|
-
collector <<
|
|
299
|
+
collector << Arel::Visitors::MSSQL::COMMA unless i == 0
|
|
496
300
|
collector = visit arg, collector
|
|
497
301
|
}
|
|
498
|
-
collector <<
|
|
302
|
+
collector << ")"
|
|
499
303
|
collector
|
|
500
304
|
end
|
|
501
305
|
|
|
502
306
|
# TODO; manage case insensitivity
|
|
503
|
-
def visit_ArelExtensions_Nodes_IMatches
|
|
307
|
+
def visit_ArelExtensions_Nodes_IMatches o, collector
|
|
504
308
|
collector = visit o.left.ci_collate, collector
|
|
505
309
|
collector << ' LIKE '
|
|
506
310
|
collector = visit o.right.ci_collate, collector
|
|
@@ -513,7 +317,7 @@ module ArelExtensions
|
|
|
513
317
|
end
|
|
514
318
|
|
|
515
319
|
# TODO; manage case insensitivity
|
|
516
|
-
def visit_ArelExtensions_Nodes_IDoesNotMatch
|
|
320
|
+
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
|
517
321
|
collector = visit o.left.ci_collate, collector
|
|
518
322
|
collector << ' NOT LIKE '
|
|
519
323
|
collector = visit o.right.ci_collate, collector
|
|
@@ -525,7 +329,7 @@ module ArelExtensions
|
|
|
525
329
|
end
|
|
526
330
|
end
|
|
527
331
|
|
|
528
|
-
def visit_ArelExtensions_Nodes_AiMatches
|
|
332
|
+
def visit_ArelExtensions_Nodes_AiMatches o, collector
|
|
529
333
|
collector = visit o.left.ai_collate, collector
|
|
530
334
|
collector << ' LIKE '
|
|
531
335
|
collector = visit o.right.ai_collate, collector
|
|
@@ -537,10 +341,10 @@ module ArelExtensions
|
|
|
537
341
|
end
|
|
538
342
|
end
|
|
539
343
|
|
|
540
|
-
def visit_ArelExtensions_Nodes_AiIMatches
|
|
541
|
-
collector = visit o.left.collate(true,
|
|
344
|
+
def visit_ArelExtensions_Nodes_AiIMatches o, collector
|
|
345
|
+
collector = visit o.left.collate(true,true), collector
|
|
542
346
|
collector << ' LIKE '
|
|
543
|
-
collector = visit o.right.collate(true,
|
|
347
|
+
collector = visit o.right.collate(true,true), collector
|
|
544
348
|
if o.escape
|
|
545
349
|
collector << ' ESCAPE '
|
|
546
350
|
visit o.escape, collector
|
|
@@ -549,7 +353,7 @@ module ArelExtensions
|
|
|
549
353
|
end
|
|
550
354
|
end
|
|
551
355
|
|
|
552
|
-
def visit_ArelExtensions_Nodes_SMatches
|
|
356
|
+
def visit_ArelExtensions_Nodes_SMatches o, collector
|
|
553
357
|
collector = visit o.left.collate, collector
|
|
554
358
|
collector << ' LIKE '
|
|
555
359
|
collector = visit o.right.collate, collector
|
|
@@ -561,7 +365,7 @@ module ArelExtensions
|
|
|
561
365
|
end
|
|
562
366
|
end
|
|
563
367
|
|
|
564
|
-
def visit_ArelExtensions_Nodes_Collate
|
|
368
|
+
def visit_ArelExtensions_Nodes_Collate o, collector
|
|
565
369
|
if o.ai && o.ci
|
|
566
370
|
collector = visit o.expressions.first, collector
|
|
567
371
|
collector << ' COLLATE Latin1_General_CI_AI'
|
|
@@ -578,162 +382,121 @@ module ArelExtensions
|
|
|
578
382
|
collector
|
|
579
383
|
end
|
|
580
384
|
|
|
581
|
-
alias old_visit_Arel_Nodes_As visit_Arel_Nodes_As rescue nil
|
|
582
|
-
def visit_Arel_Nodes_As(o, collector)
|
|
583
|
-
if o.left.is_a?(Arel::Nodes::Binary)
|
|
584
|
-
collector << '('
|
|
585
|
-
collector = visit o.left, collector
|
|
586
|
-
collector << ')'
|
|
587
|
-
else
|
|
588
|
-
collector = visit o.left, collector
|
|
589
|
-
end
|
|
590
|
-
collector << ' AS '
|
|
591
|
-
# Sometimes these values are already quoted, if they are, don't double quote it
|
|
592
|
-
lft, rgt =
|
|
593
|
-
if o.right.is_a?(Arel::Nodes::SqlLiteral)
|
|
594
|
-
if AREL_VERSION >= V6 && o.right[0] != '[' && o.right[-1] != ']'
|
|
595
|
-
# This is a lie, it's not about arel version, but SQL Server's (>= 2000).
|
|
596
|
-
%w([ ])
|
|
597
|
-
elsif ACTIVE_RECORD_VERSION < V8_1 && o.right[0] != '"' && o.right[-1] != '"'
|
|
598
|
-
%w[" "]
|
|
599
|
-
else
|
|
600
|
-
[]
|
|
601
|
-
end
|
|
602
|
-
end
|
|
603
|
-
collector << lft if lft
|
|
604
|
-
collector = visit o.right, collector
|
|
605
|
-
collector << rgt if rgt
|
|
606
|
-
collector
|
|
607
|
-
end
|
|
608
|
-
|
|
609
385
|
# SQL Server does not know about REGEXP
|
|
610
|
-
def visit_Arel_Nodes_Regexp
|
|
386
|
+
def visit_Arel_Nodes_Regexp o, collector
|
|
611
387
|
collector = visit o.left, collector
|
|
612
388
|
collector << "LIKE '%#{o.right}%'"
|
|
613
389
|
collector
|
|
614
390
|
end
|
|
615
391
|
|
|
616
|
-
def visit_Arel_Nodes_NotRegexp
|
|
392
|
+
def visit_Arel_Nodes_NotRegexp o, collector
|
|
617
393
|
collector = visit o.left, collector
|
|
618
394
|
collector << "NOT LIKE '%#{o.right}%'"
|
|
619
395
|
collector
|
|
620
396
|
end
|
|
621
397
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
end
|
|
626
|
-
|
|
627
|
-
def visit_ArelExtensions_Nodes_GroupConcat(o, collector)
|
|
628
|
-
collector << '(STRING_AGG('
|
|
398
|
+
# TODO;
|
|
399
|
+
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
400
|
+
collector << "(STRING_AGG("
|
|
629
401
|
collector = visit o.left, collector
|
|
630
|
-
collector <<
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
o.order.each_with_index do |order, i|
|
|
641
|
-
collector << LOADED_VISITOR::COMMA if i != 0
|
|
402
|
+
collector << Arel::Visitors::Oracle::COMMA
|
|
403
|
+
if o.right && o.right != 'NULL'
|
|
404
|
+
collector = visit o.right, collector
|
|
405
|
+
else
|
|
406
|
+
collector = visit Arel::Nodes.build_quoted(','), collector
|
|
407
|
+
end
|
|
408
|
+
collector << ") WITHIN GROUP (ORDER BY "
|
|
409
|
+
if !o.orders.blank?
|
|
410
|
+
o.orders.each_with_index do |order,i|
|
|
411
|
+
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
|
642
412
|
collector = visit order, collector
|
|
643
413
|
end
|
|
644
414
|
else
|
|
645
415
|
collector = visit o.left, collector
|
|
646
416
|
end
|
|
647
|
-
collector <<
|
|
417
|
+
collector << "))"
|
|
648
418
|
collector
|
|
649
419
|
end
|
|
650
420
|
|
|
651
|
-
def visit_ArelExtensions_Nodes_MD5
|
|
652
|
-
collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR
|
|
421
|
+
def visit_ArelExtensions_Nodes_MD5 o, collector
|
|
422
|
+
collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR,"
|
|
653
423
|
collector = visit o.left, collector
|
|
654
|
-
collector <<
|
|
655
|
-
collector
|
|
656
|
-
end
|
|
657
|
-
|
|
658
|
-
def visit_ArelExtensions_Nodes_Cast
|
|
659
|
-
as_attr
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
collector << 'CAST('
|
|
424
|
+
collector << ")),2))"
|
|
425
|
+
collector
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def visit_ArelExtensions_Nodes_Cast o, collector
|
|
429
|
+
case o.as_attr
|
|
430
|
+
when :string
|
|
431
|
+
as_attr = Arel::Nodes::SqlLiteral.new('varchar')
|
|
432
|
+
when :time
|
|
433
|
+
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
|
434
|
+
when :date
|
|
435
|
+
as_attr = Arel::Nodes::SqlLiteral.new('date')
|
|
436
|
+
when :datetime
|
|
437
|
+
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
|
438
|
+
when :number,:decimal, :float
|
|
439
|
+
as_attr = Arel::Nodes::SqlLiteral.new('decimal(10,6)')
|
|
440
|
+
when :int
|
|
441
|
+
collector << "CAST(CAST("
|
|
442
|
+
collector = visit o.left, collector
|
|
443
|
+
collector << " AS decimal(10,0)) AS int)"
|
|
444
|
+
return collector
|
|
445
|
+
when :binary
|
|
446
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
|
447
|
+
else
|
|
448
|
+
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
|
449
|
+
end
|
|
450
|
+
collector << "CAST("
|
|
682
451
|
collector = visit o.left, collector
|
|
683
|
-
collector <<
|
|
684
|
-
collector = visit
|
|
685
|
-
collector <<
|
|
452
|
+
collector << " AS "
|
|
453
|
+
collector = visit as_attr, collector
|
|
454
|
+
collector << ")"
|
|
686
455
|
collector
|
|
687
456
|
end
|
|
688
457
|
|
|
689
|
-
def visit_ArelExtensions_Nodes_FormattedNumber
|
|
458
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
|
690
459
|
col = o.left.coalesce(0)
|
|
691
|
-
locale = Arel.
|
|
692
|
-
param = Arel.
|
|
693
|
-
sign =
|
|
460
|
+
locale = Arel::Nodes.build_quoted(o.locale.tr('_','-'))
|
|
461
|
+
param = Arel::Nodes.build_quoted("N#{o.precision}")
|
|
462
|
+
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
|
694
463
|
then('-').
|
|
695
464
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
|
696
465
|
sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
|
|
697
|
-
Arel.
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
col.abs / Arel.quoted(10).pow(col.abs.log10.floor),
|
|
466
|
+
Arel::Nodes.build_quoted(1) :
|
|
467
|
+
ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
|
|
468
|
+
|
|
469
|
+
if o.scientific_notation
|
|
470
|
+
number = ArelExtensions::Nodes::Concat.new([
|
|
471
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
|
472
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
|
705
473
|
param,
|
|
706
474
|
locale
|
|
707
475
|
]),
|
|
708
476
|
o.type,
|
|
709
|
-
Arel::Nodes::NamedFunction.new('FORMAT',
|
|
477
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
|
710
478
|
col.abs.log10.floor,
|
|
711
|
-
Arel.
|
|
479
|
+
Arel::Nodes.build_quoted('N0'),
|
|
712
480
|
locale
|
|
713
481
|
])
|
|
714
482
|
])
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
Arel.
|
|
483
|
+
else
|
|
484
|
+
number = Arel::Nodes::NamedFunction.new('FORMAT',[
|
|
485
|
+
Arel::Nodes.build_quoted(col.abs),
|
|
718
486
|
param,
|
|
719
487
|
locale
|
|
720
488
|
])
|
|
721
|
-
|
|
489
|
+
end
|
|
722
490
|
|
|
723
|
-
repeated_char =
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
Arel
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
)
|
|
733
|
-
.else('')
|
|
734
|
-
end
|
|
735
|
-
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
736
|
-
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
491
|
+
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
|
492
|
+
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
|
493
|
+
then(Arel::Nodes.build_quoted(
|
|
494
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
|
495
|
+
).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
|
|
496
|
+
).
|
|
497
|
+
else('')
|
|
498
|
+
before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
499
|
+
middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
737
500
|
after = o.flags.include?('-') ? repeated_char : ''
|
|
738
501
|
full_number =
|
|
739
502
|
ArelExtensions::Nodes::Concat.new([
|
|
@@ -743,57 +506,49 @@ module ArelExtensions
|
|
|
743
506
|
number,
|
|
744
507
|
after
|
|
745
508
|
])
|
|
746
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel.
|
|
509
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
|
747
510
|
collector
|
|
748
511
|
end
|
|
749
512
|
|
|
750
|
-
def visit_ArelExtensions_Nodes_Std
|
|
751
|
-
collector << (o.unbiased_estimator ?
|
|
513
|
+
def visit_ArelExtensions_Nodes_Std o, collector
|
|
514
|
+
collector << (o.unbiased_estimator ? "STDEV(" : "STDEVP(")
|
|
752
515
|
visit o.left, collector
|
|
753
|
-
collector <<
|
|
516
|
+
collector << ")"
|
|
754
517
|
collector
|
|
755
518
|
end
|
|
756
519
|
|
|
757
|
-
def visit_ArelExtensions_Nodes_Variance
|
|
758
|
-
collector << (o.unbiased_estimator ?
|
|
520
|
+
def visit_ArelExtensions_Nodes_Variance o, collector
|
|
521
|
+
collector << (o.unbiased_estimator ? "VAR(" : "VARP(")
|
|
759
522
|
visit o.left, collector
|
|
760
|
-
collector <<
|
|
523
|
+
collector << ")"
|
|
761
524
|
collector
|
|
762
525
|
end
|
|
763
526
|
|
|
764
|
-
|
|
765
|
-
|
|
527
|
+
|
|
528
|
+
def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
|
|
529
|
+
collector << "dbo.LEVENSHTEIN_DISTANCE("
|
|
766
530
|
collector = visit o.left, collector
|
|
767
|
-
collector <<
|
|
531
|
+
collector << Arel::Visitors::ToSql::COMMA
|
|
768
532
|
collector = visit o.right, collector
|
|
769
533
|
collector << ')'
|
|
770
534
|
collector
|
|
771
535
|
end
|
|
772
536
|
|
|
773
|
-
|
|
537
|
+
|
|
538
|
+
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
|
774
539
|
collector << 'JSON_VALUE('
|
|
775
540
|
collector = visit o.dict, collector
|
|
776
|
-
collector <<
|
|
541
|
+
collector << Arel::Visitors::MySQL::COMMA
|
|
777
542
|
if o.key.is_a?(Integer)
|
|
778
543
|
collector << "\"$[#{o.key}]\""
|
|
779
544
|
else
|
|
780
|
-
collector = visit Arel.
|
|
545
|
+
collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
|
|
781
546
|
end
|
|
782
547
|
collector << ')'
|
|
783
548
|
collector
|
|
784
549
|
end
|
|
785
550
|
|
|
786
|
-
|
|
787
|
-
# handle grouping aggregation semantics
|
|
788
|
-
def grouping_array_or_grouping_element(o, collector)
|
|
789
|
-
if o.expr.is_a? Array
|
|
790
|
-
collector << '( '
|
|
791
|
-
visit o.expr, collector
|
|
792
|
-
collector << ' )'
|
|
793
|
-
else
|
|
794
|
-
visit o.expr, collector
|
|
795
|
-
end
|
|
796
|
-
end
|
|
551
|
+
|
|
797
552
|
end
|
|
798
553
|
end
|
|
799
554
|
end
|