activerecord-oracle_enhanced-adapter 6.1.0.rc1 → 6.1.0
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/README.md +11 -0
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +17 -14
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +19 -17
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +7 -6
- data/lib/arel/visitors/oracle.rb +20 -56
- data/lib/arel/visitors/oracle12.rb +20 -56
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +74 -0
- metadata +4 -6
- data/spec/support/stats.sql +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5985d7537ecc79468e80b7ecddf9c8a52309719db665c0b904cb2d04994eb99
|
4
|
+
data.tar.gz: 0e01cd4d37d2cd9a3f1a48f33b9cdcc9b9adc340a186415cfccb13975693bd3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58000a64e1d069d9058848a5ecf33474c8ef09ebb7ecf660d9169b5cc4b4a1911e3f8b72f24011801885c333930c378252a8f2bba5ac4051806acde9093a1af3
|
7
|
+
data.tar.gz: 0c21d8db90ff52720800a717b47f776abf91eded32aec137141e1510453d1eea21e31f291a771df17d7a5957873f2d5479ada8a96aeb4eb24420598080157cfa
|
data/README.md
CHANGED
@@ -10,6 +10,17 @@ Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby o
|
|
10
10
|
|
11
11
|
INSTALLATION
|
12
12
|
------------
|
13
|
+
### Rails 6.1
|
14
|
+
|
15
|
+
Oracle enhanced adapter version 6.1 supports Rails 6.1.
|
16
|
+
When using Ruby on Rails version 6.1 then in Gemfile include
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
# Use oracle as the database for Active Record
|
20
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 6.1.0'
|
21
|
+
gem 'ruby-oci8' # only for CRuby users
|
22
|
+
```
|
23
|
+
|
13
24
|
### Rails 6.0
|
14
25
|
|
15
26
|
Oracle enhanced adapter version 6.0 supports Rails 6.0.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.1.0
|
1
|
+
6.1.0
|
@@ -34,7 +34,7 @@ module ActiveRecord
|
|
34
34
|
table_owner, table_name = default_owner, real_name
|
35
35
|
end
|
36
36
|
sql = <<~SQL.squish
|
37
|
-
SELECT owner, table_name, 'TABLE' name_type
|
37
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name, 'TABLE' name_type
|
38
38
|
FROM all_tables
|
39
39
|
WHERE owner = '#{table_owner}'
|
40
40
|
AND table_name = '#{table_name}'
|
@@ -181,7 +181,7 @@ module ActiveRecord #:nodoc:
|
|
181
181
|
def extract_expression_for_virtual_column(column)
|
182
182
|
column_name = column.name
|
183
183
|
@connection.select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
|
184
|
-
select data_default from all_tab_columns
|
184
|
+
select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ data_default from all_tab_columns
|
185
185
|
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
186
186
|
and table_name = :table_name
|
187
187
|
and column_name = :column_name
|
@@ -12,7 +12,8 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
def tables #:nodoc:
|
14
14
|
select_values(<<~SQL.squish, "SCHEMA")
|
15
|
-
SELECT
|
15
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
16
|
+
DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
|
16
17
|
FROM all_tables
|
17
18
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
18
19
|
AND secondary = 'N'
|
@@ -44,7 +45,7 @@ module ActiveRecord
|
|
44
45
|
end
|
45
46
|
|
46
47
|
select_values(<<~SQL.squish, "SCHEMA", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
|
47
|
-
SELECT owner, table_name
|
48
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name
|
48
49
|
FROM all_tables
|
49
50
|
WHERE owner = :owner
|
50
51
|
AND table_name = :table_name
|
@@ -60,20 +61,22 @@ module ActiveRecord
|
|
60
61
|
|
61
62
|
def views # :nodoc:
|
62
63
|
select_values(<<~SQL.squish, "SCHEMA")
|
63
|
-
SELECT
|
64
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
65
|
+
LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
64
66
|
SQL
|
65
67
|
end
|
66
68
|
|
67
69
|
def materialized_views #:nodoc:
|
68
70
|
select_values(<<~SQL.squish, "SCHEMA")
|
69
|
-
SELECT
|
71
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
72
|
+
LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
70
73
|
SQL
|
71
74
|
end
|
72
75
|
|
73
76
|
# get synonyms for schema dump
|
74
77
|
def synonyms
|
75
78
|
result = select_all(<<~SQL.squish, "SCHEMA")
|
76
|
-
SELECT synonym_name, table_owner, table_name
|
79
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ synonym_name, table_owner, table_name
|
77
80
|
FROM all_synonyms where owner = SYS_CONTEXT('userenv', 'current_schema')
|
78
81
|
SQL
|
79
82
|
|
@@ -88,7 +91,7 @@ module ActiveRecord
|
|
88
91
|
default_tablespace_name = default_tablespace
|
89
92
|
|
90
93
|
result = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
91
|
-
SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
|
94
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
|
92
95
|
i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
|
93
96
|
LOWER(i.tablespace_name) AS tablespace_name,
|
94
97
|
LOWER(c.column_name) AS column_name, e.column_expression,
|
@@ -118,7 +121,7 @@ module ActiveRecord
|
|
118
121
|
if row["index_type"] == "DOMAIN" && row["ityp_owner"] == "CTXSYS" && row["ityp_name"] == "CONTEXT"
|
119
122
|
procedure_name = default_datastore_procedure(row["index_name"])
|
120
123
|
source = select_values(<<~SQL.squish, "SCHEMA", [bind_string("procedure_name", procedure_name.upcase)]).join
|
121
|
-
SELECT text
|
124
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
|
122
125
|
FROM all_source
|
123
126
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
124
127
|
AND name = :procedure_name
|
@@ -365,7 +368,7 @@ module ActiveRecord
|
|
365
368
|
def index_name_exists?(table_name, index_name)
|
366
369
|
(_owner, table_name) = @connection.describe(table_name)
|
367
370
|
result = select_value(<<~SQL.squish, "SCHEMA")
|
368
|
-
SELECT 1 FROM all_indexes i
|
371
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 1 FROM all_indexes i
|
369
372
|
WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
|
370
373
|
AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
|
371
374
|
AND i.table_name = '#{table_name}'
|
@@ -500,7 +503,7 @@ module ActiveRecord
|
|
500
503
|
# TODO
|
501
504
|
(_owner, table_name) = @connection.describe(table_name)
|
502
505
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
503
|
-
SELECT comments FROM all_tab_comments
|
506
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_tab_comments
|
504
507
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
505
508
|
AND table_name = :table_name
|
506
509
|
SQL
|
@@ -516,7 +519,7 @@ module ActiveRecord
|
|
516
519
|
# TODO: it does not exist in Abstract adapter
|
517
520
|
(_owner, table_name) = @connection.describe(table_name)
|
518
521
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
|
519
|
-
SELECT comments FROM all_col_comments
|
522
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_col_comments
|
520
523
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
521
524
|
AND table_name = :table_name
|
522
525
|
AND column_name = :column_name
|
@@ -533,7 +536,7 @@ module ActiveRecord
|
|
533
536
|
|
534
537
|
def tablespace(table_name)
|
535
538
|
select_value(<<~SQL.squish, "SCHEMA")
|
536
|
-
SELECT tablespace_name
|
539
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ tablespace_name
|
537
540
|
FROM all_tables
|
538
541
|
WHERE table_name='#{table_name.to_s.upcase}'
|
539
542
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -545,7 +548,7 @@ module ActiveRecord
|
|
545
548
|
(_owner, desc_table_name) = @connection.describe(table_name)
|
546
549
|
|
547
550
|
fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
|
548
|
-
SELECT r.table_name to_table
|
551
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ r.table_name to_table
|
549
552
|
,rc.column_name references_column
|
550
553
|
,cc.column_name
|
551
554
|
,c.constraint_name name
|
@@ -587,7 +590,7 @@ module ActiveRecord
|
|
587
590
|
|
588
591
|
def disable_referential_integrity(&block) #:nodoc:
|
589
592
|
old_constraints = select_all(<<~SQL.squish, "SCHEMA")
|
590
|
-
SELECT constraint_name, owner, table_name
|
593
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ constraint_name, owner, table_name
|
591
594
|
FROM all_constraints
|
592
595
|
WHERE constraint_type = 'R'
|
593
596
|
AND status = 'ENABLED'
|
@@ -702,7 +705,7 @@ module ActiveRecord
|
|
702
705
|
return unless tablespace
|
703
706
|
|
704
707
|
index_name = select_value(<<~SQL.squish, "Index name for primary key", [bind_string("table_name", table_name.upcase)])
|
705
|
-
SELECT index_name FROM all_constraints
|
708
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ index_name FROM all_constraints
|
706
709
|
WHERE table_name = :table_name
|
707
710
|
AND constraint_type = 'P'
|
708
711
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -9,7 +9,8 @@ module ActiveRecord #:nodoc:
|
|
9
9
|
|
10
10
|
def structure_dump #:nodoc:
|
11
11
|
sequences = select(<<~SQL.squish, "SCHEMA")
|
12
|
-
SELECT
|
12
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
13
|
+
sequence_name, min_value, max_value, increment_by, order_flag, cycle_flag
|
13
14
|
FROM all_sequences
|
14
15
|
where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
15
16
|
SQL
|
@@ -18,7 +19,7 @@ module ActiveRecord #:nodoc:
|
|
18
19
|
"CREATE SEQUENCE #{quote_table_name(result["sequence_name"])} MINVALUE #{result["min_value"]} MAXVALUE #{result["max_value"]} INCREMENT BY #{result["increment_by"]} #{result["order_flag"] == 'Y' ? "ORDER" : "NOORDER"} #{result["cycle_flag"] == 'Y' ? "CYCLE" : "NOCYCLE"}"
|
19
20
|
end
|
20
21
|
tables = select_values(<<~SQL.squish, "SCHEMA")
|
21
|
-
SELECT table_name FROM all_tables t
|
22
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables t
|
22
23
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
23
24
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
24
25
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -30,7 +31,7 @@ module ActiveRecord #:nodoc:
|
|
30
31
|
virtual_columns = virtual_columns_for(table_name) if supports_virtual_columns?
|
31
32
|
ddl = +"CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
|
32
33
|
columns = select_all(<<~SQL.squish, "SCHEMA")
|
33
|
-
SELECT column_name, data_type, data_length, char_used, char_length,
|
34
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_type, data_length, char_used, char_length,
|
34
35
|
data_precision, data_scale, data_default, nullable
|
35
36
|
FROM all_tab_columns
|
36
37
|
WHERE table_name = '#{table_name}'
|
@@ -90,7 +91,7 @@ module ActiveRecord #:nodoc:
|
|
90
91
|
def structure_dump_primary_key(table) #:nodoc:
|
91
92
|
opts = { name: "", cols: [] }
|
92
93
|
pks = select_all(<<~SQL.squish, "SCHEMA")
|
93
|
-
SELECT a.constraint_name, a.column_name, a.position
|
94
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
|
94
95
|
FROM all_cons_columns a
|
95
96
|
JOIN all_constraints c
|
96
97
|
ON a.constraint_name = c.constraint_name
|
@@ -109,7 +110,7 @@ module ActiveRecord #:nodoc:
|
|
109
110
|
def structure_dump_unique_keys(table) #:nodoc:
|
110
111
|
keys = {}
|
111
112
|
uks = select_all(<<~SQL.squish, "SCHEMA")
|
112
|
-
SELECT a.constraint_name, a.column_name, a.position
|
113
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
|
113
114
|
FROM all_cons_columns a
|
114
115
|
JOIN all_constraints c
|
115
116
|
ON a.constraint_name = c.constraint_name
|
@@ -145,7 +146,7 @@ module ActiveRecord #:nodoc:
|
|
145
146
|
|
146
147
|
def structure_dump_fk_constraints #:nodoc:
|
147
148
|
foreign_keys = select_all(<<~SQL.squish, "SCHEMA")
|
148
|
-
SELECT table_name FROM all_tables
|
149
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
|
149
150
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
150
151
|
SQL
|
151
152
|
fks = foreign_keys.map do |table|
|
@@ -173,7 +174,7 @@ module ActiveRecord #:nodoc:
|
|
173
174
|
def structure_dump_column_comments(table_name)
|
174
175
|
comments = []
|
175
176
|
columns = select_values(<<~SQL.squish, "SCHEMA")
|
176
|
-
SELECT column_name FROM user_tab_columns
|
177
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name FROM user_tab_columns
|
177
178
|
WHERE table_name = '#{table_name}' ORDER BY column_id
|
178
179
|
SQL
|
179
180
|
|
@@ -207,7 +208,7 @@ module ActiveRecord #:nodoc:
|
|
207
208
|
def structure_dump_db_stored_code #:nodoc:
|
208
209
|
structure = []
|
209
210
|
all_source = select_all(<<~SQL.squish, "SCHEMA")
|
210
|
-
SELECT DISTINCT name, type
|
211
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ DISTINCT name, type
|
211
212
|
FROM all_source
|
212
213
|
WHERE type IN ('PROCEDURE', 'PACKAGE', 'PACKAGE BODY', 'FUNCTION', 'TRIGGER', 'TYPE')
|
213
214
|
AND name NOT LIKE 'BIN$%'
|
@@ -216,7 +217,7 @@ module ActiveRecord #:nodoc:
|
|
216
217
|
all_source.each do |source|
|
217
218
|
ddl = +"CREATE OR REPLACE \n"
|
218
219
|
texts = select_all(<<~SQL.squish, "all source at structure dump")
|
219
|
-
SELECT text
|
220
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
|
220
221
|
FROM all_source
|
221
222
|
WHERE name = '#{source['name']}'
|
222
223
|
AND type = '#{source['type']}'
|
@@ -239,7 +240,7 @@ module ActiveRecord #:nodoc:
|
|
239
240
|
def structure_dump_views #:nodoc:
|
240
241
|
structure = []
|
241
242
|
views = select_all(<<~SQL.squish, "SCHEMA")
|
242
|
-
SELECT view_name, text FROM all_views
|
243
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ view_name, text FROM all_views
|
243
244
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY view_name ASC
|
244
245
|
SQL
|
245
246
|
views.each do |view|
|
@@ -251,7 +252,7 @@ module ActiveRecord #:nodoc:
|
|
251
252
|
def structure_dump_synonyms #:nodoc:
|
252
253
|
structure = []
|
253
254
|
synonyms = select_all(<<~SQL.squish, "SCHEMA")
|
254
|
-
SELECT owner, synonym_name, table_name, table_owner
|
255
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, synonym_name, table_name, table_owner
|
255
256
|
FROM all_synonyms
|
256
257
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
257
258
|
SQL
|
@@ -264,13 +265,14 @@ module ActiveRecord #:nodoc:
|
|
264
265
|
|
265
266
|
def structure_drop #:nodoc:
|
266
267
|
sequences = select_values(<<~SQL.squish, "SCHEMA")
|
267
|
-
SELECT
|
268
|
+
SELECT/*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
269
|
+
sequence_name FROM all_sequences where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
268
270
|
SQL
|
269
271
|
statements = sequences.map do |seq|
|
270
272
|
"DROP SEQUENCE \"#{seq}\""
|
271
273
|
end
|
272
274
|
tables = select_values(<<~SQL.squish, "SCHEMA")
|
273
|
-
SELECT table_name from all_tables t
|
275
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name from all_tables t
|
274
276
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
275
277
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
276
278
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -286,7 +288,7 @@ module ActiveRecord #:nodoc:
|
|
286
288
|
|
287
289
|
def temp_table_drop #:nodoc:
|
288
290
|
temporary_tables = select_values(<<~SQL.squish, "SCHEMA")
|
289
|
-
SELECT table_name FROM all_tables
|
291
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
|
290
292
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
291
293
|
AND secondary = 'N' AND temporary = 'Y' ORDER BY 1
|
292
294
|
SQL
|
@@ -320,7 +322,7 @@ module ActiveRecord #:nodoc:
|
|
320
322
|
# return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
|
321
323
|
def virtual_columns_for(table)
|
322
324
|
select_all(<<~SQL.squish, "SCHEMA")
|
323
|
-
SELECT column_name, data_default
|
325
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_default
|
324
326
|
FROM all_tab_cols
|
325
327
|
WHERE virtual_column = 'YES'
|
326
328
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -331,7 +333,7 @@ module ActiveRecord #:nodoc:
|
|
331
333
|
def drop_sql_for_feature(type)
|
332
334
|
short_type = type == "materialized view" ? "mview" : type
|
333
335
|
features = select_values(<<~SQL.squish, "SCHEMA")
|
334
|
-
SELECT #{short_type}_name FROM all_#{short_type.tableize}
|
336
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ #{short_type}_name FROM all_#{short_type.tableize}
|
335
337
|
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
336
338
|
SQL
|
337
339
|
statements = features.map do |name|
|
@@ -342,7 +344,7 @@ module ActiveRecord #:nodoc:
|
|
342
344
|
|
343
345
|
def drop_sql_for_object(type)
|
344
346
|
objects = select_values(<<~SQL.squish, "SCHEMA")
|
345
|
-
SELECT object_name FROM all_objects
|
347
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ object_name FROM all_objects
|
346
348
|
WHERE object_type = '#{type.upcase}' and owner = SYS_CONTEXT('userenv', 'current_schema')
|
347
349
|
SQL
|
348
350
|
statements = objects.map do |name|
|
@@ -553,7 +553,7 @@ module ActiveRecord
|
|
553
553
|
# Default tablespace name of current user
|
554
554
|
def default_tablespace
|
555
555
|
select_value(<<~SQL.squish, "SCHEMA")
|
556
|
-
SELECT LOWER(default_tablespace) FROM user_users
|
556
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ LOWER(default_tablespace) FROM user_users
|
557
557
|
WHERE username = SYS_CONTEXT('userenv', 'current_schema')
|
558
558
|
SQL
|
559
559
|
end
|
@@ -562,7 +562,7 @@ module ActiveRecord
|
|
562
562
|
(owner, desc_table_name) = @connection.describe(table_name)
|
563
563
|
|
564
564
|
select_all(<<~SQL.squish, "SCHEMA")
|
565
|
-
SELECT cols.column_name AS name, cols.data_type AS sql_type,
|
565
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cols.column_name AS name, cols.data_type AS sql_type,
|
566
566
|
cols.data_default, cols.nullable, cols.virtual_column, cols.hidden_column,
|
567
567
|
cols.data_type_owner AS sql_type_owner,
|
568
568
|
DECODE(cols.data_type, 'NUMBER', data_precision,
|
@@ -594,7 +594,7 @@ module ActiveRecord
|
|
594
594
|
(owner, desc_table_name) = @connection.describe(table_name)
|
595
595
|
|
596
596
|
seqs = select_values(<<~SQL.squish, "SCHEMA")
|
597
|
-
select us.sequence_name
|
597
|
+
select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ us.sequence_name
|
598
598
|
from all_sequences us
|
599
599
|
where us.sequence_owner = '#{owner}'
|
600
600
|
and us.sequence_name = upper(#{quote(default_sequence_name(desc_table_name))})
|
@@ -602,7 +602,7 @@ module ActiveRecord
|
|
602
602
|
|
603
603
|
# changed back from user_constraints to all_constraints for consistency
|
604
604
|
pks = select_values(<<~SQL.squish, "SCHEMA")
|
605
|
-
SELECT cc.column_name
|
605
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cc.column_name
|
606
606
|
FROM all_constraints c, all_cons_columns cc
|
607
607
|
WHERE c.owner = '#{owner}'
|
608
608
|
AND c.table_name = #{quote(desc_table_name)}
|
@@ -636,7 +636,7 @@ module ActiveRecord
|
|
636
636
|
(_owner, desc_table_name) = @connection.describe(table_name)
|
637
637
|
|
638
638
|
pks = select_values(<<~SQL.squish, "SCHEMA", [bind_string("table_name", desc_table_name)])
|
639
|
-
SELECT cc.column_name
|
639
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cc.column_name
|
640
640
|
FROM all_constraints c, all_cons_columns cc
|
641
641
|
WHERE c.owner = SYS_CONTEXT('userenv', 'current_schema')
|
642
642
|
AND c.table_name = :table_name
|
@@ -666,7 +666,8 @@ module ActiveRecord
|
|
666
666
|
|
667
667
|
def temporary_table?(table_name) #:nodoc:
|
668
668
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase)]) == "Y"
|
669
|
-
SELECT
|
669
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
670
|
+
temporary FROM all_tables WHERE table_name = :table_name and owner = SYS_CONTEXT('userenv', 'current_schema')
|
670
671
|
SQL
|
671
672
|
end
|
672
673
|
|
data/lib/arel/visitors/oracle.rb
CHANGED
@@ -95,9 +95,9 @@ module Arel # :nodoc: all
|
|
95
95
|
column_name = quote_table_name(o.table_name) + "." + quote_column_name(o.column_name)
|
96
96
|
operator =
|
97
97
|
if o.type == :in
|
98
|
-
"IN ("
|
98
|
+
" IN ("
|
99
99
|
else
|
100
|
-
"NOT IN ("
|
100
|
+
" NOT IN ("
|
101
101
|
end
|
102
102
|
|
103
103
|
if !Array === values || values.length <= in_clause_length
|
@@ -114,9 +114,15 @@ module Arel # :nodoc: all
|
|
114
114
|
collector << expr
|
115
115
|
collector << ")"
|
116
116
|
else
|
117
|
+
separator =
|
118
|
+
if o.type == :in
|
119
|
+
" OR "
|
120
|
+
else
|
121
|
+
" AND "
|
122
|
+
end
|
117
123
|
collector << "("
|
118
124
|
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
119
|
-
collector <<
|
125
|
+
collector << separator unless i == 0
|
120
126
|
collector << column_name
|
121
127
|
collector << operator
|
122
128
|
collector << valuez.join(",")
|
@@ -128,59 +134,6 @@ module Arel # :nodoc: all
|
|
128
134
|
collector
|
129
135
|
end
|
130
136
|
|
131
|
-
def visit_Arel_Nodes_In(o, collector)
|
132
|
-
attr, values = o.left, o.right
|
133
|
-
|
134
|
-
if Array === values
|
135
|
-
unless values.empty?
|
136
|
-
values.delete_if { |value| unboundable?(value) }
|
137
|
-
end
|
138
|
-
|
139
|
-
return collector << "1=0" if values.empty?
|
140
|
-
end
|
141
|
-
|
142
|
-
in_clause_length = @connection.in_clause_length
|
143
|
-
|
144
|
-
if !Array === values || values.length <= in_clause_length
|
145
|
-
visit(attr, collector) << " IN ("
|
146
|
-
visit(values, collector) << ")"
|
147
|
-
else
|
148
|
-
collector << "("
|
149
|
-
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
150
|
-
collector << " OR " unless i == 0
|
151
|
-
visit(attr, collector) << " IN ("
|
152
|
-
visit(valuez, collector) << ")"
|
153
|
-
end
|
154
|
-
collector << ")"
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def visit_Arel_Nodes_NotIn(o, collector)
|
159
|
-
attr, values = o.left, o.right
|
160
|
-
|
161
|
-
if Array === values
|
162
|
-
unless values.empty?
|
163
|
-
values.delete_if { |value| unboundable?(value) }
|
164
|
-
end
|
165
|
-
|
166
|
-
return collector << "1=1" if values.empty?
|
167
|
-
end
|
168
|
-
|
169
|
-
in_clause_length = @connection.in_clause_length
|
170
|
-
|
171
|
-
if !Array === values || values.length <= in_clause_length
|
172
|
-
visit(attr, collector) << " NOT IN ("
|
173
|
-
visit(values, collector) << ")"
|
174
|
-
else
|
175
|
-
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
176
|
-
collector << " AND " unless i == 0
|
177
|
-
visit(attr, collector) << " NOT IN ("
|
178
|
-
visit(valuez, collector) << ")"
|
179
|
-
end
|
180
|
-
collector
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
137
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
185
138
|
# Oracle does not allow ORDER BY/LIMIT in UPDATEs.
|
186
139
|
if o.orders.any? && o.limit.nil?
|
@@ -248,6 +201,17 @@ module Arel # :nodoc: all
|
|
248
201
|
collector = visit [o.left, o.right, 0, 1], collector
|
249
202
|
collector << ")"
|
250
203
|
end
|
204
|
+
|
205
|
+
# Oracle will occur an error `ORA-00907: missing right parenthesis`
|
206
|
+
# when using `ORDER BY` in `UPDATE` or `DELETE`'s subquery.
|
207
|
+
#
|
208
|
+
# This method has been overridden based on the following code.
|
209
|
+
# https://github.com/rails/rails/blob/v6.1.0.rc1/activerecord/lib/arel/visitors/to_sql.rb#L815-L825
|
210
|
+
def build_subselect(key, o)
|
211
|
+
stmt = super
|
212
|
+
stmt.orders = [] # `orders` will never be set to prevent `ORA-00907`.
|
213
|
+
stmt
|
214
|
+
end
|
251
215
|
end
|
252
216
|
end
|
253
217
|
end
|
@@ -48,9 +48,9 @@ module Arel # :nodoc: all
|
|
48
48
|
column_name = quote_table_name(o.table_name) + "." + quote_column_name(o.column_name)
|
49
49
|
operator =
|
50
50
|
if o.type == :in
|
51
|
-
"IN ("
|
51
|
+
" IN ("
|
52
52
|
else
|
53
|
-
"NOT IN ("
|
53
|
+
" NOT IN ("
|
54
54
|
end
|
55
55
|
|
56
56
|
if !Array === values || values.length <= in_clause_length
|
@@ -67,9 +67,15 @@ module Arel # :nodoc: all
|
|
67
67
|
collector << expr
|
68
68
|
collector << ")"
|
69
69
|
else
|
70
|
+
separator =
|
71
|
+
if o.type == :in
|
72
|
+
" OR "
|
73
|
+
else
|
74
|
+
" AND "
|
75
|
+
end
|
70
76
|
collector << "("
|
71
77
|
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
72
|
-
collector <<
|
78
|
+
collector << separator unless i == 0
|
73
79
|
collector << column_name
|
74
80
|
collector << operator
|
75
81
|
collector << valuez.join(",")
|
@@ -81,59 +87,6 @@ module Arel # :nodoc: all
|
|
81
87
|
collector
|
82
88
|
end
|
83
89
|
|
84
|
-
def visit_Arel_Nodes_In(o, collector)
|
85
|
-
attr, values = o.left, o.right
|
86
|
-
|
87
|
-
if Array === values
|
88
|
-
unless values.empty?
|
89
|
-
values.delete_if { |value| unboundable?(value) }
|
90
|
-
end
|
91
|
-
|
92
|
-
return collector << "1=0" if values.empty?
|
93
|
-
end
|
94
|
-
|
95
|
-
in_clause_length = @connection.in_clause_length
|
96
|
-
|
97
|
-
if !Array === values || values.length <= in_clause_length
|
98
|
-
visit(attr, collector) << " IN ("
|
99
|
-
visit(values, collector) << ")"
|
100
|
-
else
|
101
|
-
collector << "("
|
102
|
-
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
103
|
-
collector << " OR " unless i == 0
|
104
|
-
visit(attr, collector) << " IN ("
|
105
|
-
visit(valuez, collector) << ")"
|
106
|
-
end
|
107
|
-
collector << ")"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def visit_Arel_Nodes_NotIn(o, collector)
|
112
|
-
attr, values = o.left, o.right
|
113
|
-
|
114
|
-
if Array === values
|
115
|
-
unless values.empty?
|
116
|
-
values.delete_if { |value| unboundable?(value) }
|
117
|
-
end
|
118
|
-
|
119
|
-
return collector << "1=1" if values.empty?
|
120
|
-
end
|
121
|
-
|
122
|
-
in_clause_length = @connection.in_clause_length
|
123
|
-
|
124
|
-
if !Array === values || values.length <= in_clause_length
|
125
|
-
visit(attr, collector) << " NOT IN ("
|
126
|
-
visit(values, collector) << ")"
|
127
|
-
else
|
128
|
-
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
129
|
-
collector << " AND " unless i == 0
|
130
|
-
visit(attr, collector) << " NOT IN ("
|
131
|
-
visit(valuez, collector) << ")"
|
132
|
-
end
|
133
|
-
collector
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
90
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
138
91
|
# Oracle does not allow ORDER BY/LIMIT in UPDATEs.
|
139
92
|
if o.orders.any? && o.limit.nil?
|
@@ -155,6 +108,17 @@ module Arel # :nodoc: all
|
|
155
108
|
collector = visit [o.left, o.right, 0, 1], collector
|
156
109
|
collector << ")"
|
157
110
|
end
|
111
|
+
|
112
|
+
# Oracle will occur an error `ORA-00907: missing right parenthesis`
|
113
|
+
# when using `ORDER BY` in `UPDATE` or `DELETE`'s subquery.
|
114
|
+
#
|
115
|
+
# This method has been overridden based on the following code.
|
116
|
+
# https://github.com/rails/rails/blob/v6.1.0.rc1/activerecord/lib/arel/visitors/to_sql.rb#L815-L825
|
117
|
+
def build_subselect(key, o)
|
118
|
+
stmt = super
|
119
|
+
stmt.orders = [] # `orders` will never be set to prevent `ORA-00907`.
|
120
|
+
stmt
|
121
|
+
end
|
158
122
|
end
|
159
123
|
end
|
160
124
|
end
|
@@ -150,6 +150,45 @@ describe "OracleEnhancedAdapter" do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
describe "`has_many` assoc has `dependent: :delete_all` with `order`" do
|
154
|
+
before(:all) do
|
155
|
+
schema_define do
|
156
|
+
create_table :test_posts do |t|
|
157
|
+
t.string :title
|
158
|
+
end
|
159
|
+
create_table :test_comments do |t|
|
160
|
+
t.integer :test_post_id
|
161
|
+
t.string :description
|
162
|
+
end
|
163
|
+
add_index :test_comments, :test_post_id
|
164
|
+
end
|
165
|
+
class ::TestPost < ActiveRecord::Base
|
166
|
+
has_many :test_comments, -> { order(:id) }, dependent: :delete_all
|
167
|
+
end
|
168
|
+
class ::TestComment < ActiveRecord::Base
|
169
|
+
belongs_to :test_post
|
170
|
+
end
|
171
|
+
TestPost.transaction do
|
172
|
+
post = TestPost.create!(title: "Title")
|
173
|
+
TestComment.create!(test_post_id: post.id, description: "Description")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
after(:all) do
|
178
|
+
schema_define do
|
179
|
+
drop_table :test_comments
|
180
|
+
drop_table :test_posts
|
181
|
+
end
|
182
|
+
Object.send(:remove_const, "TestPost")
|
183
|
+
Object.send(:remove_const, "TestComment")
|
184
|
+
ActiveRecord::Base.clear_cache!
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should not occur `ActiveRecord::StatementInvalid: OCIError: ORA-00907: missing right parenthesis`" do
|
188
|
+
expect { TestPost.first.destroy }.not_to raise_error
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
153
192
|
describe "eager loading" do
|
154
193
|
before(:all) do
|
155
194
|
schema_define do
|
@@ -668,4 +707,39 @@ describe "OracleEnhancedAdapter" do
|
|
668
707
|
expect(post.explain).to include("| TABLE ACCESS FULL| TEST_POSTS |")
|
669
708
|
end
|
670
709
|
end
|
710
|
+
|
711
|
+
describe "homogeneous in" do
|
712
|
+
before(:all) do
|
713
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
714
|
+
@conn = ActiveRecord::Base.connection
|
715
|
+
schema_define do
|
716
|
+
create_table :test_posts, force: true
|
717
|
+
create_table :test_comments, force: true do |t|
|
718
|
+
t.integer :test_post_id
|
719
|
+
end
|
720
|
+
end
|
721
|
+
class ::TestPost < ActiveRecord::Base
|
722
|
+
has_many :test_comments
|
723
|
+
end
|
724
|
+
class ::TestComment < ActiveRecord::Base
|
725
|
+
belongs_to :test_post
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
after(:all) do
|
730
|
+
schema_define do
|
731
|
+
drop_table :test_posts, if_exists: true
|
732
|
+
drop_table :test_comments, if_exists: true
|
733
|
+
end
|
734
|
+
Object.send(:remove_const, "TestPost")
|
735
|
+
Object.send(:remove_const, "TestComment")
|
736
|
+
ActiveRecord::Base.clear_cache!
|
737
|
+
end
|
738
|
+
|
739
|
+
it "should not raise undefined method length" do
|
740
|
+
post = TestPost.create!
|
741
|
+
post.test_comments << TestComment.create!
|
742
|
+
expect(TestComment.where(test_post_id: TestPost.select(:id)).size).to eq(1)
|
743
|
+
end
|
744
|
+
end
|
671
745
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-oracle_enhanced-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1.0
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Raimonds Simanovskis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.1.0
|
19
|
+
version: 6.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.1.0
|
26
|
+
version: 6.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-plsql
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,7 +118,6 @@ files:
|
|
118
118
|
- spec/support/alter_system_set_open_cursors.sql
|
119
119
|
- spec/support/alter_system_user_password.sql
|
120
120
|
- spec/support/create_oracle_enhanced_users.sql
|
121
|
-
- spec/support/stats.sql
|
122
121
|
homepage: http://github.com/rsim/oracle-enhanced
|
123
122
|
licenses:
|
124
123
|
- MIT
|
@@ -168,7 +167,6 @@ test_files:
|
|
168
167
|
- spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb
|
169
168
|
- spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb
|
170
169
|
- spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
|
171
|
-
- spec/support/stats.sql
|
172
170
|
- spec/support/create_oracle_enhanced_users.sql
|
173
171
|
- spec/support/alter_system_user_password.sql
|
174
172
|
- spec/support/alter_system_set_open_cursors.sql
|
data/spec/support/stats.sql
DELETED