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