arel_extensions 1.2.3 → 1.2.14
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 +5 -5
- data/.rubocop.yml +7 -4
- data/.travis.yml +59 -91
- data/Gemfile +2 -2
- data/README.md +17 -12
- data/Rakefile +38 -27
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +1 -1
- data/functions.html +3 -3
- data/gemfiles/rails4.gemfile +1 -1
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +14 -0
- data/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions.rb +63 -19
- data/lib/arel_extensions/attributes.rb +0 -1
- data/lib/arel_extensions/boolean_functions.rb +38 -13
- 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 +26 -24
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +10 -5
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
- data/lib/arel_extensions/nodes/case.rb +8 -4
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- 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/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- 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/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +4 -4
- data/lib/arel_extensions/nodes/power.rb +6 -5
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- 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/wday.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +2 -2
- data/lib/arel_extensions/predications.rb +35 -33
- data/lib/arel_extensions/set_functions.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +34 -12
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +14 -13
- data/lib/arel_extensions/visitors/mysql.rb +90 -36
- data/lib/arel_extensions/visitors/oracle.rb +16 -16
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +78 -32
- data/lib/arel_extensions/visitors/sqlite.rb +52 -44
- data/lib/arel_extensions/visitors/to_sql.rb +71 -58
- data/test/arelx_test_helper.rb +28 -0
- data/test/real_db_test.rb +1 -1
- data/test/support/fake_record.rb +4 -0
- data/test/test_comparators.rb +9 -8
- data/test/visitors/test_bulk_insert_oracle.rb +8 -7
- data/test/visitors/test_bulk_insert_sqlite.rb +9 -8
- data/test/visitors/test_bulk_insert_to_sql.rb +8 -10
- data/test/visitors/test_oracle.rb +41 -40
- data/test/visitors/test_to_sql.rb +367 -193
- data/test/with_ar/all_agnostic_test.rb +68 -35
- data/test/with_ar/insert_agnostic_test.rb +3 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -5
- data/test/with_ar/test_math_sqlite.rb +4 -4
- data/test/with_ar/test_string_mysql.rb +4 -6
- data/test/with_ar/test_string_sqlite.rb +3 -7
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +13 -7
- data/test/helper.rb +0 -18
@@ -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,11 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Predications
|
3
|
-
|
3
|
+
|
4
|
+
def when right, expression = nil
|
4
5
|
ArelExtensions::Nodes::Case.new(self).when(right,expression)
|
5
6
|
end
|
6
7
|
|
7
|
-
def matches(other, escape=nil,case_sensitive= nil)
|
8
|
+
def matches(other, escape = nil,case_sensitive = nil)
|
8
9
|
if Arel::VERSION.to_i < 7
|
9
10
|
Arel::Nodes::Matches.new(self, Arel::Nodes.build_quoted(other), escape)
|
10
11
|
else
|
@@ -12,7 +13,7 @@ module ArelExtensions
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
|
-
def imatches(other, escape=nil)
|
16
|
+
def imatches(other, escape = nil)
|
16
17
|
ArelExtensions::Nodes::IMatches.new(self, other, escape)
|
17
18
|
end
|
18
19
|
|
@@ -20,51 +21,53 @@ module ArelExtensions
|
|
20
21
|
ArelExtensions::Nodes::Cast.new([self,right])
|
21
22
|
end
|
22
23
|
|
23
|
-
def in(other) #In should handle nil element in the Array
|
24
|
+
def in(*other) #In should handle nil element in the Array
|
25
|
+
other = other.first if other.length <= 1
|
24
26
|
case other
|
25
27
|
when Range
|
26
28
|
self.between(other)
|
29
|
+
when Arel::Nodes::Grouping
|
30
|
+
Arel::Nodes::In.new(self, quoted_node(other))
|
27
31
|
when Enumerable
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
Arel::Nodes::In.new(self,quoted_array(other))
|
40
|
-
end
|
32
|
+
nils, values = other.partition{ |v| v.nil? }
|
33
|
+
ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
|
34
|
+
# In order of (imagined) decreasing efficiency: nil, values, and then more complex.
|
35
|
+
clauses =
|
36
|
+
nils.uniq.map { |r| self.in(r) } \
|
37
|
+
+ (case values.uniq.size
|
38
|
+
when 0 then []
|
39
|
+
when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.in(values[0]) : self.eq(values[0])]
|
40
|
+
else [Arel::Nodes::In.new(self, quoted_array(values))] end) \
|
41
|
+
+ ranges.uniq.map { |r| self.in(r) }
|
42
|
+
clauses.empty? ? Arel.false : clauses.reduce(&:or)
|
41
43
|
when nil
|
42
44
|
self.is_null
|
43
45
|
when Arel::SelectManager
|
44
46
|
Arel::Nodes::In.new(self, other.ast)
|
45
47
|
else
|
46
|
-
Arel::Nodes::In.new(self,quoted_node(other))
|
48
|
+
Arel::Nodes::In.new(self, quoted_node(other))
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
def not_in(other) #In should handle nil element in the Array
|
52
|
+
def not_in(*other) #In should handle nil element in the Array
|
53
|
+
other = other.first if other.length <= 1
|
51
54
|
case other
|
52
55
|
when Range
|
53
56
|
Arel::Nodes::Not.new(self.between(other))
|
57
|
+
when Arel::Nodes::Grouping
|
58
|
+
Arel::Nodes::NotIn.new(self, quoted_node(other))
|
54
59
|
when Enumerable
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
Arel::Nodes::NotIn.new(self,quoted_array(other))
|
67
|
-
end
|
60
|
+
nils, values = other.partition{ |v| v.nil? }
|
61
|
+
ranges, values = values.partition{ |v| v.is_a?(Range) || v.is_a?(Arel::SelectManager)}
|
62
|
+
# In order of (imagined) decreasing efficiency: nil, values, and then more complex.
|
63
|
+
clauses =
|
64
|
+
nils.uniq.map { |r| self.not_in(r) } \
|
65
|
+
+ (case values.uniq.size
|
66
|
+
when 0 then []
|
67
|
+
when 1 then [values[0].is_a?(Arel::Nodes::Grouping) ? self.not_in(values[0]) : self.not_eq(values[0])]
|
68
|
+
else [Arel::Nodes::NotIn.new(self, quoted_array(values))] end) \
|
69
|
+
+ ranges.uniq.map { |r| self.not_in(r) }
|
70
|
+
Arel::Nodes::And.new clauses
|
68
71
|
when nil
|
69
72
|
self.is_not_null
|
70
73
|
when Arel::SelectManager
|
@@ -94,6 +97,5 @@ module ArelExtensions
|
|
94
97
|
raise(ArgumentError, "#{object.class} can not be converted to CONCAT arg")
|
95
98
|
end
|
96
99
|
end
|
97
|
-
|
98
100
|
end
|
99
101
|
end
|
@@ -23,10 +23,10 @@ module ArelExtensions
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
Arel::Nodes::Union
|
26
|
+
class Arel::Nodes::Union
|
27
27
|
include ArelExtensions::SetFunctions
|
28
28
|
end
|
29
29
|
|
30
|
-
Arel::Nodes::UnionAll
|
30
|
+
class Arel::Nodes::UnionAll
|
31
31
|
include ArelExtensions::SetFunctions
|
32
32
|
end
|
@@ -64,6 +64,19 @@ module ArelExtensions
|
|
64
64
|
grouping_any :imatches, others, escape
|
65
65
|
end
|
66
66
|
|
67
|
+
# def grouping_any method, others, *extra
|
68
|
+
# puts "*******************"
|
69
|
+
# puts method
|
70
|
+
# puts others.inspect
|
71
|
+
# puts extra.inspect
|
72
|
+
# puts "-------------------"
|
73
|
+
# res = super(method,others,*extra)
|
74
|
+
# puts res.to_sql
|
75
|
+
# puts res.inspect
|
76
|
+
# puts "*******************"
|
77
|
+
# res
|
78
|
+
# end
|
79
|
+
|
67
80
|
def imatches_all others, escape = nil
|
68
81
|
grouping_all :imatches, others, escape, escape
|
69
82
|
end
|
@@ -92,7 +105,7 @@ module ArelExtensions
|
|
92
105
|
ArelExtensions::Nodes::SMatches.new(self,other)
|
93
106
|
end
|
94
107
|
|
95
|
-
def ai_collate
|
108
|
+
def ai_collate
|
96
109
|
ArelExtensions::Nodes::Collate.new(self,nil,true,false)
|
97
110
|
end
|
98
111
|
|
@@ -100,31 +113,40 @@ module ArelExtensions
|
|
100
113
|
ArelExtensions::Nodes::Collate.new(self,nil,false,true)
|
101
114
|
end
|
102
115
|
|
103
|
-
def collate ai=false,ci=false, option=nil
|
116
|
+
def collate ai = false,ci = false, option = nil
|
104
117
|
ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
|
105
118
|
end
|
106
119
|
|
107
120
|
#REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
|
108
|
-
def replace
|
109
|
-
|
121
|
+
def replace pattern, substitute
|
122
|
+
if pattern.is_a? Regexp
|
123
|
+
ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
|
124
|
+
else
|
125
|
+
ArelExtensions::Nodes::Replace.new self, pattern, substitute
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def regexp_replace pattern, substitute
|
130
|
+
ArelExtensions::Nodes::RegexpReplace.new self, pattern, substitute
|
110
131
|
end
|
111
|
-
|
132
|
+
|
112
133
|
def concat other
|
113
134
|
ArelExtensions::Nodes::Concat.new [self, other]
|
114
135
|
end
|
115
136
|
|
116
137
|
#concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
|
117
|
-
def group_concat
|
138
|
+
def group_concat(sep = nil, *orders, group: nil, order: nil)
|
139
|
+
if orders.present?
|
140
|
+
warn("Warning : ArelExtensions: group_concat: you should now use the kwarg 'order' to specify an order in the group_concat.")
|
141
|
+
end
|
118
142
|
order_tabs = [orders].flatten.map{ |o|
|
119
143
|
if o.is_a?(Arel::Nodes::Ascending) || o.is_a?(Arel::Nodes::Descending)
|
120
144
|
o
|
121
145
|
elsif o.respond_to?(:asc)
|
122
146
|
o.asc
|
123
|
-
else
|
124
|
-
nil
|
125
147
|
end
|
126
148
|
}.compact
|
127
|
-
ArelExtensions::Nodes::GroupConcat.new
|
149
|
+
ArelExtensions::Nodes::GroupConcat.new(self, sep, group: group, order: (order || order_tabs))
|
128
150
|
end
|
129
151
|
|
130
152
|
#Function returns a string after removing left, right or the both prefixes or suffixes int argument
|
@@ -155,11 +177,11 @@ module ArelExtensions
|
|
155
177
|
def not_blank
|
156
178
|
ArelExtensions::Nodes::NotBlank.new [self]
|
157
179
|
end
|
158
|
-
|
159
|
-
def repeat other = 1
|
180
|
+
|
181
|
+
def repeat other = 1
|
160
182
|
ArelExtensions::Nodes::Repeat.new [self, other]
|
161
183
|
end
|
162
|
-
|
184
|
+
|
163
185
|
def levenshtein_distance other
|
164
186
|
ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
|
165
187
|
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
|
@@ -6,7 +6,7 @@ require 'arel_extensions/visitors/postgresql'
|
|
6
6
|
require 'arel_extensions/visitors/sqlite'
|
7
7
|
require 'arel_extensions/visitors/mssql'
|
8
8
|
|
9
|
-
Arel::Visitors::MSSQL
|
9
|
+
class Arel::Visitors::MSSQL
|
10
10
|
include ArelExtensions::Visitors::MSSQL
|
11
11
|
|
12
12
|
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
@@ -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,6 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
Arel::Visitors::MySQL
|
3
|
+
class Arel::Visitors::MySQL
|
4
4
|
Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
5
5
|
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
6
6
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
@@ -97,26 +97,28 @@ module ArelExtensions
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
charset =
|
101
|
+
case o.expressions.first
|
102
|
+
when Arel::Attributes::Attribute
|
103
|
+
case o.option
|
103
104
|
when 'latin1','utf8'
|
104
105
|
o.option
|
105
106
|
else
|
106
107
|
Arel::Table.engine.connection.charset || 'utf8'
|
107
108
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
else
|
110
|
+
(o.option == 'latin1') ? 'latin1' : 'utf8'
|
111
|
+
end
|
111
112
|
collector = visit o.expressions.first, collector
|
112
|
-
|
113
|
-
|
113
|
+
collector <<
|
114
|
+
if o.ai
|
115
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
114
116
|
#doesn't work in latin1
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
117
|
+
elsif o.ci
|
118
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci' }"
|
119
|
+
else
|
120
|
+
" COLLATE #{charset}_bin"
|
121
|
+
end
|
120
122
|
collector
|
121
123
|
end
|
122
124
|
|
@@ -139,16 +141,16 @@ module ArelExtensions
|
|
139
141
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
140
142
|
collector << "GROUP_CONCAT("
|
141
143
|
collector = visit o.left, collector
|
142
|
-
if !o.
|
144
|
+
if !o.order.blank?
|
143
145
|
collector << ' ORDER BY '
|
144
|
-
o.
|
146
|
+
o.order.each_with_index do |order,i|
|
145
147
|
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
146
148
|
collector = visit order, collector
|
147
149
|
end
|
148
150
|
end
|
149
|
-
if o.
|
151
|
+
if o.separator && o.separator != 'NULL'
|
150
152
|
collector << ' SEPARATOR '
|
151
|
-
collector = visit o.
|
153
|
+
collector = visit o.separator, collector
|
152
154
|
end
|
153
155
|
collector << ")"
|
154
156
|
collector
|
@@ -191,6 +193,13 @@ module ArelExtensions
|
|
191
193
|
collector
|
192
194
|
end
|
193
195
|
|
196
|
+
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
197
|
+
if !regexp_replace_supported?
|
198
|
+
warn("Warning : ArelExtensions: REGEXP_REPLACE does not seem to be available in the current version of the DBMS, it might crash")
|
199
|
+
end
|
200
|
+
super(o,collector)
|
201
|
+
end
|
202
|
+
|
194
203
|
def visit_ArelExtensions_Nodes_Format o, collector
|
195
204
|
case o.col_type
|
196
205
|
when :date, :datetime
|
@@ -262,7 +271,7 @@ module ArelExtensions
|
|
262
271
|
else
|
263
272
|
if o.with_interval
|
264
273
|
case o.left
|
265
|
-
when
|
274
|
+
when 'd','m','y'
|
266
275
|
interval = 'DAY'
|
267
276
|
when 'h','mn','s'
|
268
277
|
interval = 'SECOND'
|
@@ -362,20 +371,21 @@ module ArelExtensions
|
|
362
371
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
363
372
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
364
373
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
+
number =
|
375
|
+
if o.scientific_notation
|
376
|
+
ArelExtensions::Nodes::Concat.new([
|
377
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
378
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)
|
379
|
+
]+params),
|
380
|
+
o.type,
|
381
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[
|
382
|
+
col.abs.log10.floor,
|
383
|
+
0
|
384
|
+
])
|
374
385
|
])
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
end
|
386
|
+
else
|
387
|
+
Arel::Nodes::NamedFunction.new('FORMAT',[col.abs]+params)
|
388
|
+
end
|
379
389
|
|
380
390
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
381
391
|
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
@@ -398,10 +408,34 @@ module ArelExtensions
|
|
398
408
|
collector
|
399
409
|
end
|
400
410
|
|
411
|
+
def visit_Aggregate_For_AggregateFunction o, collector
|
412
|
+
if !window_supported?
|
413
|
+
warn("Warning : ArelExtensions: Window Functions are not available in the current version of the DBMS.")
|
414
|
+
return collector
|
415
|
+
end
|
416
|
+
|
417
|
+
if !o.order.empty? || !o.group.empty?
|
418
|
+
collector << " OVER ("
|
419
|
+
if !o.group.empty?
|
420
|
+
collector << " PARTITION BY ("
|
421
|
+
visit o.group, collector
|
422
|
+
collector << ")"
|
423
|
+
end
|
424
|
+
if !o.order.empty?
|
425
|
+
collector << " ORDER BY ("
|
426
|
+
visit o.order, collector
|
427
|
+
collector << ")"
|
428
|
+
end
|
429
|
+
collector << ")"
|
430
|
+
end
|
431
|
+
collector
|
432
|
+
end
|
433
|
+
|
401
434
|
def visit_ArelExtensions_Nodes_Std o, collector
|
402
435
|
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
403
436
|
visit o.left, collector
|
404
437
|
collector << ")"
|
438
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
405
439
|
collector
|
406
440
|
end
|
407
441
|
|
@@ -409,15 +443,35 @@ module ArelExtensions
|
|
409
443
|
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
410
444
|
visit o.left, collector
|
411
445
|
collector << ")"
|
446
|
+
visit_Aggregate_For_AggregateFunction o, collector
|
412
447
|
collector
|
413
448
|
end
|
414
449
|
|
415
450
|
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
416
451
|
def json_supported?
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
452
|
+
version_supported?('10.2.3', '5.7.0')
|
453
|
+
end
|
454
|
+
|
455
|
+
def window_supported?
|
456
|
+
version_supported?('10.2.3', '8.0')
|
457
|
+
end
|
458
|
+
|
459
|
+
def regexp_replace_supported?
|
460
|
+
version_supported?('10.0.5', '8.0')
|
461
|
+
end
|
462
|
+
|
463
|
+
def version_supported?(mariadb_v = '10.2.3', mysql_v = '5.7.0')
|
464
|
+
conn = Arel::Table.engine.connection
|
465
|
+
conn.send(:mariadb?) && \
|
466
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mariadb_v || \
|
467
|
+
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v || \
|
468
|
+
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mariadb_v) || \
|
469
|
+
!conn.send(:mariadb?) && \
|
470
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v || \
|
471
|
+
conn.respond_to?(:version) && conn.send(:version) >= mysql_v || \
|
472
|
+
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mysql_v)
|
473
|
+
# ideally we should parse the instance_variable @full_version because @version contains only the supposedly
|
474
|
+
# corresponding mysql version of the current mariadb version (which is not very helpful most of the time)
|
421
475
|
end
|
422
476
|
|
423
477
|
def visit_ArelExtensions_Nodes_Json o,collector
|