arel_extensions 2.0.1 → 2.0.4
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/.rubocop.yml +7 -4
- data/.travis.yml +10 -10
- data/Gemfile +14 -19
- data/README.md +17 -12
- data/Rakefile +23 -23
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +2 -2
- data/functions.html +3 -3
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +13 -0
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions/boolean_functions.rb +0 -2
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/comparators.rb +4 -2
- data/lib/arel_extensions/insert_manager.rb +12 -12
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +10 -5
- data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
- data/lib/arel_extensions/nodes/case.rb +0 -2
- data/lib/arel_extensions/nodes/coalesce.rb +2 -2
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +6 -13
- data/lib/arel_extensions/nodes/date_diff.rb +3 -5
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/format.rb +8 -8
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
- data/lib/arel_extensions/nodes/function.rb +2 -0
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/matches.rb +4 -4
- data/lib/arel_extensions/nodes/power.rb +6 -5
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +24 -6
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +16 -15
- data/lib/arel_extensions/nodes/std.rb +19 -21
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/sum.rb +7 -0
- data/lib/arel_extensions/nodes/trim.rb +3 -3
- data/lib/arel_extensions/nodes/union.rb +2 -3
- data/lib/arel_extensions/nodes/union_all.rb +0 -1
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/predications.rb +16 -17
- data/lib/arel_extensions/string_functions.rb +21 -12
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +14 -13
- data/lib/arel_extensions/visitors/mysql.rb +72 -37
- data/lib/arel_extensions/visitors/oracle.rb +12 -11
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +77 -31
- data/lib/arel_extensions/visitors/sqlite.rb +54 -40
- data/lib/arel_extensions/visitors/to_sql.rb +50 -31
- data/lib/arel_extensions.rb +20 -1
- data/test/helper.rb +1 -1
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +0 -4
- data/test/test_comparators.rb +1 -1
- data/test/visitors/test_bulk_insert_oracle.rb +6 -6
- data/test/visitors/test_bulk_insert_sqlite.rb +6 -6
- data/test/visitors/test_bulk_insert_to_sql.rb +7 -9
- data/test/visitors/test_oracle.rb +1 -0
- data/test/visitors/test_to_sql.rb +15 -1
- data/test/with_ar/all_agnostic_test.rb +54 -32
- data/test/with_ar/insert_agnostic_test.rb +2 -1
- data/test/with_ar/test_bulk_sqlite.rb +2 -2
- data/test/with_ar/test_math_sqlite.rb +3 -3
- data/test/with_ar/test_string_mysql.rb +3 -5
- data/test/with_ar/test_string_sqlite.rb +2 -6
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +13 -6
@@ -1,22 +1,15 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class Substring < Function
|
4
|
-
|
4
|
+
RETURN_TYPE = :string
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
return super(tab)
|
14
|
-
end
|
15
|
-
|
16
|
-
# def +(other)
|
17
|
-
# puts "[Substring] : #{other.inspect} (#{self.expressions.inspect})"
|
18
|
-
# return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
19
|
-
# end
|
6
|
+
def initialize expr
|
7
|
+
tab = [convert_to_node(expr[0]), convert_to_node(expr[1])]
|
8
|
+
if expr[2]
|
9
|
+
tab << convert_to_node(expr[2])
|
10
|
+
end
|
11
|
+
return super(tab)
|
12
|
+
end
|
20
13
|
|
21
14
|
end
|
22
15
|
end
|
@@ -2,7 +2,7 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Trim < Function
|
4
4
|
RETURN_TYPE = :string
|
5
|
-
|
5
|
+
|
6
6
|
def initialize expr
|
7
7
|
tab = expr.map { |arg|
|
8
8
|
convert_to_node(arg)
|
@@ -11,13 +11,13 @@ module ArelExtensions
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def +(other)
|
14
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
14
|
+
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
19
|
class Ltrim < Trim
|
20
|
-
|
20
|
+
RETURN_TYPE = :string
|
21
21
|
end
|
22
22
|
|
23
23
|
class Rtrim < Trim
|
@@ -7,11 +7,11 @@ module ArelExtensions
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def +(other)
|
10
|
-
return ArelExtensions::Nodes::Union.new(self,other)
|
10
|
+
return ArelExtensions::Nodes::Union.new(self,other)
|
11
11
|
end
|
12
12
|
|
13
13
|
def union(other)
|
14
|
-
return ArelExtensions::Nodes::UnionAll.new(self,other)
|
14
|
+
return ArelExtensions::Nodes::UnionAll.new(self,other)
|
15
15
|
end
|
16
16
|
|
17
17
|
def as other
|
@@ -21,4 +21,3 @@ module ArelExtensions
|
|
21
21
|
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'arel_extensions/nodes/function'
|
2
|
-
|
2
|
+
require 'arel_extensions/nodes/aggregate_function'
|
@@ -8,12 +8,12 @@ module ArelExtensions
|
|
8
8
|
def is_null
|
9
9
|
ArelExtensions::Nodes::IsNull.new [self]
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
#ISNOTNULL function lets you return an alternative value when an expression is NOT NULL.
|
13
13
|
def is_not_null
|
14
14
|
ArelExtensions::Nodes::IsNotNull.new [self]
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# returns the first non-null expr in the expression list. You must specify at least two expressions.
|
18
18
|
#If all occurrences of expr evaluate to null, then the function returns null.
|
19
19
|
def coalesce *args
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Predications
|
3
|
-
def when right, expression=nil
|
3
|
+
def when right, expression = nil
|
4
4
|
ArelExtensions::Nodes::Case.new(self).when(right,expression)
|
5
5
|
end
|
6
6
|
|
7
|
-
def matches(other, escape=nil,case_sensitive= nil)
|
7
|
+
def matches(other, escape = nil,case_sensitive = nil)
|
8
8
|
if Arel::VERSION.to_i < 7
|
9
9
|
Arel::Nodes::Matches.new(self, Arel::Nodes.build_quoted(other), escape)
|
10
10
|
else
|
@@ -12,7 +12,7 @@ module ArelExtensions
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def imatches(other, escape=nil)
|
15
|
+
def imatches(other, escape = nil)
|
16
16
|
ArelExtensions::Nodes::IMatches.new(self, other, escape)
|
17
17
|
end
|
18
18
|
|
@@ -25,25 +25,24 @@ module ArelExtensions
|
|
25
25
|
when Range
|
26
26
|
self.between(other)
|
27
27
|
when Enumerable
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
28
|
+
nils, values = other.partition{ |v| v.nil? }
|
29
|
+
ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
|
30
|
+
|
31
|
+
# In order of (imagined) decreasing efficiency: nil, values, and then more complex.
|
32
|
+
clauses =
|
33
|
+
nils.uniq.map { |r| self.in(r) } \
|
34
|
+
+ (case values.uniq.size
|
35
|
+
when 0 then []
|
36
|
+
when 1 then [self == values[0]]
|
37
|
+
else [Arel::Nodes::In.new(self, quoted_array(values))] end) \
|
38
|
+
+ ranges.uniq.map { |r| self.in(r) }
|
39
|
+
clauses.empty? ? self.is_null : clauses.reduce(&:or)
|
41
40
|
when nil
|
42
41
|
self.is_null
|
43
42
|
when Arel::SelectManager
|
44
43
|
Arel::Nodes::In.new(self, other.ast)
|
45
44
|
else
|
46
|
-
Arel::Nodes::In.new(self,quoted_node(other))
|
45
|
+
Arel::Nodes::In.new(self, quoted_node(other))
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
@@ -92,7 +92,7 @@ module ArelExtensions
|
|
92
92
|
ArelExtensions::Nodes::SMatches.new(self,other)
|
93
93
|
end
|
94
94
|
|
95
|
-
def ai_collate
|
95
|
+
def ai_collate
|
96
96
|
ArelExtensions::Nodes::Collate.new(self,nil,true,false)
|
97
97
|
end
|
98
98
|
|
@@ -100,31 +100,40 @@ module ArelExtensions
|
|
100
100
|
ArelExtensions::Nodes::Collate.new(self,nil,false,true)
|
101
101
|
end
|
102
102
|
|
103
|
-
def collate ai=false,ci=false, option=nil
|
103
|
+
def collate ai = false,ci = false, option = nil
|
104
104
|
ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
|
105
105
|
end
|
106
106
|
|
107
107
|
#REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
|
108
|
-
def replace
|
109
|
-
|
108
|
+
def replace pattern, substitute
|
109
|
+
if pattern.is_a? Regexp
|
110
|
+
ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
|
111
|
+
else
|
112
|
+
ArelExtensions::Nodes::Replace.new self, pattern, substitute
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def regexp_replace pattern, substitute
|
117
|
+
ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
|
110
118
|
end
|
111
|
-
|
119
|
+
|
112
120
|
def concat other
|
113
121
|
ArelExtensions::Nodes::Concat.new [self, other]
|
114
122
|
end
|
115
123
|
|
116
124
|
#concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
|
117
|
-
def group_concat
|
125
|
+
def group_concat(sep = nil, *orders, group: nil, order: nil)
|
126
|
+
if orders.present?
|
127
|
+
warn("Warning : ArelExtensions: group_concat: you should now use the kwarg 'order' to specify an order in the group_concat.")
|
128
|
+
end
|
118
129
|
order_tabs = [orders].flatten.map{ |o|
|
119
130
|
if o.is_a?(Arel::Nodes::Ascending) || o.is_a?(Arel::Nodes::Descending)
|
120
131
|
o
|
121
132
|
elsif o.respond_to?(:asc)
|
122
133
|
o.asc
|
123
|
-
else
|
124
|
-
nil
|
125
134
|
end
|
126
135
|
}.compact
|
127
|
-
ArelExtensions::Nodes::GroupConcat.new
|
136
|
+
ArelExtensions::Nodes::GroupConcat.new(self, sep, group: group, order: (order || order_tabs))
|
128
137
|
end
|
129
138
|
|
130
139
|
#Function returns a string after removing left, right or the both prefixes or suffixes int argument
|
@@ -155,11 +164,11 @@ module ArelExtensions
|
|
155
164
|
def not_blank
|
156
165
|
ArelExtensions::Nodes::NotBlank.new [self]
|
157
166
|
end
|
158
|
-
|
159
|
-
def repeat other = 1
|
167
|
+
|
168
|
+
def repeat other = 1
|
160
169
|
ArelExtensions::Nodes::Repeat.new [self, other]
|
161
170
|
end
|
162
|
-
|
171
|
+
|
163
172
|
def levenshtein_distance other
|
164
173
|
ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
|
165
174
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
namespace :arel_extensions do
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
desc 'Install DB functions into current DB'
|
3
|
+
task :install_functions => :environment do
|
4
|
+
@env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
|
5
5
|
(RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
|
6
6
|
else
|
7
7
|
ENV['DB'] || ActiveRecord::Base.connection.adapter_name
|
8
8
|
end
|
9
|
-
ActiveRecord::Base.establish_connection(Rails.env)
|
9
|
+
ActiveRecord::Base.establish_connection(Rails.env.to_sym)
|
10
10
|
CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions(@env_db)
|
11
|
-
|
11
|
+
end
|
12
12
|
end
|
@@ -400,14 +400,15 @@ module ArelExtensions
|
|
400
400
|
collector << "(STRING_AGG("
|
401
401
|
collector = visit o.left, collector
|
402
402
|
collector << Arel::Visitors::Oracle::COMMA
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
403
|
+
collector =
|
404
|
+
if o.separator && o.separator != 'NULL'
|
405
|
+
visit o.separator, collector
|
406
|
+
else
|
407
|
+
visit Arel::Nodes.build_quoted(','), collector
|
408
|
+
end
|
408
409
|
collector << ") WITHIN GROUP (ORDER BY "
|
409
|
-
if
|
410
|
-
o.
|
410
|
+
if o.order.present?
|
411
|
+
o.order.each_with_index do |order,i|
|
411
412
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
412
413
|
collector = visit order, collector
|
413
414
|
end
|
@@ -466,8 +467,9 @@ module ArelExtensions
|
|
466
467
|
Arel::Nodes.build_quoted(1) :
|
467
468
|
ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
|
468
469
|
|
469
|
-
|
470
|
-
|
470
|
+
number =
|
471
|
+
if o.scientific_notation
|
472
|
+
ArelExtensions::Nodes::Concat.new([
|
471
473
|
Arel::Nodes::NamedFunction.new('FORMAT',[
|
472
474
|
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
473
475
|
param,
|
@@ -480,13 +482,13 @@ module ArelExtensions
|
|
480
482
|
locale
|
481
483
|
])
|
482
484
|
])
|
483
|
-
|
484
|
-
|
485
|
+
else
|
486
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
485
487
|
Arel::Nodes.build_quoted(col.abs),
|
486
488
|
param,
|
487
489
|
locale
|
488
490
|
])
|
489
|
-
|
491
|
+
end
|
490
492
|
|
491
493
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
492
494
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -548,7 +550,6 @@ module ArelExtensions
|
|
548
550
|
collector
|
549
551
|
end
|
550
552
|
|
551
|
-
|
552
553
|
end
|
553
554
|
end
|
554
555
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
Arel::Visitors::MySQL.class_eval do
|
4
|
-
Arel::Visitors::MySQL::COMMA = ", "
|
5
4
|
Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
6
5
|
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
7
6
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
@@ -98,26 +97,28 @@ module ArelExtensions
|
|
98
97
|
end
|
99
98
|
|
100
99
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
charset =
|
101
|
+
case o.expressions.first
|
102
|
+
when Arel::Attributes::Attribute
|
103
|
+
case o.option
|
104
104
|
when 'latin1','utf8'
|
105
105
|
o.option
|
106
106
|
else
|
107
107
|
Arel::Table.engine.connection.charset || 'utf8'
|
108
108
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
else
|
110
|
+
(o.option == 'latin1') ? 'latin1' : 'utf8'
|
111
|
+
end
|
112
112
|
collector = visit o.expressions.first, collector
|
113
|
-
|
114
|
-
|
113
|
+
collector <<
|
114
|
+
if o.ai
|
115
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
115
116
|
#doesn't work in latin1
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
117
|
+
elsif o.ci
|
118
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
119
|
+
else
|
120
|
+
" COLLATE #{charset}_bin"
|
121
|
+
end
|
121
122
|
collector
|
122
123
|
end
|
123
124
|
|
@@ -140,16 +141,16 @@ module ArelExtensions
|
|
140
141
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
141
142
|
collector << "GROUP_CONCAT("
|
142
143
|
collector = visit o.left, collector
|
143
|
-
if !o.
|
144
|
+
if !o.order.blank?
|
144
145
|
collector << ' ORDER BY '
|
145
|
-
o.
|
146
|
+
o.order.each_with_index do |order,i|
|
146
147
|
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
147
148
|
collector = visit order, collector
|
148
149
|
end
|
149
150
|
end
|
150
|
-
if o.
|
151
|
+
if o.separator && o.separator != 'NULL'
|
151
152
|
collector << ' SEPARATOR '
|
152
|
-
collector = visit o.
|
153
|
+
collector = visit o.separator, collector
|
153
154
|
end
|
154
155
|
collector << ")"
|
155
156
|
collector
|
@@ -263,7 +264,7 @@ module ArelExtensions
|
|
263
264
|
else
|
264
265
|
if o.with_interval
|
265
266
|
case o.left
|
266
|
-
when
|
267
|
+
when 'd','m','y'
|
267
268
|
interval = 'DAY'
|
268
269
|
when 'h','mn','s'
|
269
270
|
interval = 'SECOND'
|
@@ -363,20 +364,21 @@ module ArelExtensions
|
|
363
364
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
364
365
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
365
366
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
367
|
+
number =
|
368
|
+
if o.scientific_notation
|
369
|
+
ArelExtensions::Nodes::Concat.new([
|
370
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
371
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
|
372
|
+
]+params),
|
373
|
+
o.type,
|
374
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
375
|
+
col.abs.log10.floor,
|
376
|
+
0
|
377
|
+
])
|
375
378
|
])
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
end
|
379
|
+
else
|
380
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
|
381
|
+
end
|
380
382
|
|
381
383
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
382
384
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -399,10 +401,34 @@ module ArelExtensions
|
|
399
401
|
collector
|
400
402
|
end
|
401
403
|
|
404
|
+
def visit_Aggregate_For_AggregateFunction o, collector
|
405
|
+
if !window_supported?
|
406
|
+
warn("Warning : ArelExtensions: Window Functions are not available in the current version on the DBMS.")
|
407
|
+
return collector
|
408
|
+
end
|
409
|
+
|
410
|
+
if !o.order.empty? || !o.group.empty?
|
411
|
+
collector << " OVER ("
|
412
|
+
if !o.group.empty?
|
413
|
+
collector << " PARTITION BY ("
|
414
|
+
visit o.group, collector
|
415
|
+
collector << ")"
|
416
|
+
end
|
417
|
+
if !o.order.empty?
|
418
|
+
collector << " ORDER BY ("
|
419
|
+
visit o.order, collector
|
420
|
+
collector << ")"
|
421
|
+
end
|
422
|
+
collector << ")"
|
423
|
+
end
|
424
|
+
collector
|
425
|
+
end
|
426
|
+
|
402
427
|
def visit_ArelExtensions_Nodes_Std o, collector
|
403
428
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
404
429
|
visit o.left, collector
|
405
430
|
collector << ")"
|
431
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
406
432
|
collector
|
407
433
|
end
|
408
434
|
|
@@ -410,18 +436,27 @@ module ArelExtensions
|
|
410
436
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
411
437
|
visit o.left, collector
|
412
438
|
collector << ")"
|
439
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
413
440
|
collector
|
414
441
|
end
|
415
442
|
|
416
443
|
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
417
444
|
def json_supported?
|
445
|
+
version_supported?('10.2.3', '5.7.0')
|
446
|
+
end
|
447
|
+
|
448
|
+
def window_supported?
|
449
|
+
version_supported?('10.2.3', '8.0')
|
450
|
+
end
|
451
|
+
|
452
|
+
def version_supported?(mysql_v = '10.2.3',mariadb_v = '5.7.0')
|
418
453
|
conn = Arel::Table.engine.connection
|
419
454
|
conn.send(:mariadb?) &&
|
420
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >=
|
421
|
-
conn.respond_to?(:version) && conn.send(:version) >=
|
422
|
-
|
423
|
-
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >=
|
424
|
-
conn.respond_to?(:version) && conn.send(:version) >=
|
455
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v ||
|
456
|
+
conn.respond_to?(:version) && conn.send(:version) >= mysql_v) ||
|
457
|
+
!Arel::Table.engine.connection.send(:mariadb?) &&
|
458
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mariadb_v ||
|
459
|
+
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v)
|
425
460
|
end
|
426
461
|
|
427
462
|
def visit_ArelExtensions_Nodes_Json o,collector
|
@@ -131,14 +131,15 @@ module ArelExtensions
|
|
131
131
|
collector << "(LISTAGG("
|
132
132
|
collector = visit o.left, collector
|
133
133
|
collector << Arel::Visitors::Oracle::COMMA
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
134
|
+
collector =
|
135
|
+
if o.separator && o.separator != 'NULL'
|
136
|
+
visit o.separator, collector
|
137
|
+
else
|
138
|
+
visit Arel::Nodes.build_quoted(','), collector
|
139
|
+
end
|
139
140
|
collector << ") WITHIN GROUP (ORDER BY "
|
140
|
-
if !o.
|
141
|
-
o.
|
141
|
+
if !o.order.blank?
|
142
|
+
o.order.each_with_index do |order,i|
|
142
143
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
143
144
|
collector = visit order, collector
|
144
145
|
end
|
@@ -154,7 +155,7 @@ module ArelExtensions
|
|
154
155
|
o.expressions.each_with_index { |arg, i|
|
155
156
|
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
156
157
|
if i > 0 && o.left_node_type == :text
|
157
|
-
if arg == ''
|
158
|
+
if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
|
158
159
|
collector << "NULL"
|
159
160
|
else
|
160
161
|
collector << 'TO_CLOB('
|
@@ -489,9 +490,9 @@ module ArelExtensions
|
|
489
490
|
o.left.each_with_index do |row, idx|
|
490
491
|
collector << " UNION ALL " if idx != 0
|
491
492
|
collector << "(SELECT "
|
492
|
-
|
493
|
-
|
494
|
-
|
493
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
494
|
+
len = v.expressions.length - 1
|
495
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
495
496
|
case value
|
496
497
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
497
498
|
collector = visit value, collector
|