diff --git a/crates/dbx-core/src/table_structure_sql/tests.rs b/crates/dbx-core/src/table_structure_sql/tests.rs index 54c1be3ec..57aa1a519 100644 --- a/crates/dbx-core/src/table_structure_sql/tests.rs +++ b/crates/dbx-core/src/table_structure_sql/tests.rs @@ -3558,6 +3558,69 @@ fn builds_mysql_trigger_changes() { ); } +#[test] +fn unchanged_postgres_trigger_does_not_block_column_rename() { + let mut renamed = column("display_name"); + renamed.original = Some(ColumnInfo { + name: "name".to_string(), + data_type: "varchar(255)".to_string(), + is_nullable: true, + column_default: None, + is_primary_key: false, + extra: None, + comment: None, + ..Default::default() + }); + let mut existing = trigger("users_audit", "AFTER", "UPDATE", "EXECUTE FUNCTION audit_users()"); + existing.original = Some(TriggerInfo { + name: "users_audit".to_string(), + event: "UPDATE".to_string(), + timing: "AFTER".to_string(), + statement: Some("EXECUTE FUNCTION audit_users()".to_string()), + }); + + let result = build_table_structure_change_sql(TableStructureSqlOptions { + database_type: Some(DatabaseType::Postgres), + schema: Some("public".to_string()), + table_name: "users".to_string(), + columns: vec![renamed], + indexes: Vec::new(), + foreign_keys: Vec::new(), + triggers: vec![existing], + table_comment: None, + original_table_comment: None, + }); + + assert_eq!(result.warnings, Vec::::new()); + assert_eq!(result.statements, vec!["ALTER TABLE \"public\".\"users\" RENAME COLUMN \"name\" TO \"display_name\";"]); +} + +#[test] +fn changed_postgres_trigger_remains_unsupported() { + let mut existing = trigger("users_audit", "AFTER", "INSERT", "EXECUTE FUNCTION audit_users()"); + existing.original = Some(TriggerInfo { + name: "users_audit".to_string(), + event: "UPDATE".to_string(), + timing: "AFTER".to_string(), + statement: Some("EXECUTE FUNCTION audit_users()".to_string()), + }); + + let result = build_table_structure_change_sql(TableStructureSqlOptions { + database_type: Some(DatabaseType::Postgres), + schema: Some("public".to_string()), + table_name: "users".to_string(), + columns: Vec::new(), + indexes: Vec::new(), + foreign_keys: Vec::new(), + triggers: vec![existing], + table_comment: None, + original_table_comment: None, + }); + + assert!(result.statements.is_empty()); + assert_eq!(result.warnings, vec!["Editing triggers is not supported for postgres from this editor."]); +} + #[test] fn rejects_editing_existing_oracle_trigger_without_complete_source() { let mut existing = trigger( diff --git a/crates/dbx-core/src/table_structure_sql/triggers.rs b/crates/dbx-core/src/table_structure_sql/triggers.rs index 420bfac66..cc45356f9 100644 --- a/crates/dbx-core/src/table_structure_sql/triggers.rs +++ b/crates/dbx-core/src/table_structure_sql/triggers.rs @@ -10,7 +10,9 @@ pub(super) fn build_trigger_sql(options: &TableStructureSqlOptions, warnings: &m let dialect = super::dialect::capabilities_for(options.database_type).dialect; let database_label = database_label(options.database_type); if !matches!(dialect, StructureDialect::Mysql | StructureDialect::Oracle) { - warnings.push(format!("Editing triggers is not supported for {database_label} from this editor.")); + if options.triggers.iter().any(has_trigger_edit) { + warnings.push(format!("Editing triggers is not supported for {database_label} from this editor.")); + } return Vec::new(); } @@ -52,6 +54,10 @@ pub(super) fn build_trigger_sql(options: &TableStructureSqlOptions, warnings: &m statements } +fn has_trigger_edit(trigger: &EditableStructureTrigger) -> bool { + trigger.marked_for_drop || trigger.original.as_ref().map_or(true, |original| has_trigger_change(trigger, original)) +} + fn has_trigger_change(trigger: &EditableStructureTrigger, original: &TriggerInfo) -> bool { clean(&trigger.name) != clean(&original.name) || normalize_keyword(&trigger.timing) != normalize_keyword(&original.timing)