Skip to content

Commit 9de190e

Browse files
tianzhouclaude
andauthored
fix: re-emit COMMENT when a function or procedure is dropped and recreated (#677) (#678)
When a function change requires DROP + CREATE (return type, OUT params, parameter names) or a procedure body changes (always DROP + CREATE), the plan only emitted COMMENT ON when the comment text differed. Since DROP discards the comment, an unchanged comment was lost after apply and the next plan reported a spurious diff. Emit COMMENT ON after every DROP + CREATE whenever the new routine has a comment, so a single apply converges. Fixes #677 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent f2ebe96 commit 9de190e

14 files changed

Lines changed: 131 additions & 12 deletions

File tree

‎internal/diff/function.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ func generateModifyFunctionsSQL(diffs []*functionDiff, targetSchema string, coll
122122
}
123123
collector.collectStatements(alterContext, statements)
124124

125-
// Check if comment also changed alongside body changes
126-
if oldFunc.Comment != newFunc.Comment {
125+
// DROP FUNCTION discards the comment, so re-emit it whenever the new
126+
// function has one, even if it is unchanged (issue #677).
127+
if newFunc.Comment != "" {
127128
generateFunctionComment(newFunc, targetSchema, DiffTypeFunction, DiffOperationAlter, collector)
128129
}
129130
} else {

‎internal/diff/procedure.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ func generateModifyProceduresSQL(diffs []*procedureDiff, targetSchema string, co
8989

9090
collector.collectStatements(alterContext, statements)
9191

92-
// Check if comment also changed alongside body changes
93-
if oldProc.Comment != newProc.Comment {
92+
// DROP PROCEDURE discards the comment, so re-emit it whenever the new
93+
// procedure has one, even if it is unchanged (issue #677).
94+
if newProc.Comment != "" {
9495
generateProcedureComment(newProc, targetSchema, DiffTypeProcedure, DiffOperationAlter, collector)
9596
}
9697
}

‎testdata/diff/create_function/issue_326_return_type_change/diff.sql‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ LANGUAGE sql
88
VOLATILE
99
AS $$ SELECT length(param1);
1010
$$;
11+
12+
COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';

‎testdata/diff/create_function/issue_326_return_type_change/new.sql‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ CREATE OR REPLACE FUNCTION somefunction(
33
) RETURNS integer
44
LANGUAGE sql
55
AS $$ SELECT length(param1); $$;
6+
7+
-- Issue #677: unchanged comment must survive the DROP + CREATE cycle
8+
COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';

‎testdata/diff/create_function/issue_326_return_type_change/old.sql‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ CREATE OR REPLACE FUNCTION somefunction(
33
) RETURNS text
44
LANGUAGE sql
55
AS $$ SELECT param1; $$;
6+
7+
COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';

‎testdata/diff/create_function/issue_326_return_type_change/plan.json‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"pgschema_version": "1.13.4",
44
"created_at": "1970-01-01T00:00:00Z",
55
"source_fingerprint": {
6-
"hash": "59a96fc0ed0cbfa32f92a9d869bbbc6e38359d50afcd5ea6eb4f388717c48135"
6+
"hash": "7b9f39d2d87004e53be9715527178d0c2f2b5e92a87034c3828c87bd0a3af0ad"
77
},
88
"groups": [
99
{
@@ -19,6 +19,12 @@
1919
"type": "function",
2020
"operation": "alter",
2121
"path": "public.somefunction"
22+
},
23+
{
24+
"sql": "COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';",
25+
"type": "function",
26+
"operation": "alter",
27+
"path": "public.somefunction"
2228
}
2329
]
2430
}

‎testdata/diff/create_function/issue_326_return_type_change/plan.sql‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ LANGUAGE sql
88
VOLATILE
99
AS $$ SELECT length(param1);
1010
$$;
11+
12+
COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';

‎testdata/diff/create_function/issue_326_return_type_change/plan.txt‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
Plan: 1 to modify.
1+
Plan: 2 to modify.
22

33
Summary by type:
4-
functions: 1 to modify
4+
functions: 2 to modify
55

66
Functions:
77
~ somefunction
8+
~ somefunction
89

910
DDL to be executed:
1011
--------------------------------------------------
@@ -19,3 +20,5 @@ LANGUAGE sql
1920
VOLATILE
2021
AS $$ SELECT length(param1);
2122
$$;
23+
24+
COMMENT ON FUNCTION somefunction(text) IS 'Returns text based on param1';

‎testdata/diff/create_procedure/alter_procedure/diff.sql‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,19 @@ BEGIN
2121
COMMIT;
2222
END;
2323
$$;
24+
25+
COMMENT ON PROCEDURE process_payment(integer, numeric, text) IS 'Marks an order as paid';
26+
27+
DROP PROCEDURE IF EXISTS log_event(IN message text);
28+
29+
CREATE OR REPLACE PROCEDURE log_event(
30+
IN message text
31+
)
32+
LANGUAGE plpgsql
33+
AS $$
34+
BEGIN
35+
INSERT INTO event_log (message, logged_at) VALUES (message, NOW());
36+
END;
37+
$$;
38+
39+
COMMENT ON PROCEDURE log_event(text) IS 'Appends a message to event_log';

‎testdata/diff/create_procedure/alter_procedure/new.sql‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,17 @@ BEGIN
1818

1919
COMMIT;
2020
END;
21-
$$;
21+
$$;
22+
-- Issue #677: unchanged comment must survive the DROP + CREATE cycle
23+
COMMENT ON PROCEDURE process_payment(integer, numeric, text) IS 'Marks an order as paid';
24+
25+
-- Issue #677: body-only change keeps the same signature, so pgschema plans
26+
-- DROP + CREATE; the unchanged comment must be re-emitted afterwards.
27+
CREATE PROCEDURE log_event(message text)
28+
LANGUAGE plpgsql
29+
AS $$
30+
BEGIN
31+
INSERT INTO event_log (message, logged_at) VALUES (message, NOW());
32+
END;
33+
$$;
34+
COMMENT ON PROCEDURE log_event(text) IS 'Appends a message to event_log';

0 commit comments

Comments
 (0)