From 054ea72ad96a0d858ed0566f4c1bdeac35a0c79b Mon Sep 17 00:00:00 2001 From: Azim Sonawalla Date: Wed, 14 Jan 2026 18:50:17 -0500 Subject: [PATCH 1/2] fix: include column comments when adding new columns When adding a new column with a COMMENT ON COLUMN to an existing table, the comment was not included in the first plan. It required a second plan/apply cycle to converge. Added a loop after the AddedColumns processing in generateAlterTableStatements to emit COMMENT ON COLUMN statements for any added columns that have comments. This follows the same pattern used for new tables and new indexes. --- internal/diff/table.go | 17 +++++++++++++++++ testdata/diff/comment/mixed_comments/diff.sql | 4 ++++ testdata/diff/comment/mixed_comments/new.sql | 4 +++- testdata/diff/comment/mixed_comments/plan.json | 12 ++++++++++++ testdata/diff/comment/mixed_comments/plan.sql | 4 ++++ testdata/diff/comment/mixed_comments/plan.txt | 6 ++++++ 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/internal/diff/table.go b/internal/diff/table.go index 8983a6b7..621cd0a3 100644 --- a/internal/diff/table.go +++ b/internal/diff/table.go @@ -766,6 +766,23 @@ func (td *tableDiff) generateAlterTableStatements(targetSchema string, collector collector.collect(context, stmt+";") } + // Add comments for new columns + for _, column := range td.AddedColumns { + if column.Comment != "" { + tableName := getTableNameWithSchema(td.Table.Schema, td.Table.Name, targetSchema) + sql := fmt.Sprintf("COMMENT ON COLUMN %s.%s IS %s;", tableName, column.Name, quoteString(column.Comment)) + + context := &diffContext{ + Type: DiffTypeTableColumnComment, + Operation: DiffOperationCreate, + Path: fmt.Sprintf("%s.%s.%s", td.Table.Schema, td.Table.Name, column.Name), + Source: column, + CanRunInTransaction: true, + } + collector.collect(context, sql) + } + } + // Modify existing columns - already sorted by the Diff operation for _, ColumnDiff := range td.ModifiedColumns { // Generate column modification statements and collect as a single step diff --git a/testdata/diff/comment/mixed_comments/diff.sql b/testdata/diff/comment/mixed_comments/diff.sql index 0307ba26..9fdf7197 100644 --- a/testdata/diff/comment/mixed_comments/diff.sql +++ b/testdata/diff/comment/mixed_comments/diff.sql @@ -12,6 +12,10 @@ COMMENT ON COLUMN categories.created_at IS 'Category creation timestamp'; COMMENT ON INDEX idx_categories_parent IS 'Index for hierarchical category queries'; +ALTER TABLE posts ADD COLUMN views integer DEFAULT 0; + +COMMENT ON COLUMN posts.views IS 'Number of post views'; + COMMENT ON TABLE posts IS 'Blog posts and articles'; COMMENT ON COLUMN posts.id IS 'Unique post identifier'; diff --git a/testdata/diff/comment/mixed_comments/new.sql b/testdata/diff/comment/mixed_comments/new.sql index aeca554f..19f115e9 100644 --- a/testdata/diff/comment/mixed_comments/new.sql +++ b/testdata/diff/comment/mixed_comments/new.sql @@ -3,7 +3,8 @@ CREATE TABLE posts ( title VARCHAR(200) NOT NULL, content TEXT, author_id INTEGER NOT NULL, - published_at TIMESTAMP + published_at TIMESTAMP, + views INTEGER DEFAULT 0 ); COMMENT ON TABLE posts IS 'Blog posts and articles'; COMMENT ON COLUMN posts.id IS 'Unique post identifier'; @@ -11,6 +12,7 @@ COMMENT ON COLUMN posts.title IS 'Post title, max 200 characters'; COMMENT ON COLUMN posts.content IS 'Post body in markdown format'; COMMENT ON COLUMN posts.author_id IS 'Foreign key to users table'; COMMENT ON COLUMN posts.published_at IS 'Publication timestamp, NULL for drafts'; +COMMENT ON COLUMN posts.views IS 'Number of post views'; CREATE INDEX idx_posts_author ON posts (author_id); COMMENT ON INDEX idx_posts_author IS 'Index for finding posts by author'; diff --git a/testdata/diff/comment/mixed_comments/plan.json b/testdata/diff/comment/mixed_comments/plan.json index 1a431aaf..91735907 100644 --- a/testdata/diff/comment/mixed_comments/plan.json +++ b/testdata/diff/comment/mixed_comments/plan.json @@ -50,6 +50,18 @@ "operation": "alter", "path": "public.categories.idx_categories_parent" }, + { + "sql": "ALTER TABLE posts ADD COLUMN views integer DEFAULT 0;", + "type": "table.column", + "operation": "create", + "path": "public.posts.views" + }, + { + "sql": "COMMENT ON COLUMN posts.views IS 'Number of post views';", + "type": "table.column.comment", + "operation": "create", + "path": "public.posts.views" + }, { "sql": "COMMENT ON TABLE posts IS 'Blog posts and articles';", "type": "table.comment", diff --git a/testdata/diff/comment/mixed_comments/plan.sql b/testdata/diff/comment/mixed_comments/plan.sql index 0307ba26..9fdf7197 100644 --- a/testdata/diff/comment/mixed_comments/plan.sql +++ b/testdata/diff/comment/mixed_comments/plan.sql @@ -12,6 +12,10 @@ COMMENT ON COLUMN categories.created_at IS 'Category creation timestamp'; COMMENT ON INDEX idx_categories_parent IS 'Index for hierarchical category queries'; +ALTER TABLE posts ADD COLUMN views integer DEFAULT 0; + +COMMENT ON COLUMN posts.views IS 'Number of post views'; + COMMENT ON TABLE posts IS 'Blog posts and articles'; COMMENT ON COLUMN posts.id IS 'Unique post identifier'; diff --git a/testdata/diff/comment/mixed_comments/plan.txt b/testdata/diff/comment/mixed_comments/plan.txt index ae5960b9..6ac14ba1 100644 --- a/testdata/diff/comment/mixed_comments/plan.txt +++ b/testdata/diff/comment/mixed_comments/plan.txt @@ -13,11 +13,13 @@ Tables: ~ categories (comment) ~ idx_categories_parent (index.comment) ~ posts + + views (column) ~ author_id (column.comment) ~ content (column.comment) ~ id (column.comment) ~ published_at (column.comment) ~ title (column.comment) + + views (column.comment) ~ posts (comment) ~ idx_posts_author (index.comment) ~ idx_posts_published (index.comment) @@ -39,6 +41,10 @@ COMMENT ON COLUMN categories.created_at IS 'Category creation timestamp'; COMMENT ON INDEX idx_categories_parent IS 'Index for hierarchical category queries'; +ALTER TABLE posts ADD COLUMN views integer DEFAULT 0; + +COMMENT ON COLUMN posts.views IS 'Number of post views'; + COMMENT ON TABLE posts IS 'Blog posts and articles'; COMMENT ON COLUMN posts.id IS 'Unique post identifier'; From 1b571bd6576c0c09ff51c2e821926733a7efec41 Mon Sep 17 00:00:00 2001 From: Tianzhou Date: Wed, 14 Jan 2026 18:19:16 -0800 Subject: [PATCH 2/2] Update internal/diff/table.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- internal/diff/table.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/diff/table.go b/internal/diff/table.go index 621cd0a3..927465ec 100644 --- a/internal/diff/table.go +++ b/internal/diff/table.go @@ -770,7 +770,7 @@ func (td *tableDiff) generateAlterTableStatements(targetSchema string, collector for _, column := range td.AddedColumns { if column.Comment != "" { tableName := getTableNameWithSchema(td.Table.Schema, td.Table.Name, targetSchema) - sql := fmt.Sprintf("COMMENT ON COLUMN %s.%s IS %s;", tableName, column.Name, quoteString(column.Comment)) + sql := fmt.Sprintf("COMMENT ON COLUMN %s.%s IS %s;", tableName, ir.QuoteIdentifier(column.Name), quoteString(column.Comment)) context := &diffContext{ Type: DiffTypeTableColumnComment,