Skip to content

Commit 8a24d9e

Browse files
b-nikaidanharan
authored andcommitted
Maintain index options during change_column operations (#1345)
1 parent 4d7a29e commit 8a24d9e

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
- [#1342](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1342) Support more Azure services by changing language source.
66

7+
#### Fixed
8+
- [#1346](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1346) Maintain index options during `change_column` operations.
9+
710
## v8.0.7
811

912
#### Fixed

lib/active_record/connection_adapters/sqlserver/schema_statements.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,14 @@ def change_column(table_name, column_name, type, options = {})
182182
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{default} FOR #{quote_column_name(column_name)}"
183183
end
184184

185+
sql_commands.each { |c| execute(c) }
186+
185187
# Add any removed indexes back
186188
indexes.each do |index|
187-
sql_commands << "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index.columns.map { |c| quote_column_name(c) }.join(', ')})"
189+
create_index_def = CreateIndexDefinition.new(index)
190+
execute schema_creation.accept(create_index_def)
188191
end
189192

190-
sql_commands.each { |c| execute(c) }
191193
clear_cache!
192194
end
193195

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# frozen_string_literal: true
2+
3+
require "cases/helper_sqlserver"
4+
5+
class ChangeColumnIndexTestSqlServer < ActiveRecord::TestCase
6+
class CreateClientsWithUniqueIndex < ActiveRecord::Migration[8.0]
7+
def up
8+
create_table :clients do |t|
9+
t.string :name, limit: 15
10+
end
11+
add_index :clients, :name, unique: true
12+
end
13+
14+
def down
15+
drop_table :clients
16+
end
17+
end
18+
19+
class CreateBlogPostsWithMultipleIndexesOnTheSameColumn < ActiveRecord::Migration[8.0]
20+
def up
21+
create_table :blog_posts do |t|
22+
t.string :title, limit: 15
23+
t.string :subtitle
24+
end
25+
add_index :blog_posts, :title, unique: true, where: "([blog_posts].[title] IS NOT NULL)", name: "custom_index_name"
26+
add_index :blog_posts, [:title, :subtitle], unique: true
27+
end
28+
29+
def down
30+
drop_table :blog_posts
31+
end
32+
end
33+
34+
class ChangeClientsNameLength < ActiveRecord::Migration[8.0]
35+
def up
36+
change_column :clients, :name, :string, limit: 30
37+
end
38+
end
39+
40+
class ChangeBlogPostsTitleLength < ActiveRecord::Migration[8.0]
41+
def up
42+
change_column :blog_posts, :title, :string, limit: 30
43+
end
44+
end
45+
46+
before do
47+
@old_verbose = ActiveRecord::Migration.verbose
48+
ActiveRecord::Migration.verbose = false
49+
50+
CreateClientsWithUniqueIndex.new.up
51+
CreateBlogPostsWithMultipleIndexesOnTheSameColumn.new.up
52+
end
53+
54+
after do
55+
CreateClientsWithUniqueIndex.new.down
56+
CreateBlogPostsWithMultipleIndexesOnTheSameColumn.new.down
57+
58+
ActiveRecord::Migration.verbose = @old_verbose
59+
end
60+
61+
def test_index_uniqueness_is_maintained_after_column_change
62+
indexes = ActiveRecord::Base.connection.indexes("clients")
63+
columns = ActiveRecord::Base.connection.columns("clients")
64+
assert_equal columns.find { |column| column.name == "name" }.limit, 15
65+
assert_equal indexes.size, 1
66+
assert_equal indexes.first.name, "index_clients_on_name"
67+
assert indexes.first.unique
68+
69+
ChangeClientsNameLength.new.up
70+
71+
indexes = ActiveRecord::Base.connection.indexes("clients")
72+
columns = ActiveRecord::Base.connection.columns("clients")
73+
assert_equal columns.find { |column| column.name == "name" }.limit, 30
74+
assert_equal indexes.size, 1
75+
assert_equal indexes.first.name, "index_clients_on_name"
76+
assert indexes.first.unique
77+
end
78+
79+
def test_multiple_index_options_are_maintained_after_column_change
80+
indexes = ActiveRecord::Base.connection.indexes("blog_posts")
81+
columns = ActiveRecord::Base.connection.columns("blog_posts")
82+
assert_equal columns.find { |column| column.name == "title" }.limit, 15
83+
assert_equal indexes.size, 2
84+
85+
index_1 = indexes.find { |index| index.columns == ["title"] }
86+
assert_equal index_1.name, "custom_index_name"
87+
assert_equal index_1.where, "([blog_posts].[title] IS NOT NULL)"
88+
assert index_1.unique
89+
90+
index_2 = indexes.find { |index| index.columns == ["title", "subtitle"] }
91+
assert index_2.unique
92+
93+
ChangeBlogPostsTitleLength.new.up
94+
95+
indexes = ActiveRecord::Base.connection.indexes("blog_posts")
96+
columns = ActiveRecord::Base.connection.columns("blog_posts")
97+
assert_equal columns.find { |column| column.name == "title" }.limit, 30
98+
assert_equal indexes.size, 2
99+
100+
index_1 = indexes.find { |index| index.columns == ["title"] }
101+
assert_equal index_1.name, "custom_index_name"
102+
assert_equal index_1.where, "([blog_posts].[title] IS NOT NULL)"
103+
assert index_1.unique
104+
105+
index_2 = indexes.find { |index| index.columns == ["title", "subtitle"] }
106+
assert index_2.unique
107+
end
108+
end

0 commit comments

Comments
 (0)