Skip to content

Commit b53d06b

Browse files
committed
Use SQL literals for column_definitions and pk_and_sequence_for
since these methods called via `to_sql` method under `unprepared_statement` Fix rsim#1678 Starting from Oracle enhanced adapter 5.2.0.beta1 most of the queries for the dictionary, such as all_sequences use bind variables by rsim#1498 . It should help shared memory usage however, which eventually means Oracle enhanced adapter 5.2+ only supports `prepared_statements: true` as Rails default configuration but it does not support `prepared_statements: false`. Even if `prepared_statements: true`, `to_sql` uses `unprepared_statement` to generate SQL statement. If the connection already knows which table is associated with which model object in advance, `to_sql` works fine but when `to_sql` executed first the connection needs to know these relation then call column_definitions` and `pk_and_sequence_for` methods at least.
1 parent 6080402 commit b53d06b

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

lib/active_record/connection_adapters/oracle_enhanced_adapter.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ def default_tablespace
525525
end
526526

527527
def column_definitions(table_name)
528-
(_owner, desc_table_name) = @connection.describe(table_name)
528+
(owner, desc_table_name) = @connection.describe(table_name)
529529

530-
select_all(<<-SQL.strip.gsub(/\s+/, " "), "Column definitions", [bind_string("table_name", desc_table_name)])
530+
select_all(<<-SQL.strip.gsub(/\s+/, " "), "Column definitions")
531531
SELECT cols.column_name AS name, cols.data_type AS sql_type,
532532
cols.data_default, cols.nullable, cols.virtual_column, cols.hidden_column,
533533
cols.data_type_owner AS sql_type_owner,
@@ -540,8 +540,8 @@ def column_definitions(table_name)
540540
DECODE(data_type, 'NUMBER', data_scale, NULL) AS scale,
541541
comments.comments as column_comment
542542
FROM all_tab_cols cols, all_col_comments comments
543-
WHERE cols.owner = SYS_CONTEXT('userenv', 'current_schema')
544-
AND cols.table_name = :table_name
543+
WHERE cols.owner = '#{owner}'
544+
AND cols.table_name = #{quote(desc_table_name)}
545545
AND cols.hidden_column = 'NO'
546546
AND cols.owner = comments.owner
547547
AND cols.table_name = comments.table_name
@@ -553,21 +553,21 @@ def column_definitions(table_name)
553553
# Find a table's primary key and sequence.
554554
# *Note*: Only primary key is implemented - sequence will be nil.
555555
def pk_and_sequence_for(table_name, owner = nil, desc_table_name = nil) #:nodoc:
556-
(_owner, desc_table_name) = @connection.describe(table_name)
556+
(owner, desc_table_name) = @connection.describe(table_name)
557557

558-
seqs = select_values(<<-SQL.strip.gsub(/\s+/, " "), "Sequence", [bind_string("sequence_name", default_sequence_name(desc_table_name).upcase)])
558+
seqs = select_values(<<-SQL.strip.gsub(/\s+/, " "), "Sequence")
559559
select us.sequence_name
560560
from all_sequences us
561-
where us.sequence_owner = SYS_CONTEXT('userenv', 'current_schema')
562-
and us.sequence_name = :sequence_name
561+
where us.sequence_owner = '#{owner}'
562+
and us.sequence_name = upper(#{quote(default_sequence_name(desc_table_name))})
563563
SQL
564564

565565
# changed back from user_constraints to all_constraints for consistency
566-
pks = select_values(<<-SQL.strip.gsub(/\s+/, " "), "Primary Key", [bind_string("table_name", desc_table_name)])
566+
pks = select_values(<<-SQL.strip.gsub(/\s+/, " "), "Primary Key")
567567
SELECT cc.column_name
568568
FROM all_constraints c, all_cons_columns cc
569-
WHERE c.owner = SYS_CONTEXT('userenv', 'current_schema')
570-
AND c.table_name = :table_name
569+
WHERE c.owner = '#{owner}'
570+
AND c.table_name = #{quote(desc_table_name)}
571571
AND c.constraint_type = 'P'
572572
AND cc.owner = c.owner
573573
AND cc.constraint_name = c.constraint_name

spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,15 +480,15 @@ class ::TestPost < ActiveRecord::Base
480480
expect(@conn.table_exists?("NOT_EXISTING")).to eq false
481481
end
482482

483-
it "should return content from columns with bind usage" do
483+
it "should return content from columns without bind usage" do
484484
expect(@conn.columns("TEST_POSTS").length).to be > 0
485-
expect(@logger.logged(:debug).last).to match(/:table_name/)
486-
expect(@logger.logged(:debug).last).to match(/\["table_name", "TEST_POSTS"\]/)
485+
expect(@logger.logged(:debug).last).not_to match(/:table_name/)
486+
expect(@logger.logged(:debug).last).not_to match(/\["table_name", "TEST_POSTS"\]/)
487487
end
488488

489-
it "should return pk and sequence from pk_and_sequence_for with bind usage" do
489+
it "should return pk and sequence from pk_and_sequence_for without bind usage" do
490490
expect(@conn.pk_and_sequence_for("TEST_POSTS").length).to eq 2
491-
expect(@logger.logged(:debug).last).to match(/\["table_name", "TEST_POSTS"\]/)
491+
expect(@logger.logged(:debug).last).not_to match(/\["table_name", "TEST_POSTS"\]/)
492492
end
493493

494494
it "should return pk from primary_keys with bind usage" do

0 commit comments

Comments
 (0)