diff --git a/CHANGELOG.md b/CHANGELOG.md index 31692d8..aed5ae7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## master (unreleased) +- Fix `backfill_column_for_type_change_in_background` for cast expressions - Fix copying indexes with long names when changing column type - Enhance error messages with the link to the detailed description diff --git a/lib/online_migrations/background_migrations/copy_column.rb b/lib/online_migrations/background_migrations/copy_column.rb index 0550926..ad75fac 100644 --- a/lib/online_migrations/background_migrations/copy_column.rb +++ b/lib/online_migrations/background_migrations/copy_column.rb @@ -42,12 +42,18 @@ def process_batch(relation) old_values = copy_from.map do |from_column| old_value = arel_table[from_column] if (type_cast_function = type_cast_functions[from_column]) - if Utils.ar_version <= 5.2 - # Active Record <= 5.2 does not support quoting of Arel::Nodes::NamedFunction - old_value = Arel.sql("#{type_cast_function}(#{connection.quote_column_name(from_column)})") - else - old_value = Arel::Nodes::NamedFunction.new(type_cast_function, [old_value]) - end + old_value = + if type_cast_function =~ /\A\w+\z/ + if Utils.ar_version <= 5.2 + # Active Record <= 5.2 does not support quoting of Arel::Nodes::NamedFunction + Arel.sql("#{type_cast_function}(#{connection.quote_column_name(from_column)})") + else + Arel::Nodes::NamedFunction.new(type_cast_function, [old_value]) + end + else + # We got a cast expression. + Arel.sql(type_cast_function) + end end old_value end diff --git a/test/background_migrations/copy_column_test.rb b/test/background_migrations/copy_column_test.rb index d23e348..666f9f3 100644 --- a/test/background_migrations/copy_column_test.rb +++ b/test/background_migrations/copy_column_test.rb @@ -52,6 +52,14 @@ def test_process_batch_type_cast_function assert_equal "value", @project1.settings_for_type_change["key"] end + def test_process_batch_type_cast_expression + m = OnlineMigrations::BackgroundMigrations::CopyColumn.new(:projects, ["settings"], ["settings_for_type_change"], nil, { "settings" => "CAST(settings AS jsonb)" }) + m.process_batch(m.relation) + + @project1.reload + assert_equal "value", @project1.settings_for_type_change["key"] + end + def test_count m = OnlineMigrations::BackgroundMigrations::CopyColumn.new(:projects, ["id"], ["id_for_type_change"]) assert_kind_of Integer, m.count