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,67 +1,43 @@
|
|
|
1
1
|
module ArelExtensions
|
|
2
2
|
module Visitors
|
|
3
|
-
|
|
4
|
-
DATE_MAPPING = {
|
|
5
|
-
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
|
|
13
|
-
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'TMDy', '%A' => 'TMDay', # day, weekday
|
|
14
|
-
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
|
15
|
-
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
|
|
16
|
-
'%%' => '%',
|
|
17
|
-
}.freeze
|
|
18
|
-
|
|
19
|
-
NUMBER_COMMA_MAPPING = {
|
|
20
|
-
'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '
|
|
21
|
-
}.freeze
|
|
22
|
-
|
|
23
|
-
def visit_ArelExtensions_Nodes_ByteSize o, collector
|
|
24
|
-
collector << 'octet_length('
|
|
25
|
-
collector = visit o.expr.coalesce(''), collector
|
|
26
|
-
collector << ')'
|
|
27
|
-
collector
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def visit_ArelExtensions_Nodes_CharLength o, collector
|
|
31
|
-
collector << 'length('
|
|
32
|
-
collector = visit o.expr.coalesce(''), collector
|
|
33
|
-
collector << ')'
|
|
34
|
-
collector
|
|
35
|
-
end
|
|
3
|
+
Arel::Visitors::PostgreSQL.class_eval do
|
|
4
|
+
Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
|
5
|
+
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
|
|
6
|
+
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
|
7
|
+
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
|
8
|
+
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
|
9
|
+
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
|
10
|
+
}
|
|
11
|
+
Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
|
|
36
12
|
|
|
37
13
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
|
38
|
-
collector <<
|
|
39
|
-
if
|
|
14
|
+
collector << "RANDOM("
|
|
15
|
+
if(o.left != nil && o.right != nil)
|
|
40
16
|
collector = visit o.left, collector
|
|
41
|
-
collector << COMMA
|
|
17
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
42
18
|
collector = isit o.right, collector
|
|
43
19
|
end
|
|
44
|
-
collector <<
|
|
20
|
+
collector << ")"
|
|
45
21
|
collector
|
|
46
22
|
end
|
|
47
23
|
|
|
48
24
|
def visit_ArelExtensions_Nodes_Power o, collector
|
|
49
|
-
collector <<
|
|
25
|
+
collector << "POWER("
|
|
50
26
|
o.expressions.each_with_index { |arg, i|
|
|
51
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
27
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
52
28
|
collector = visit arg, collector
|
|
53
29
|
}
|
|
54
|
-
collector <<
|
|
30
|
+
collector << ")"
|
|
55
31
|
collector
|
|
56
32
|
end
|
|
57
33
|
|
|
58
34
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
|
59
|
-
collector <<
|
|
35
|
+
collector << "LOG("
|
|
60
36
|
o.expressions.each_with_index { |arg, i|
|
|
61
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
37
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
62
38
|
collector = visit arg, collector
|
|
63
39
|
}
|
|
64
|
-
collector <<
|
|
40
|
+
collector << ")"
|
|
65
41
|
collector
|
|
66
42
|
end
|
|
67
43
|
|
|
@@ -69,7 +45,7 @@ module ArelExtensions
|
|
|
69
45
|
remove_method(:visit_Arel_Nodes_Regexp) rescue nil
|
|
70
46
|
def visit_Arel_Nodes_Regexp o, collector
|
|
71
47
|
collector = visit o.left, collector
|
|
72
|
-
collector <<
|
|
48
|
+
collector << " ~ "
|
|
73
49
|
collector = visit o.right, collector
|
|
74
50
|
collector
|
|
75
51
|
end
|
|
@@ -77,7 +53,7 @@ module ArelExtensions
|
|
|
77
53
|
remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil
|
|
78
54
|
def visit_Arel_Nodes_NotRegexp o, collector
|
|
79
55
|
collector = visit o.left, collector
|
|
80
|
-
collector <<
|
|
56
|
+
collector << " !~ "
|
|
81
57
|
collector = visit o.right, collector
|
|
82
58
|
collector
|
|
83
59
|
end
|
|
@@ -88,11 +64,11 @@ module ArelExtensions
|
|
|
88
64
|
collector = visit arg, collector
|
|
89
65
|
collector << ' || ' unless i == o.expressions.length - 1
|
|
90
66
|
}
|
|
91
|
-
collector <<
|
|
67
|
+
collector << ")"
|
|
92
68
|
collector
|
|
93
69
|
end
|
|
94
70
|
|
|
95
|
-
alias_method
|
|
71
|
+
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
|
96
72
|
def visit_Arel_Nodes_As o, collector
|
|
97
73
|
if o.left.is_a?(Arel::Nodes::Binary)
|
|
98
74
|
collector << '('
|
|
@@ -101,126 +77,80 @@ module ArelExtensions
|
|
|
101
77
|
else
|
|
102
78
|
collector = visit o.left, collector
|
|
103
79
|
end
|
|
104
|
-
collector <<
|
|
105
|
-
|
|
106
|
-
# sometimes these values are already quoted, if they are, don't double quote it
|
|
107
|
-
quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
|
|
108
|
-
|
|
109
|
-
collector << '"' if quote
|
|
80
|
+
collector << " AS \""
|
|
110
81
|
collector = visit o.right, collector
|
|
111
|
-
collector <<
|
|
112
|
-
|
|
113
|
-
collector
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def visit_Aggregate_For_AggregateFunction o, collector
|
|
117
|
-
if !o.order.blank? || !o.group.blank?
|
|
118
|
-
collector << ' OVER ('
|
|
119
|
-
if !o.group.blank?
|
|
120
|
-
collector << ' PARTITION BY '
|
|
121
|
-
o.group.each_with_index do |group, i|
|
|
122
|
-
collector << COMMA if i != 0
|
|
123
|
-
visit group, collector
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
if !o.order.blank?
|
|
127
|
-
collector << ' ORDER BY '
|
|
128
|
-
o.order.each_with_index do |order, i|
|
|
129
|
-
collector << COMMA if i != 0
|
|
130
|
-
visit order, collector
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
collector << ')'
|
|
134
|
-
end
|
|
82
|
+
collector << "\""
|
|
135
83
|
collector
|
|
136
84
|
end
|
|
137
85
|
|
|
138
86
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
139
|
-
collector <<
|
|
87
|
+
collector << "array_to_string(array_agg("
|
|
140
88
|
collector = visit o.left, collector
|
|
141
|
-
if
|
|
142
|
-
collector << ' ORDER BY'
|
|
143
|
-
o.
|
|
144
|
-
collector << COMMA
|
|
145
|
-
collector
|
|
146
|
-
visit order, collector
|
|
89
|
+
if !o.orders.blank?
|
|
90
|
+
collector << ' ORDER BY '
|
|
91
|
+
o.orders.each_with_index do |order,i|
|
|
92
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
|
93
|
+
collector = visit order, collector
|
|
147
94
|
end
|
|
148
95
|
end
|
|
149
|
-
collector <<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
else
|
|
158
|
-
visit Arel.quoted(','), collector
|
|
159
|
-
end
|
|
160
|
-
collector << ')'
|
|
96
|
+
collector << ")"
|
|
97
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
98
|
+
if o.right && o.right != 'NULL'
|
|
99
|
+
collector = visit o.right, collector
|
|
100
|
+
else
|
|
101
|
+
collector = visit Arel::Nodes.build_quoted(','), collector
|
|
102
|
+
end
|
|
103
|
+
collector << ")"
|
|
161
104
|
collector
|
|
162
105
|
end
|
|
163
106
|
|
|
164
107
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
108
|
+
collector << 'TRIM(BOTH '
|
|
109
|
+
collector = visit o.right, collector
|
|
110
|
+
collector << " FROM "
|
|
111
|
+
collector = visit o.left, collector
|
|
112
|
+
collector << ")"
|
|
113
|
+
collector
|
|
171
114
|
end
|
|
172
115
|
|
|
173
116
|
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
117
|
+
collector << 'TRIM(LEADING '
|
|
118
|
+
collector = visit o.right, collector
|
|
119
|
+
collector << " FROM "
|
|
120
|
+
collector = visit o.left, collector
|
|
121
|
+
collector << ")"
|
|
122
|
+
collector
|
|
180
123
|
end
|
|
181
124
|
|
|
182
125
|
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
|
183
126
|
collector << 'TRIM(TRAILING '
|
|
184
127
|
collector = visit o.right, collector
|
|
185
|
-
collector <<
|
|
128
|
+
collector << " FROM "
|
|
186
129
|
collector = visit o.left, collector
|
|
187
|
-
collector <<
|
|
130
|
+
collector << ")"
|
|
188
131
|
collector
|
|
189
132
|
end
|
|
190
133
|
|
|
191
134
|
def visit_ArelExtensions_Nodes_Format o, collector
|
|
192
|
-
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
|
196
|
-
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
|
197
|
-
collector << 'TO_CHAR('
|
|
198
|
-
collector << '(' if o.time_zone
|
|
135
|
+
collector << "TO_CHAR("
|
|
199
136
|
collector = visit o.left, collector
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
when String
|
|
208
|
-
collector << ") AT TIME ZONE 'UTC' AT TIME ZONE "
|
|
209
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
|
210
|
-
end
|
|
211
|
-
collector << COMMA
|
|
212
|
-
collector = visit Arel.quoted(fmt), collector
|
|
213
|
-
collector << ')'
|
|
137
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
138
|
+
|
|
139
|
+
f = o.iso_format.dup
|
|
140
|
+
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
|
141
|
+
collector = visit Arel::Nodes.build_quoted(f), collector
|
|
142
|
+
|
|
143
|
+
collector << ")"
|
|
214
144
|
collector
|
|
215
145
|
end
|
|
216
146
|
|
|
217
147
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
|
218
|
-
collector <<
|
|
148
|
+
collector << "REPEAT("
|
|
219
149
|
o.expressions.each_with_index { |arg, i|
|
|
220
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
150
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
221
151
|
collector = visit arg, collector
|
|
222
152
|
}
|
|
223
|
-
collector <<
|
|
153
|
+
collector << ")"
|
|
224
154
|
collector
|
|
225
155
|
end
|
|
226
156
|
|
|
@@ -262,9 +192,9 @@ module ArelExtensions
|
|
|
262
192
|
|
|
263
193
|
def visit_ArelExtensions_Nodes_Collate o, collector
|
|
264
194
|
if o.ai
|
|
265
|
-
collector <<
|
|
195
|
+
collector << "unaccent("
|
|
266
196
|
collector = visit o.expressions.first, collector
|
|
267
|
-
collector <<
|
|
197
|
+
collector << ")"
|
|
268
198
|
elsif o.ci
|
|
269
199
|
collector = visit o.expressions.first, collector
|
|
270
200
|
else
|
|
@@ -275,7 +205,7 @@ module ArelExtensions
|
|
|
275
205
|
|
|
276
206
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
|
277
207
|
collector = visit o.left, collector
|
|
278
|
-
collector << ' + ' #
|
|
208
|
+
collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
|
|
279
209
|
collector = visit o.postgresql_value(o.right), collector
|
|
280
210
|
collector
|
|
281
211
|
end
|
|
@@ -283,16 +213,16 @@ module ArelExtensions
|
|
|
283
213
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
|
284
214
|
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
|
|
285
215
|
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
|
286
|
-
|
|
216
|
+
"DATEDIFF('second', "
|
|
287
217
|
else
|
|
288
|
-
|
|
218
|
+
"DATEDIFF('day', "
|
|
289
219
|
end
|
|
290
220
|
collector = visit o.right, collector
|
|
291
221
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
|
292
|
-
collector << COMMA
|
|
222
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
293
223
|
collector = visit o.left, collector
|
|
294
224
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
|
295
|
-
collector <<
|
|
225
|
+
collector << ")"
|
|
296
226
|
else
|
|
297
227
|
collector << '('
|
|
298
228
|
collector = visit o.left, collector
|
|
@@ -309,57 +239,41 @@ module ArelExtensions
|
|
|
309
239
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
|
310
240
|
if o.with_interval
|
|
311
241
|
interval = case o.left
|
|
312
|
-
when 'd',
|
|
242
|
+
when 'd','m','y'
|
|
313
243
|
'DAY'
|
|
314
|
-
when 'h',
|
|
244
|
+
when 'h','mn','s'
|
|
315
245
|
'SECOND'
|
|
316
246
|
when /i\z/
|
|
317
|
-
collector <<
|
|
247
|
+
collector << "("
|
|
318
248
|
collector = visit o.right, collector
|
|
319
|
-
collector <<
|
|
320
|
-
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
|
249
|
+
collector << ")"
|
|
250
|
+
collector << " * (INTERVAL '1' #{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left[0..-2]]})"
|
|
321
251
|
return collector
|
|
322
252
|
end
|
|
323
253
|
end
|
|
324
|
-
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM
|
|
254
|
+
collector << "EXTRACT(#{Arel::Visitors::PostgreSQL::DATE_MAPPING[o.left]} FROM "
|
|
325
255
|
collector = visit o.right, collector
|
|
326
|
-
collector <<
|
|
256
|
+
collector << ")"
|
|
327
257
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
|
328
258
|
collector
|
|
329
259
|
end
|
|
330
260
|
|
|
331
261
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
|
332
|
-
collector <<
|
|
262
|
+
collector << "POSITION("
|
|
333
263
|
collector = visit o.right, collector
|
|
334
|
-
collector <<
|
|
264
|
+
collector << " IN "
|
|
335
265
|
collector = visit o.left, collector
|
|
336
|
-
collector <<
|
|
266
|
+
collector << ")"
|
|
337
267
|
collector
|
|
338
268
|
end
|
|
339
269
|
|
|
340
270
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
|
341
|
-
collector <<
|
|
271
|
+
collector << "SUBSTR("
|
|
342
272
|
o.expressions.each_with_index { |arg, i|
|
|
343
|
-
collector << COMMA
|
|
273
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
|
344
274
|
collector = visit arg, collector
|
|
345
275
|
}
|
|
346
|
-
collector <<
|
|
347
|
-
collector
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
|
351
|
-
collector << 'REGEXP_REPLACE('
|
|
352
|
-
visit o.left, collector
|
|
353
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
354
|
-
tab = o.pattern.inspect + 'g' # Make it always global
|
|
355
|
-
pattern = tab.split('/')[1..-2].join('/')
|
|
356
|
-
flags = tab.split('/')[-1]
|
|
357
|
-
visit Arel.quoted(pattern), collector
|
|
358
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
359
|
-
visit o.substitute, collector
|
|
360
|
-
collector << Arel::Visitors::ToSql::COMMA
|
|
361
|
-
visit Arel.quoted(flags + 'g'), collector
|
|
362
|
-
collector << ')'
|
|
276
|
+
collector << ")"
|
|
363
277
|
collector
|
|
364
278
|
end
|
|
365
279
|
|
|
@@ -370,111 +284,98 @@ module ArelExtensions
|
|
|
370
284
|
end
|
|
371
285
|
|
|
372
286
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
|
373
|
-
|
|
287
|
+
collector = visit o.expr, collector
|
|
374
288
|
collector << ' IS NOT NULL'
|
|
375
289
|
collector
|
|
376
290
|
end
|
|
377
291
|
|
|
378
292
|
def visit_ArelExtensions_Nodes_Sum o, collector
|
|
379
|
-
collector <<
|
|
293
|
+
collector << "sum("
|
|
380
294
|
collector = visit o.expr, collector
|
|
381
|
-
collector <<
|
|
382
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
295
|
+
collector << ")"
|
|
383
296
|
collector
|
|
384
297
|
end
|
|
385
298
|
|
|
386
299
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
|
387
|
-
collector <<
|
|
300
|
+
collector << "EXRTACT(DOW, "
|
|
388
301
|
collector = visit o.date, collector
|
|
389
302
|
collector << ')'
|
|
390
303
|
collector
|
|
391
304
|
end
|
|
392
305
|
|
|
393
306
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
|
394
|
-
as_attr =
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
'jsonb'
|
|
417
|
-
else
|
|
418
|
-
o.as_attr.to_s
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
collector << 'CAST('
|
|
307
|
+
as_attr = case o.as_attr
|
|
308
|
+
when :string
|
|
309
|
+
Arel::Nodes::SqlLiteral.new('varchar')
|
|
310
|
+
when :time
|
|
311
|
+
Arel::Nodes::SqlLiteral.new('time')
|
|
312
|
+
when :int
|
|
313
|
+
collector << "CAST(CAST("
|
|
314
|
+
collector = visit o.left, collector
|
|
315
|
+
collector << " AS numeric) AS int)"
|
|
316
|
+
return collector
|
|
317
|
+
when :number, :decimal, :float
|
|
318
|
+
Arel::Nodes::SqlLiteral.new('numeric')
|
|
319
|
+
when :datetime
|
|
320
|
+
Arel::Nodes::SqlLiteral.new('timestamp')
|
|
321
|
+
when :date
|
|
322
|
+
Arel::Nodes::SqlLiteral.new('date')
|
|
323
|
+
when :binary
|
|
324
|
+
Arel::Nodes::SqlLiteral.new('binary')
|
|
325
|
+
else
|
|
326
|
+
Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
|
327
|
+
end
|
|
328
|
+
collector << "CAST("
|
|
422
329
|
collector = visit o.left, collector
|
|
423
|
-
collector <<
|
|
424
|
-
collector = visit
|
|
425
|
-
collector <<
|
|
330
|
+
collector << " AS "
|
|
331
|
+
collector = visit as_attr, collector
|
|
332
|
+
collector << ")"
|
|
426
333
|
collector
|
|
427
334
|
end
|
|
428
335
|
|
|
429
336
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
|
430
337
|
col = o.left.coalesce(0)
|
|
431
|
-
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
|
432
|
-
thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
|
|
338
|
+
comma = o.precision == 0 ? '' : (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
|
339
|
+
thousand_separator = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale][1] || (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
|
|
433
340
|
nines_after = (1..o.precision).map{'9'}.join('')
|
|
434
|
-
nines_before = ("999#{thousand_separator}"
|
|
341
|
+
nines_before = ("999#{thousand_separator}"*4+"990")
|
|
435
342
|
|
|
436
|
-
sign =
|
|
343
|
+
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
|
437
344
|
then('-').
|
|
438
345
|
else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
|
|
439
346
|
sign_length = ArelExtensions::Nodes::Length.new([sign])
|
|
440
347
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
end
|
|
348
|
+
if o.scientific_notation
|
|
349
|
+
number = ArelExtensions::Nodes::Concat.new([
|
|
350
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
|
351
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
|
352
|
+
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
|
353
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
|
354
|
+
])]),
|
|
355
|
+
o.type,
|
|
356
|
+
Arel::Nodes::NamedFunction.new('TRIM',[
|
|
357
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
|
358
|
+
col.abs.log10.floor,
|
|
359
|
+
Arel::Nodes.build_quoted('FM'+nines_before)
|
|
360
|
+
])])
|
|
361
|
+
])
|
|
362
|
+
else
|
|
363
|
+
number = Arel::Nodes::NamedFunction.new('TRIM',[
|
|
364
|
+
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
|
365
|
+
Arel::Nodes.build_quoted(col.abs),
|
|
366
|
+
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
|
367
|
+
])])
|
|
368
|
+
end
|
|
463
369
|
|
|
464
|
-
repeated_char =
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
Arel
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
)
|
|
474
|
-
.else('')
|
|
475
|
-
end
|
|
476
|
-
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
477
|
-
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
|
370
|
+
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
|
371
|
+
when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
|
|
372
|
+
then(Arel::Nodes.build_quoted(
|
|
373
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
|
374
|
+
).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
|
|
375
|
+
).
|
|
376
|
+
else('')
|
|
377
|
+
before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
378
|
+
middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
|
478
379
|
after = o.flags.include?('-') ? repeated_char : ''
|
|
479
380
|
full_number = ArelExtensions::Nodes::Concat.new([
|
|
480
381
|
before,
|
|
@@ -483,30 +384,30 @@ module ArelExtensions
|
|
|
483
384
|
number,
|
|
484
385
|
after
|
|
485
386
|
])
|
|
486
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel.
|
|
387
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
|
487
388
|
collector
|
|
488
389
|
end
|
|
489
390
|
|
|
490
391
|
|
|
491
|
-
alias_method
|
|
392
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
|
492
393
|
def visit_Arel_Nodes_SelectStatement o, collector
|
|
493
394
|
|
|
494
395
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
|
495
396
|
o = o.dup
|
|
496
397
|
o.orders = []
|
|
497
398
|
end
|
|
498
|
-
old_visit_Arel_Nodes_SelectStatement(o,
|
|
399
|
+
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
|
499
400
|
end
|
|
500
401
|
|
|
501
|
-
alias_method
|
|
402
|
+
alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
|
|
502
403
|
def visit_Arel_Nodes_TableAlias o, collector
|
|
503
404
|
if o.name.length > 63
|
|
504
405
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
|
505
406
|
end
|
|
506
|
-
old_visit_Arel_Nodes_TableAlias(o,
|
|
407
|
+
old_visit_Arel_Nodes_TableAlias(o,collector)
|
|
507
408
|
end
|
|
508
409
|
|
|
509
|
-
alias_method
|
|
410
|
+
alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
|
|
510
411
|
def visit_Arel_Attributes_Attribute o, collector
|
|
511
412
|
join_name = o.relation.table_alias || o.relation.name
|
|
512
413
|
if join_name.length > 63
|
|
@@ -516,35 +417,33 @@ module ArelExtensions
|
|
|
516
417
|
end
|
|
517
418
|
|
|
518
419
|
def visit_ArelExtensions_Nodes_Std o, collector
|
|
519
|
-
collector << (o.unbiased_estimator ?
|
|
420
|
+
collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
|
|
520
421
|
visit o.left, collector
|
|
521
|
-
collector <<
|
|
522
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
422
|
+
collector << ")"
|
|
523
423
|
collector
|
|
524
424
|
end
|
|
525
425
|
|
|
526
426
|
def visit_ArelExtensions_Nodes_Variance o, collector
|
|
527
|
-
collector << (o.unbiased_estimator ?
|
|
427
|
+
collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
|
|
528
428
|
visit o.left, collector
|
|
529
|
-
collector <<
|
|
530
|
-
visit_Aggregate_For_AggregateFunction o, collector
|
|
429
|
+
collector << ")"
|
|
531
430
|
collector
|
|
532
431
|
end
|
|
533
432
|
|
|
534
|
-
def visit_ArelExtensions_Nodes_Json o,
|
|
433
|
+
def visit_ArelExtensions_Nodes_Json o,collector
|
|
535
434
|
case o.dict
|
|
536
435
|
when Array
|
|
537
436
|
collector << 'to_jsonb(array['
|
|
538
|
-
o.dict.each.with_index do |v,
|
|
437
|
+
o.dict.each.with_index do |v,i|
|
|
539
438
|
if i != 0
|
|
540
439
|
collector << Arel::Visitors::MySQL::COMMA
|
|
541
440
|
end
|
|
542
|
-
collector
|
|
441
|
+
collector = visit v, collector
|
|
543
442
|
end
|
|
544
443
|
collector << '])'
|
|
545
444
|
when Hash
|
|
546
445
|
collector << 'jsonb_build_object('
|
|
547
|
-
o.dict.each.with_index do |(k,
|
|
446
|
+
o.dict.each.with_index do |(k,v),i|
|
|
548
447
|
if i != 0
|
|
549
448
|
collector << Arel::Visitors::MySQL::COMMA
|
|
550
449
|
end
|
|
@@ -553,11 +452,13 @@ module ArelExtensions
|
|
|
553
452
|
collector = visit v, collector
|
|
554
453
|
end
|
|
555
454
|
collector << ')'
|
|
556
|
-
when String,
|
|
557
|
-
collector = visit Arel.
|
|
455
|
+
when String,Numeric,TrueClass,FalseClass
|
|
456
|
+
collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
|
|
558
457
|
collector << '::jsonb'
|
|
559
458
|
when NilClass
|
|
560
|
-
collector
|
|
459
|
+
collector << %Q['null'::jsonb]
|
|
460
|
+
when Arel::Attributes::Attribute
|
|
461
|
+
collector = visit o.dict.cast(:jsonb), collector
|
|
561
462
|
else
|
|
562
463
|
collector = visit o.dict, collector
|
|
563
464
|
collector << '::jsonb'
|
|
@@ -565,8 +466,8 @@ module ArelExtensions
|
|
|
565
466
|
collector
|
|
566
467
|
end
|
|
567
468
|
|
|
568
|
-
def visit_ArelExtensions_Nodes_JsonMerge o,
|
|
569
|
-
o.expressions.each.with_index do |v,
|
|
469
|
+
def visit_ArelExtensions_Nodes_JsonMerge o,collector
|
|
470
|
+
o.expressions.each.with_index do |v,i|
|
|
570
471
|
if i != 0
|
|
571
472
|
collector << ' || '
|
|
572
473
|
end
|
|
@@ -575,14 +476,14 @@ module ArelExtensions
|
|
|
575
476
|
collector
|
|
576
477
|
end
|
|
577
478
|
|
|
578
|
-
def visit_ArelExtensions_Nodes_JsonGet o,
|
|
479
|
+
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
|
579
480
|
collector = visit o.dict, collector
|
|
580
|
-
collector << '
|
|
481
|
+
collector << ' -> '
|
|
581
482
|
collector = visit o.key, collector
|
|
582
483
|
collector
|
|
583
484
|
end
|
|
584
485
|
|
|
585
|
-
def visit_ArelExtensions_Nodes_JsonSet o,
|
|
486
|
+
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
|
586
487
|
collector << 'jsonb_set('
|
|
587
488
|
collector = visit o.dict, collector
|
|
588
489
|
collector << Arel::Visitors::MySQL::COMMA
|
|
@@ -604,7 +505,7 @@ module ArelExtensions
|
|
|
604
505
|
else
|
|
605
506
|
case o.dict
|
|
606
507
|
when Hash
|
|
607
|
-
o.dict.each.with_index do |(k,
|
|
508
|
+
o.dict.each.with_index do |(k,v),i|
|
|
608
509
|
if i != 0
|
|
609
510
|
collector << ' || '
|
|
610
511
|
end
|
|
@@ -622,6 +523,7 @@ module ArelExtensions
|
|
|
622
523
|
end
|
|
623
524
|
collector
|
|
624
525
|
end
|
|
526
|
+
|
|
625
527
|
end
|
|
626
528
|
end
|
|
627
529
|
end
|