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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -8
  4. data/.rubocop.yml +4 -194
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +28 -2
  13. data/README.md +89 -265
  14. data/Rakefile +30 -50
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +17 -14
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +20 -0
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +17 -19
  23. data/gemfiles/rails5_2.gemfile +17 -26
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +25 -24
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -9
  30. data/lib/arel_extensions/boolean_functions.rb +16 -57
  31. data/lib/arel_extensions/common_sql_functions.rb +20 -21
  32. data/lib/arel_extensions/comparators.rb +28 -31
  33. data/lib/arel_extensions/date_duration.rb +13 -19
  34. data/lib/arel_extensions/insert_manager.rb +15 -22
  35. data/lib/arel_extensions/math.rb +70 -68
  36. data/lib/arel_extensions/math_functions.rb +52 -57
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +5 -6
  39. data/lib/arel_extensions/nodes/case.rb +27 -31
  40. data/lib/arel_extensions/nodes/cast.rb +12 -12
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +5 -4
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +22 -13
  45. data/lib/arel_extensions/nodes/date_diff.rb +70 -77
  46. data/lib/arel_extensions/nodes/duration.rb +5 -2
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +39 -50
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -2
  53. data/lib/arel_extensions/nodes/json.rb +47 -72
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  56. data/lib/arel_extensions/nodes/locate.rb +3 -2
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +8 -6
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +3 -2
  62. data/lib/arel_extensions/nodes/repeat.rb +6 -4
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +7 -6
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -58
  68. data/lib/arel_extensions/nodes/then.rb +2 -2
  69. data/lib/arel_extensions/nodes/trim.rb +7 -5
  70. data/lib/arel_extensions/nodes/union.rb +9 -6
  71. data/lib/arel_extensions/nodes/union_all.rb +8 -5
  72. data/lib/arel_extensions/nodes/wday.rb +6 -2
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +6 -18
  75. data/lib/arel_extensions/predications.rb +49 -54
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +55 -110
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -3
  81. data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
  82. data/lib/arel_extensions/visitors/mssql.rb +248 -493
  83. data/lib/arel_extensions/visitors/mysql.rb +244 -420
  84. data/lib/arel_extensions/visitors/oracle.rb +258 -311
  85. data/lib/arel_extensions/visitors/oracle12.rb +34 -20
  86. data/lib/arel_extensions/visitors/postgresql.rb +239 -350
  87. data/lib/arel_extensions/visitors/sqlite.rb +169 -191
  88. data/lib/arel_extensions/visitors/to_sql.rb +299 -371
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +32 -243
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +120 -123
  94. data/test/support/fake_record.rb +3 -11
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +12 -12
  97. data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +375 -912
  102. data/test/with_ar/insert_agnostic_test.rb +22 -28
  103. data/test/with_ar/test_bulk_sqlite.rb +17 -18
  104. data/test/with_ar/test_math_sqlite.rb +27 -27
  105. data/test/with_ar/test_string_mysql.rb +34 -32
  106. data/test/with_ar/test_string_sqlite.rb +35 -31
  107. metadata +64 -50
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -452
  111. data/CONTRIBUTING.md +0 -102
  112. data/Makefile +0 -48
  113. data/NEWS.md +0 -131
  114. data/bin/build +0 -15
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -41
  117. data/dev/compose.yaml +0 -69
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails5.gemfile +0 -36
  121. data/gemfiles/rails6.gemfile +0 -40
  122. data/gemfiles/rails6_1.gemfile +0 -48
  123. data/gemfiles/rails7.gemfile +0 -48
  124. data/gemfiles/rails7_1.gemfile +0 -48
  125. data/gemfiles/rails7_2.gemfile +0 -47
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -25
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -25
  130. data/generate_gems.sh +0 -15
  131. data/lib/arel_extensions/aliases.rb +0 -14
  132. data/lib/arel_extensions/constants.rb +0 -13
  133. data/lib/arel_extensions/helpers.rb +0 -61
  134. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  135. data/lib/arel_extensions/nodes/byte_size.rb +0 -11
  136. data/lib/arel_extensions/nodes/char_length.rb +0 -11
  137. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  138. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  139. data/lib/arel_extensions/nodes/select.rb +0 -10
  140. data/lib/arel_extensions/nodes/sum.rb +0 -7
  141. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  142. data/lib/arel_extensions/warning.rb +0 -42
  143. data/test/arelx_test_helper.rb +0 -94
  144. data/test/config_loader.rb +0 -9
  145. data/version_v1.rb +0 -5
  146. data/version_v2.rb +0 -5
