Skip to content

Commit

Permalink
Merge pull request rails#51531 from fatkodima/fix-sqlite-copy-virtual…
Browse files Browse the repository at this point in the history
…-columns

Fix copying virtual columns when altering a table in sqlite3
  • Loading branch information
yahonda authored Apr 10, 2024
2 parents 50a3bf7 + a457b12 commit 81cbca7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,6 @@ def copy_table(from, to, options = {})
options[:rename][column.name.to_sym] ||
column.name) : column.name

if column.has_default?
type = lookup_cast_type_from_column(column)
default = type.deserialize(column.default)
default = -> { column.default_function } if default.nil?
end

column_options = {
limit: column.limit,
precision: column.precision,
Expand All @@ -593,19 +587,31 @@ def copy_table(from, to, options = {})
primary_key: column_name == from_primary_key
}

unless column.auto_increment?
column_options[:default] = default
if column.virtual?
column_options[:as] = column.default_function
column_options[:stored] = column.virtual_stored?
column_options[:type] = column.type
elsif column.has_default?
type = lookup_cast_type_from_column(column)
default = type.deserialize(column.default)
default = -> { column.default_function } if default.nil?

unless column.auto_increment?
column_options[:default] = default
end
end

column_type = column.bigint? ? :bigint : column.type
column_type = column.virtual? ? :virtual : (column.bigint? ? :bigint : column.type)
@definition.column(column_name, column_type, **column_options)
end

yield @definition if block_given?
end
copy_table_indexes(from, to, options[:rename] || {})

columns_to_copy = @definition.columns.reject { |col| col.options.key?(:as) }.map(&:name)
copy_table_contents(from, to,
@definition.columns.map(&:name),
columns_to_copy,
options[:rename] || {})
end

Expand Down
14 changes: 14 additions & 0 deletions activerecord/test/cases/adapters/sqlite3/copy_table_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ def test_copy_table_with_binary_column
test_copy_table "binaries", "binaries2"
end

def test_copy_table_with_virtual_column
@connection.create_table :virtual_columns, force: true do |t|
t.string :name
t.virtual :upper_name, type: :string, as: "UPPER(name)", stored: true
end

test_copy_table("virtual_columns", "virtual_columns2") do
column = @connection.columns("virtual_columns2").find { |col| col.name == "upper_name" }
assert_predicate column, :virtual_stored?
assert_equal :string, column.type
assert_equal "UPPER(name)", column.default_function
end
end

private
def copy_table(from, to, options = {})
@connection.send(:copy_table, from, to, { temporary: true }.merge(options))
Expand Down

0 comments on commit 81cbca7

Please sign in to comment.