From a3cb745d6ed88505d60bc9ad49e4efa355b52cb5 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Fri, 20 Feb 2026 13:58:38 +0000 Subject: [PATCH 1/4] Fix change_column to preserve old column attributes --- .../sqlserver/schema_statements.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb index ab6313f4b..db85d21f3 100644 --- a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +++ b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb @@ -196,14 +196,16 @@ def change_column(table_name, column_name, type, options = {}) end column_object = schema_cache.columns(table_name).find { |c| c.name.to_s == column_name.to_s } - without_constraints = options.key?(:default) || options.key?(:limit) + changing_type = column_object && column_object.type != type.to_sym + no_constraint_options = options.key?(:default) || options.key?(:limit) + default = if !options.key?(:default) && column_object column_object.default else options[:default] end - if without_constraints || (column_object && column_object.type != type.to_sym) + if no_constraint_options || changing_type remove_default_constraint(table_name, column_name) indexes = indexes(table_name).select { |index| index.columns.include?(column_name.to_s) } remove_indexes(table_name, column_name) @@ -212,10 +214,14 @@ def change_column(table_name, column_name, type, options = {}) sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil? alter_command = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}" alter_command += " COLLATE #{options[:collation]}" if options[:collation].present? - alter_command += " NOT NULL" if !options[:null].nil? && options[:null] == false + if !options[:null].nil? + alter_command += " NOT NULL" if options[:null] == false + elsif column_object && !column_object.null + alter_command += " NOT NULL" + end sql_commands << alter_command - if without_constraints + if no_constraint_options || (changing_type && default.present?) default = quote_default_expression(default, column_object || column_for(table_name, column_name)) 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)}" end From 61ca23aba1a881190a4c416673edc60f4d820c25 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sun, 22 Feb 2026 18:06:37 +0000 Subject: [PATCH 2/4] Fix test --- test/cases/migration_test_sqlserver.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cases/migration_test_sqlserver.rb b/test/cases/migration_test_sqlserver.rb index b829c8632..e4d713627 100644 --- a/test/cases/migration_test_sqlserver.rb +++ b/test/cases/migration_test_sqlserver.rb @@ -34,11 +34,13 @@ class MigrationTestSQLServer < ActiveRecord::TestCase lock_version_column = Person.columns_hash["lock_version"] assert_equal :integer, lock_version_column.type assert lock_version_column.default.present? + assert_equal 0, lock_version_column.default assert_nothing_raised { connection.change_column "people", "lock_version", :string } Person.reset_column_information lock_version_column = Person.columns_hash["lock_version"] assert_equal :string, lock_version_column.type - assert lock_version_column.default.nil? + assert lock_version_column.default.present? + assert_equal "0", lock_version_column.default assert_nothing_raised { connection.change_column "people", "lock_version", :integer } Person.reset_column_information end From 6683380892cf8ef19c164d27a61fd44bc43b4875 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sun, 22 Feb 2026 18:08:29 +0000 Subject: [PATCH 3/4] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d345aff8d..743e57590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ #### Changed +- [#1381](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1381) Fix change column preserve old attributes. + #### Fixed Please check [8-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/8-1-stable/CHANGELOG.md) for previous changes. From 2ced0e84c1a1ee33d400ea6f36cfdbffa4b3455d Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sun, 22 Feb 2026 18:52:09 +0000 Subject: [PATCH 4/4] Update CHANGELOG.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 743e57590..0cb742c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ #### Changed -- [#1381](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1381) Fix change column preserve old attributes. +- [#1381](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1381) Fix `change_column` to preserve old column attributes. #### Fixed