@@ -1,365 +1,207 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  module MSSQL
4
- MSSQL_CLASS_NAMES = %i[MSSQL SQLServer].freeze
5
-
6
- mssql_class =
7
- Arel::Visitors
8
- .constants
9
- .select { |c| Arel::Visitors.const_get(c).is_a?(Class) }
10
- .find { |c| MSSQL_CLASS_NAMES.include?(c) }
11
-
12
- # This guard is necessary because:
13
- #
14
- # 1. const_get(mssql_class) will fail when mssql_class is nil.
15
- # 2. mssql_class could be nil under certain conditions:
16
- # 1. especially on ruby 2.5 (and surprisingly not jruby 9.2) and 3.0+.
17
- # 2. when not working with mssql itself.
18
- if mssql_class
19
- LOADED_VISITOR = Arel::Visitors.const_get(mssql_class)
20
-
21
- LOADED_VISITOR::DATE_MAPPING = {
22
- 'd' => 'day', 'm' => 'month', 'y' => 'year',
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(o, collector)
158
- collector << 'CEILING('
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(o, collector)
165
- collector << 'LOG10('
166
- o.expressions.each_with_index { |arg, i|
167
- collector << LOADED_VISITOR::COMMA if i != 0
168
- collector = visit arg, collector
169
- }
170
- collector << ')'
171
- collector
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(o, collector)
175
- collector << 'POWER('
42
+ def visit_ArelExtensions_Nodes_Power o, collector
43
+ collector << "POWER("
176
44
  o.expressions.each_with_index { |arg, i|
177
- collector << LOADED_VISITOR::COMMA if i != 0
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(o, collector)
185
- collector << '('
52
+ def visit_ArelExtensions_Nodes_IsNull o, collector
53
+ collector << "("
186
54
  collector = visit o.expr, collector
187
- collector << ' IS NULL)'
55
+ collector << " IS NULL)"
188
56
  collector
189
57
  end
190
58
 
191
- def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
192
- collector << '('
193
- collector = visit o.expr, collector
194
- collector << ' IS NOT NULL)'
195
- collector
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(o, collector)
199
- collector << 'CONCAT('
66
+ def visit_ArelExtensions_Nodes_Concat o, collector
67
+ collector << "CONCAT("
200
68
  o.expressions.each_with_index { |arg, i|
201
- collector << LOADED_VISITOR::COMMA if i != 0
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(o, collector)
209
- collector << 'REPLICATE('
76
+ def visit_ArelExtensions_Nodes_Repeat o, collector
77
+ collector << "REPLICATE("
210
78
  o.expressions.each_with_index { |arg, i|
211
- collector << LOADED_VISITOR::COMMA if i != 0
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
- def visit_ArelExtensions_Nodes_DateDiff(o, collector)
219
- case o.right_node_type
220
- when :ruby_date, :ruby_time, :date, :datetime, :time
221
- collector << case o.left_node_type
222
- when :ruby_time, :datetime, :time then 'DATEDIFF(second'
223
- else 'DATEDIFF(day'
224
- end
225
- collector << LOADED_VISITOR::COMMA
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 << LOADED_VISITOR::COMMA
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 << 'DATEADD('
102
+ collector << "DATEADD("
233
103
  collector = visit da.mssql_datepart(o.right), collector
234
- collector << LOADED_VISITOR::COMMA
235
- collector << '-('
104
+ collector << Arel::Visitors::MSSQL::COMMA
105
+ collector << "-("
236
106
  collector = visit da.mssql_value(o.right), collector
237
- collector << ')'
238
- collector << LOADED_VISITOR::COMMA
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(o, collector)
247
- collector << 'DATEADD('
116
+ def visit_ArelExtensions_Nodes_DateAdd o, collector
117
+ collector << "DATEADD("
248
118
  collector = visit o.mssql_datepart(o.right), collector
249
- collector << LOADED_VISITOR::COMMA
119
+ collector << Arel::Visitors::MSSQL::COMMA
250
120
  collector = visit o.mssql_value(o.right), collector
251
- collector << LOADED_VISITOR::COMMA
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(o, collector)
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 = %w[h mn s].include?(o.left)
132
+ conv = ['h', 'mn', 's'].include?(o.left)
263
133
  collector << 'DATEPART('
264
- collector << LOADED_VISITOR::DATE_MAPPING[left]
265
- collector << LOADED_VISITOR::COMMA
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 visit_ArelExtensions_Nodes_ByteSize(o, collector)
275
- collector << 'DATALENGTH(CAST('
276
- collector = visit o.expr.coalesce(''), collector
277
- collector << ' AS VARCHAR(MAX)))'
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 visit_ArelExtensions_Nodes_Length(o, collector)
292
- if o.bytewise
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 << LOADED_VISITOR::COMMA if i != 0
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 << LOADED_VISITOR::COMMA
315
- collector << '0'
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(o, collector)
322
- collector << 'CHARINDEX('
165
+ def visit_ArelExtensions_Nodes_Locate o, collector
166
+ collector << "CHARINDEX("
323
167
  collector = visit o.right, collector
324
- collector << LOADED_VISITOR::COMMA
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(o, collector)
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 << LOADED_VISITOR::COMMA
177
+ collector << Arel::Visitors::MSSQL::COMMA
336
178
  collector = visit o.expressions[1], collector
337
- collector << LOADED_VISITOR::COMMA
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(o, collector)
344
- # NOTE: in MSSQL's `blank`, o.right is the space char so we need to
345
- # account for it.
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 << LOADED_VISITOR::COMMA
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 << 'LTRIM(RTRIM('
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(o, collector)
202
+ def visit_ArelExtensions_Nodes_Ltrim o, collector
361
203
  if o.right
362
- collector << 'REPLACE(REPLACE(LTRIM(REPLACE(REPLACE('
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 << 'LTRIM('
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(o, collector)
219
+ def visit_ArelExtensions_Nodes_Rtrim o, collector
378
220
  if o.right
379
- collector << 'REPLACE(REPLACE(RTRIM(REPLACE(REPLACE('
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 << 'RTRIM('
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(o, collector)
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(o, collector)
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(o, collector)
403
- visit_ArelExtensions_Nodes_FormattedDate o, collector
404
- end
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 << LOADED_VISITOR::COMMA
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
- case o.time_zone
418
- when Hash
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
- s = StringScanner.new o.iso_format
434
- collector << '('
435
- sep = ''
436
- while !s.eos?
437
- collector << sep
438
- sep = ' + '
439
- if s.scan(LOADED_VISITOR::DATE_FORMAT_REGEX)
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
- collector = visit o.left, collector
455
- case o.time_zone
456
- when Hash
457
- src_tz = o.time_zone.first.first
458
- dst_tz = o.time_zone.first.second
459
- collector << ') AT TIME ZONE '
460
- collector = visit Arel.quoted(src_tz), collector
461
- collector << ' AT TIME ZONE '
462
- collector = visit Arel.quoted(dst_tz), collector
463
- when String
464
- collector << ') AT TIME ZONE '
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
- end
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(o, collector)
483
- collector << 'REPLACE('
286
+ def visit_ArelExtensions_Nodes_Replace o, collector
287
+ collector << "REPLACE("
484
288
  o.expressions.each_with_index { |arg, i|
485
- collector << LOADED_VISITOR::COMMA if i != 0
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(o, collector)
493
- collector << 'dbo.FIND_IN_SET('
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 << LOADED_VISITOR::COMMA if i != 0
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(o, collector)
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(o, collector)
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(o, collector)
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(o, collector)
541
- collector = visit o.left.collate(true, true), collector
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, true), collector
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(o, collector)
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(o, collector)
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(o, collector)
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(o, collector)
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
- def visit_Arel_Nodes_RollUp(o, collector)
623
- collector << 'ROLLUP'
624
- grouping_array_or_grouping_element o, collector
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 << LOADED_VISITOR::COMMA
631
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
632
- collector =
633
- if 'NULL' == sep
634
- visit Arel.quoted(','), collector
635
- else
636
- visit o.separator, collector
637
- end
638
- collector << ') WITHIN GROUP (ORDER BY '
639
- if o.order.present?
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(o, collector)
652
- collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR(MAX),"
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 << ')),2))'
655
- collector
656
- end
657
-
658
- def visit_ArelExtensions_Nodes_Cast(o, collector)
659
- as_attr =
660
- case o.as_attr
661
- when :string
662
- 'varchar(MAX)'
663
- when :time
664
- 'time'
665
- when :date
666
- 'date'
667
- when :datetime
668
- 'datetime'
669
- when :number, :decimal, :float
670
- 'decimal(10,6)'
671
- when :int
672
- collector << 'CAST(CAST('
673
- collector = visit o.left, collector
674
- collector << ' AS decimal(10,0)) AS int)'
675
- return collector
676
- when :binary
677
- 'binary'
678
- else
679
- o.as_attr.to_s
680
- end
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 << ' AS '
684
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
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(o, collector)
458
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
690
459
  col = o.left.coalesce(0)
691
- locale = Arel.quoted(o.locale.tr('_', '-'))
692
- param = Arel.quoted("N#{o.precision}")
693
- sign = Arel.when(col < 0).
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.quoted(1) :
698
- Arel.when(col < 0).then(1).else(0)
699
-
700
- number =
701
- if o.scientific_notation
702
- ArelExtensions::Nodes::Concat.new([
703
- Arel::Nodes::NamedFunction.new('FORMAT', [
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.quoted('N0'),
479
+ Arel::Nodes.build_quoted('N0'),
712
480
  locale
713
481
  ])
714
482
  ])
715
- else
716
- Arel::Nodes::NamedFunction.new('FORMAT', [
717
- Arel.quoted(col.abs),
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
- end
489
+ end
722
490
 
723
- repeated_char =
724
- if o.width == 0
725
- Arel.quoted('')
726
- else
727
- Arel
728
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
729
- .then(Arel.quoted(
730
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
731
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
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.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
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(o, collector)
751
- collector << (o.unbiased_estimator ? 'STDEV(' : 'STDEVP(')
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(o, collector)
758
- collector << (o.unbiased_estimator ? 'VAR(' : 'VARP(')
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
- def visit_ArelExtensions_Nodes_LevenshteinDistance(o, collector)
765
- collector << 'dbo.LEVENSHTEIN_DISTANCE('
527
+
528
+ def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
529
+ collector << "dbo.LEVENSHTEIN_DISTANCE("
766
530
  collector = visit o.left, collector
767
- collector << LOADED_VISITOR::COMMA
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
- def visit_ArelExtensions_Nodes_JsonGet(o, collector)
537
+
538
+ def visit_ArelExtensions_Nodes_JsonGet o,collector
774
539
  collector << 'JSON_VALUE('
775
540
  collector = visit o.dict, collector
776
- collector << LOADED_VISITOR::COMMA
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.quoted('$.') + o.key, collector
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
- # Utilized by GroupingSet, Cube & RollUp visitors to
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