Skip to content

Commit 400391e

Browse files
authored
Merge pull request rsim#2727 from yahonda/add-supports-expression-index
Override supports_expression_index? to true
2 parents 890d17f + 51b37bf commit 400391e

4 files changed

Lines changed: 81 additions & 0 deletions

File tree

lib/active_record/connection_adapters/oracle_enhanced_adapter.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ def supports_validate_constraints?
511511
true
512512
end
513513

514+
def supports_expression_index?
515+
true
516+
end
517+
514518
def supports_optimizer_hints?
515519
true
516520
end

spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,48 @@ def drop_test_posts_table
106106
end
107107
end
108108

109+
describe "expression index" do
110+
before(:each) do
111+
schema_define do
112+
create_table :test_idx_expr_dump, force: true do |t|
113+
t.string :name
114+
end
115+
end
116+
end
117+
118+
after(:each) do
119+
schema_define do
120+
drop_table :test_idx_expr_dump, if_exists: true
121+
end
122+
end
123+
124+
it "dumps a function-based index with the expression preserved" do
125+
schema_define do
126+
add_index :test_idx_expr_dump, "LOWER(name)", name: "ix_dump_expr"
127+
end
128+
output = dump_table_schema "test_idx_expr_dump"
129+
expect(output).to match(/t\.index \[.*LOWER\(.*NAME.*\).*\], name: "ix_dump_expr"/im)
130+
end
131+
132+
it "round-trips an expression index through dump and load" do
133+
schema_define do
134+
add_index :test_idx_expr_dump, "LOWER(name)", name: "ix_rt_expr"
135+
end
136+
dumped = dump_table_schema "test_idx_expr_dump"
137+
schema_define do
138+
drop_table :test_idx_expr_dump, if_exists: true
139+
end
140+
body = dumped[/ActiveRecord::Schema\[.+?\]\.define\(version: \d+\) do\n(.+)\nend\s*\z/m, 1]
141+
schema_define { instance_eval(body) }
142+
expr = ActiveRecord::Base.lease_connection.select_value(<<~SQL.squish)
143+
SELECT column_expression FROM all_ind_expressions
144+
WHERE index_owner = SYS_CONTEXT('userenv', 'current_schema')
145+
AND index_name = 'IX_RT_EXPR'
146+
SQL
147+
expect(expr).to match(/LOWER\("?NAME"?\)/i)
148+
end
149+
end
150+
109151
describe "foreign key constraints" do
110152
# Recreate the canonical tables before each example. One example
111153
# (`should include primary_key when reference column name is not 'id'`)

spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,33 @@ class ::TestEmployee < ActiveRecord::Base; end
559559
end
560560
end
561561

562+
it "supports expression indexes (function-based) via add_index" do
563+
schema_define do
564+
create_table :test_idx_expr, force: true do |t|
565+
t.string :name
566+
end
567+
add_index :test_idx_expr, "LOWER(name)", name: "ix_expr_lower_name"
568+
end
569+
idx_count = @conn.select_value(<<~SQL.squish)
570+
SELECT COUNT(*) FROM all_indexes
571+
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
572+
AND index_name = 'IX_EXPR_LOWER_NAME'
573+
SQL
574+
expect(idx_count).to eq(1)
575+
expr = @conn.select_value(<<~SQL.squish)
576+
SELECT column_expression FROM all_ind_expressions
577+
WHERE index_owner = SYS_CONTEXT('userenv', 'current_schema')
578+
AND index_name = 'IX_EXPR_LOWER_NAME'
579+
SQL
580+
expect(expr).to match(/LOWER\("?NAME"?\)/i)
581+
ensure
582+
schema_define { drop_table :test_idx_expr, if_exists: true }
583+
end
584+
585+
it "reports supports_expression_index? as true" do
586+
expect(@conn.supports_expression_index?).to be(true)
587+
end
588+
562589
it "measures default index name length in bytes, not characters" do
563590
max = @conn.index_name_length
564591
# "index_t_on_<col>" fits in `max` characters but overflows in bytes

spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ class ::TestPost < ActiveRecord::Base
105105
expect(dump).to eq("")
106106
end
107107

108+
it "dumps a function-based index expression in structure_dump_indexes" do
109+
schema_define do
110+
add_index :test_posts, "LOWER(title)", name: "ix_struct_expr"
111+
end
112+
dump = @conn.structure_dump_indexes("test_posts").join("\n")
113+
expect(dump).to match(/CREATE INDEX "?IX_STRUCT_EXPR"? ON "?TEST_POSTS"? \(LOWER\("?TITLE"?\)\)/i)
114+
end
115+
108116
it "appends NOVALIDATE for foreign keys added with validate: false" do
109117
schema_define do
110118
add_column :test_posts, :foo_uniq, :integer

0 commit comments

Comments
 (0)