Skip to content

Commit 81cbca7

Browse files
authored
Merge pull request rails#51531 from fatkodima/fix-sqlite-copy-virtual-columns
Fix copying virtual columns when altering a table in sqlite3
2 parents 50a3bf7 + a457b12 commit 81cbca7

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -578,12 +578,6 @@ def copy_table(from, to, options = {})
578578
options[:rename][column.name.to_sym] ||
579579
column.name) : column.name
580580

581-
if column.has_default?
582-
type = lookup_cast_type_from_column(column)
583-
default = type.deserialize(column.default)
584-
default = -> { column.default_function } if default.nil?
585-
end
586-
587581
column_options = {
588582
limit: column.limit,
589583
precision: column.precision,
@@ -593,19 +587,31 @@ def copy_table(from, to, options = {})
593587
primary_key: column_name == from_primary_key
594588
}
595589

596-
unless column.auto_increment?
597-
column_options[:default] = default
590+
if column.virtual?
591+
column_options[:as] = column.default_function
592+
column_options[:stored] = column.virtual_stored?
593+
column_options[:type] = column.type
594+
elsif column.has_default?
595+
type = lookup_cast_type_from_column(column)
596+
default = type.deserialize(column.default)
597+
default = -> { column.default_function } if default.nil?
598+
599+
unless column.auto_increment?
600+
column_options[:default] = default
601+
end
598602
end
599603

600-
column_type = column.bigint? ? :bigint : column.type
604+
column_type = column.virtual? ? :virtual : (column.bigint? ? :bigint : column.type)
601605
@definition.column(column_name, column_type, **column_options)
602606
end
603607

604608
yield @definition if block_given?
605609
end
606610
copy_table_indexes(from, to, options[:rename] || {})
611+
612+
columns_to_copy = @definition.columns.reject { |col| col.options.key?(:as) }.map(&:name)
607613
copy_table_contents(from, to,
608-
@definition.columns.map(&:name),
614+
columns_to_copy,
609615
options[:rename] || {})
610616
end
611617

activerecord/test/cases/adapters/sqlite3/copy_table_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ def test_copy_table_with_binary_column
8585
test_copy_table "binaries", "binaries2"
8686
end
8787

88+
def test_copy_table_with_virtual_column
89+
@connection.create_table :virtual_columns, force: true do |t|
90+
t.string :name
91+
t.virtual :upper_name, type: :string, as: "UPPER(name)", stored: true
92+
end
93+
94+
test_copy_table("virtual_columns", "virtual_columns2") do
95+
column = @connection.columns("virtual_columns2").find { |col| col.name == "upper_name" }
96+
assert_predicate column, :virtual_stored?
97+
assert_equal :string, column.type
98+
assert_equal "UPPER(name)", column.default_function
99+
end
100+
end
101+
88102
private
89103
def copy_table(from, to, options = {})
90104
@connection.send(:copy_table, from, to, { temporary: true }.merge(options))

0 commit comments

Comments
 (0)