From cb0776887a6ea98aedf432da232b8026ee5213cd Mon Sep 17 00:00:00 2001 From: August Date: Wed, 19 Jun 2024 12:29:15 +0800 Subject: [PATCH] fix: fix type mismatch of compressed_binary column in function table (#17312) --- src/meta/model_v2/migration/src/lib.rs | 2 + ...40618_072634_function_compressed_binary.rs | 74 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/meta/model_v2/migration/src/m20240618_072634_function_compressed_binary.rs diff --git a/src/meta/model_v2/migration/src/lib.rs b/src/meta/model_v2/migration/src/lib.rs index fa886d0e7df9..83645c479649 100644 --- a/src/meta/model_v2/migration/src/lib.rs +++ b/src/meta/model_v2/migration/src/lib.rs @@ -12,6 +12,7 @@ mod m20240418_142249_function_runtime; mod m20240506_112555_subscription_partial_ckpt; mod m20240525_090457_secret; mod m20240617_070131_index_column_properties; +mod m20240618_072634_function_compressed_binary; pub struct Migrator; @@ -28,6 +29,7 @@ impl MigratorTrait for Migrator { Box::new(m20240418_142249_function_runtime::Migration), Box::new(m20240506_112555_subscription_partial_ckpt::Migration), Box::new(m20240525_090457_secret::Migration), + Box::new(m20240618_072634_function_compressed_binary::Migration), Box::new(m20240617_070131_index_column_properties::Migration), ] } diff --git a/src/meta/model_v2/migration/src/m20240618_072634_function_compressed_binary.rs b/src/meta/model_v2/migration/src/m20240618_072634_function_compressed_binary.rs new file mode 100644 index 000000000000..6b4ef6157bcf --- /dev/null +++ b/src/meta/model_v2/migration/src/m20240618_072634_function_compressed_binary.rs @@ -0,0 +1,74 @@ +use sea_orm_migration::prelude::*; + +use crate::sea_orm::{DatabaseBackend, DbBackend, Statement}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + // Fix mismatch column `compressed_binary` type and do data migration + match manager.get_database_backend() { + DbBackend::MySql => { + // Creating function with compressed binary will fail in previous version, so we can + // safely assume that the column is always empty and we can just modify the column type + // without any data migration. + manager + .alter_table( + Table::alter() + .table(Function::Table) + .modify_column( + ColumnDef::new(Function::CompressedBinary).blob(BlobSize::Medium), + ) + .to_owned(), + ) + .await?; + } + DbBackend::Postgres => { + manager.get_connection().execute(Statement::from_string( + DatabaseBackend::Postgres, + "ALTER TABLE function ALTER COLUMN compressed_binary TYPE bytea USING compressed_binary::bytea", + )).await?; + } + DbBackend::Sqlite => { + // Sqlite does not support modifying column type, so we need to do data migration and column renaming. + // Note that: all these DDLs are not transactional, so if some of them fail, we need to manually run it again. + let conn = manager.get_connection(); + conn.execute(Statement::from_string( + DatabaseBackend::Sqlite, + "ALTER TABLE function ADD COLUMN compressed_binary_new BLOB", + )) + .await?; + conn.execute(Statement::from_string( + DatabaseBackend::Sqlite, + "UPDATE function SET compressed_binary_new = compressed_binary", + )) + .await?; + conn.execute(Statement::from_string( + DatabaseBackend::Sqlite, + "ALTER TABLE function DROP COLUMN compressed_binary", + )) + .await?; + conn.execute(Statement::from_string( + DatabaseBackend::Sqlite, + "ALTER TABLE function RENAME COLUMN compressed_binary_new TO compressed_binary", + )) + .await?; + } + } + + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + // DO nothing, the operations in `up` are idempotent and required to fix the column type mismatch. + Ok(()) + } +} + +#[derive(DeriveIden)] +enum Function { + Table, + CompressedBinary, +}