From 14e317edce2b171658379639792df1fcdeec6a6b Mon Sep 17 00:00:00 2001 From: tianzhou Date: Mon, 5 Jan 2026 00:49:55 -0800 Subject: [PATCH 1/2] docs: add design for COMMENT ON FUNCTION/PROCEDURE support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the implementation approach for adding comment support to functions and procedures in diff generation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- ...05-comment-on-function-procedure-design.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 docs/plans/2026-01-05-comment-on-function-procedure-design.md diff --git a/docs/plans/2026-01-05-comment-on-function-procedure-design.md b/docs/plans/2026-01-05-comment-on-function-procedure-design.md new file mode 100644 index 00000000..c0baa45c --- /dev/null +++ b/docs/plans/2026-01-05-comment-on-function-procedure-design.md @@ -0,0 +1,67 @@ +# COMMENT ON FUNCTION/PROCEDURE Support + +## Overview + +Add support for `COMMENT ON FUNCTION` and `COMMENT ON PROCEDURE` statements in pgschema diff generation. + +## Current State + +- `ir.Function` and `ir.Procedure` already have `Comment` fields +- Comments are inspected from the database via `ir/inspector.go` +- `functionsEqual()` and `proceduresEqual()` don't compare comments +- No code generates `COMMENT ON FUNCTION/PROCEDURE` statements + +## Implementation + +### Approach + +Comment-only changes generate just the `COMMENT ON` statement without DROP/CREATE or CREATE OR REPLACE. This follows the existing pattern used for indexes (`generateIndexComment` in `internal/diff/index.go`). + +### PostgreSQL Syntax + +```sql +COMMENT ON FUNCTION schema.func(arg_types) IS 'description'; +COMMENT ON FUNCTION schema.func(arg_types) IS NULL; -- remove comment +COMMENT ON PROCEDURE schema.proc(arg_types) IS 'description'; +COMMENT ON PROCEDURE schema.proc(arg_types) IS NULL; -- remove comment +``` + +### Files to Modify + +1. **`internal/diff/function.go`** + - Add `generateFunctionComment()` helper + - Call when creating new function with comment + - Call when comment changes (with or without body changes) + +2. **`internal/diff/procedure.go`** + - Add `generateProcedureComment()` helper + - Same pattern as functions + +### Logic Flow + +``` +If function is new: + → CREATE OR REPLACE FUNCTION ... + → If has comment: COMMENT ON FUNCTION ... IS '...' + +If function exists and changed: + → If body/params changed: CREATE OR REPLACE FUNCTION ... + → If comment changed: COMMENT ON FUNCTION ... IS '...' (or IS NULL) + +If only comment changed (body identical): + → Only generate COMMENT ON FUNCTION ... +``` + +### Test Cases + +**`testdata/diff/comment/add_function_comment/`** + +- old.sql: Function without comment +- new.sql: Same function with COMMENT ON FUNCTION statement +- diff.sql: Only the COMMENT ON FUNCTION statement + +**`testdata/diff/comment/add_procedure_comment/`** + +- old.sql: Procedure without comment +- new.sql: Same procedure with COMMENT ON PROCEDURE statement +- diff.sql: Only the COMMENT ON PROCEDURE statement From 673f44d8046e5162e0f63f5aa41fd0ea8540afa7 Mon Sep 17 00:00:00 2001 From: tianzhou Date: Mon, 5 Jan 2026 01:03:22 -0800 Subject: [PATCH 2/2] feat: add COMMENT ON FUNCTION/PROCEDURE support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add generateFunctionComment() and generateProcedureComment() helpers - Update functionsEqual() and proceduresEqual() to compare comments - Add functionsEqualExceptComment() and proceduresEqualExceptComment() - Comment-only changes generate just COMMENT ON statement (no DROP/CREATE) - New functions/procedures with comments emit COMMENT ON after CREATE - Body changes with comment changes emit both statements Test cases added: - comment/add_function_comment - comment/add_procedure_comment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .gitignore | 1 + ...05-comment-on-function-procedure-design.md | 67 ------------- internal/diff/function.go | 95 +++++++++++++++++++ internal/diff/procedure.go | 90 +++++++++++++++++- .../comment/add_function_comment/diff.sql | 1 + .../diff/comment/add_function_comment/new.sql | 6 ++ .../diff/comment/add_function_comment/old.sql | 4 + .../comment/add_function_comment/plan.json | 20 ++++ .../comment/add_function_comment/plan.sql | 1 + .../comment/add_function_comment/plan.txt | 12 +++ .../comment/add_procedure_comment/diff.sql | 1 + .../comment/add_procedure_comment/new.sql | 5 + .../comment/add_procedure_comment/old.sql | 3 + .../comment/add_procedure_comment/plan.json | 20 ++++ .../comment/add_procedure_comment/plan.sql | 1 + .../comment/add_procedure_comment/plan.txt | 12 +++ 16 files changed, 268 insertions(+), 71 deletions(-) delete mode 100644 docs/plans/2026-01-05-comment-on-function-procedure-design.md create mode 100644 testdata/diff/comment/add_function_comment/diff.sql create mode 100644 testdata/diff/comment/add_function_comment/new.sql create mode 100644 testdata/diff/comment/add_function_comment/old.sql create mode 100644 testdata/diff/comment/add_function_comment/plan.json create mode 100644 testdata/diff/comment/add_function_comment/plan.sql create mode 100644 testdata/diff/comment/add_function_comment/plan.txt create mode 100644 testdata/diff/comment/add_procedure_comment/diff.sql create mode 100644 testdata/diff/comment/add_procedure_comment/new.sql create mode 100644 testdata/diff/comment/add_procedure_comment/old.sql create mode 100644 testdata/diff/comment/add_procedure_comment/plan.json create mode 100644 testdata/diff/comment/add_procedure_comment/plan.sql create mode 100644 testdata/diff/comment/add_procedure_comment/plan.txt diff --git a/.gitignore b/.gitignore index 243a187a..13cb37c4 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ Thumbs.db # Build output pgschema +docs/plans/ dist/ build/ diff --git a/docs/plans/2026-01-05-comment-on-function-procedure-design.md b/docs/plans/2026-01-05-comment-on-function-procedure-design.md deleted file mode 100644 index c0baa45c..00000000 --- a/docs/plans/2026-01-05-comment-on-function-procedure-design.md +++ /dev/null @@ -1,67 +0,0 @@ -# COMMENT ON FUNCTION/PROCEDURE Support - -## Overview - -Add support for `COMMENT ON FUNCTION` and `COMMENT ON PROCEDURE` statements in pgschema diff generation. - -## Current State - -- `ir.Function` and `ir.Procedure` already have `Comment` fields -- Comments are inspected from the database via `ir/inspector.go` -- `functionsEqual()` and `proceduresEqual()` don't compare comments -- No code generates `COMMENT ON FUNCTION/PROCEDURE` statements - -## Implementation - -### Approach - -Comment-only changes generate just the `COMMENT ON` statement without DROP/CREATE or CREATE OR REPLACE. This follows the existing pattern used for indexes (`generateIndexComment` in `internal/diff/index.go`). - -### PostgreSQL Syntax - -```sql -COMMENT ON FUNCTION schema.func(arg_types) IS 'description'; -COMMENT ON FUNCTION schema.func(arg_types) IS NULL; -- remove comment -COMMENT ON PROCEDURE schema.proc(arg_types) IS 'description'; -COMMENT ON PROCEDURE schema.proc(arg_types) IS NULL; -- remove comment -``` - -### Files to Modify - -1. **`internal/diff/function.go`** - - Add `generateFunctionComment()` helper - - Call when creating new function with comment - - Call when comment changes (with or without body changes) - -2. **`internal/diff/procedure.go`** - - Add `generateProcedureComment()` helper - - Same pattern as functions - -### Logic Flow - -``` -If function is new: - → CREATE OR REPLACE FUNCTION ... - → If has comment: COMMENT ON FUNCTION ... IS '...' - -If function exists and changed: - → If body/params changed: CREATE OR REPLACE FUNCTION ... - → If comment changed: COMMENT ON FUNCTION ... IS '...' (or IS NULL) - -If only comment changed (body identical): - → Only generate COMMENT ON FUNCTION ... -``` - -### Test Cases - -**`testdata/diff/comment/add_function_comment/`** - -- old.sql: Function without comment -- new.sql: Same function with COMMENT ON FUNCTION statement -- diff.sql: Only the COMMENT ON FUNCTION statement - -**`testdata/diff/comment/add_procedure_comment/`** - -- old.sql: Procedure without comment -- new.sql: Same procedure with COMMENT ON PROCEDURE statement -- diff.sql: Only the COMMENT ON PROCEDURE statement diff --git a/internal/diff/function.go b/internal/diff/function.go index b1c94305..1b7112fa 100644 --- a/internal/diff/function.go +++ b/internal/diff/function.go @@ -30,6 +30,11 @@ func generateCreateFunctionsSQL(functions []*ir.Function, targetSchema string, c } collector.collect(context, sql) + + // Generate COMMENT ON FUNCTION if the function has a comment + if function.Comment != "" { + generateFunctionComment(function, targetSchema, DiffTypeFunction, DiffOperationCreate, collector) + } } } @@ -39,6 +44,15 @@ func generateModifyFunctionsSQL(diffs []*functionDiff, targetSchema string, coll oldFunc := diff.Old newFunc := diff.New + // Check if only comment changed (no body/attribute changes) + onlyCommentChanged := functionsEqualExceptComment(oldFunc, newFunc) && oldFunc.Comment != newFunc.Comment + + if onlyCommentChanged { + // Only the comment changed - generate just COMMENT ON FUNCTION + generateFunctionComment(newFunc, targetSchema, DiffTypeFunction, DiffOperationAlter, collector) + continue + } + // Check if only LEAKPROOF or PARALLEL attributes changed (not the function body/definition) onlyAttributesChanged := functionsEqualExceptAttributes(oldFunc, newFunc) @@ -83,6 +97,11 @@ func generateModifyFunctionsSQL(diffs []*functionDiff, targetSchema string, coll } collector.collect(context, stmt) } + + // Check if comment also changed alongside attributes + if oldFunc.Comment != newFunc.Comment { + generateFunctionComment(newFunc, targetSchema, DiffTypeFunction, DiffOperationAlter, collector) + } } else { // Function body or other attributes changed - use CREATE OR REPLACE sql := generateFunctionSQL(newFunc, targetSchema) @@ -97,6 +116,11 @@ func generateModifyFunctionsSQL(diffs []*functionDiff, targetSchema string, coll } collector.collect(context, sql) + + // Check if comment also changed alongside body changes + if oldFunc.Comment != newFunc.Comment { + generateFunctionComment(newFunc, targetSchema, DiffTypeFunction, DiffOperationAlter, collector) + } } } } @@ -369,6 +393,9 @@ func functionsEqual(old, new *ir.Function) bool { if old.Parallel != new.Parallel { return false } + if old.Comment != new.Comment { + return false + } // Compare using normalized Parameters array // This ensures type aliases like "character varying" vs "varchar" are treated as equal @@ -379,6 +406,46 @@ func functionsEqual(old, new *ir.Function) bool { return parametersEqual(oldInputParams, newInputParams) } +// functionsEqualExceptComment compares two functions ignoring comment differences +// Used to determine if only the comment changed (no body/attribute changes needed) +func functionsEqualExceptComment(old, new *ir.Function) bool { + if old.Schema != new.Schema { + return false + } + if old.Name != new.Name { + return false + } + if old.Definition != new.Definition { + return false + } + if old.ReturnType != new.ReturnType { + return false + } + if old.Language != new.Language { + return false + } + if old.Volatility != new.Volatility { + return false + } + if old.IsStrict != new.IsStrict { + return false + } + if old.IsSecurityDefiner != new.IsSecurityDefiner { + return false + } + if old.IsLeakproof != new.IsLeakproof { + return false + } + if old.Parallel != new.Parallel { + return false + } + // Note: We intentionally do NOT compare Comment here + + oldInputParams := filterNonTableParameters(old.Parameters) + newInputParams := filterNonTableParameters(new.Parameters) + return parametersEqual(oldInputParams, newInputParams) +} + // filterNonTableParameters filters out TABLE mode parameters // TABLE parameters are output columns in RETURNS TABLE() and shouldn't be compared as input parameters func filterNonTableParameters(params []*ir.Parameter) []*ir.Parameter { @@ -433,3 +500,31 @@ func parameterEqual(old, new *ir.Parameter) bool { return true } + +// generateFunctionComment generates COMMENT ON FUNCTION statement +func generateFunctionComment( + function *ir.Function, + targetSchema string, + diffType DiffType, + operation DiffOperation, + collector *diffCollector, +) { + functionName := qualifyEntityName(function.Schema, function.Name, targetSchema) + argsList := function.GetArguments() + + var sql string + if function.Comment == "" { + sql = fmt.Sprintf("COMMENT ON FUNCTION %s(%s) IS NULL;", functionName, argsList) + } else { + sql = fmt.Sprintf("COMMENT ON FUNCTION %s(%s) IS %s;", functionName, argsList, quoteString(function.Comment)) + } + + context := &diffContext{ + Type: diffType, + Operation: operation, + Path: fmt.Sprintf("%s.%s", function.Schema, function.Name), + Source: function, + CanRunInTransaction: true, + } + collector.collect(context, sql) +} diff --git a/internal/diff/procedure.go b/internal/diff/procedure.go index 827af9a5..1a385bc8 100644 --- a/internal/diff/procedure.go +++ b/internal/diff/procedure.go @@ -30,18 +30,35 @@ func generateCreateProceduresSQL(procedures []*ir.Procedure, targetSchema string } collector.collect(context, sql) + + // Generate COMMENT ON PROCEDURE if the procedure has a comment + if procedure.Comment != "" { + generateProcedureComment(procedure, targetSchema, DiffTypeProcedure, DiffOperationCreate, collector) + } } } // generateModifyProceduresSQL generates DROP and CREATE PROCEDURE statements for modified procedures func generateModifyProceduresSQL(diffs []*procedureDiff, targetSchema string, collector *diffCollector) { for _, diff := range diffs { + oldProc := diff.Old + newProc := diff.New + + // Check if only comment changed (no body changes) + onlyCommentChanged := proceduresEqualExceptComment(oldProc, newProc) && oldProc.Comment != newProc.Comment + + if onlyCommentChanged { + // Only the comment changed - generate just COMMENT ON PROCEDURE + generateProcedureComment(newProc, targetSchema, DiffTypeProcedure, DiffOperationAlter, collector) + continue + } + // Drop the old procedure first - procedureName := qualifyEntityName(diff.Old.Schema, diff.Old.Name, targetSchema) + procedureName := qualifyEntityName(oldProc.Schema, oldProc.Name, targetSchema) var dropSQL string // For DROP statements, we need the full parameter signature including modes and names - paramSignature := formatProcedureParametersForDrop(diff.Old) + paramSignature := formatProcedureParametersForDrop(oldProc) if paramSignature != "" { dropSQL = fmt.Sprintf("DROP PROCEDURE IF EXISTS %s(%s);", procedureName, paramSignature) } else { @@ -49,14 +66,14 @@ func generateModifyProceduresSQL(diffs []*procedureDiff, targetSchema string, co } // Create the new procedure - createSQL := generateProcedureSQL(diff.New, targetSchema) + createSQL := generateProcedureSQL(newProc, targetSchema) // Create a single context with ALTER operation and multiple statements // This represents the modification as a single operation in the summary alterContext := &diffContext{ Type: DiffTypeProcedure, Operation: DiffOperationAlter, - Path: fmt.Sprintf("%s.%s", diff.New.Schema, diff.New.Name), + Path: fmt.Sprintf("%s.%s", newProc.Schema, newProc.Name), Source: diff, CanRunInTransaction: true, } @@ -68,6 +85,11 @@ func generateModifyProceduresSQL(diffs []*procedureDiff, targetSchema string, co } collector.collectStatements(alterContext, statements) + + // Check if comment also changed alongside body changes + if oldProc.Comment != newProc.Comment { + generateProcedureComment(newProc, targetSchema, DiffTypeProcedure, DiffOperationAlter, collector) + } } } @@ -240,6 +262,9 @@ func proceduresEqual(old, new *ir.Procedure) bool { if old.Language != new.Language { return false } + if old.Comment != new.Comment { + return false + } // Compare using normalized Parameters array instead of Signature // This ensures proper comparison regardless of how parameters are specified @@ -258,6 +283,35 @@ func proceduresEqual(old, new *ir.Procedure) bool { return true } +// proceduresEqualExceptComment compares two procedures ignoring comment differences +// Used to determine if only the comment changed (no body changes needed) +func proceduresEqualExceptComment(old, new *ir.Procedure) bool { + if old.Schema != new.Schema { + return false + } + if old.Name != new.Name { + return false + } + if old.Definition != new.Definition { + return false + } + if old.Language != new.Language { + return false + } + // Note: We intentionally do NOT compare Comment here + + hasOldParams := len(old.Parameters) > 0 + hasNewParams := len(new.Parameters) > 0 + + if hasOldParams && hasNewParams { + return parametersEqual(old.Parameters, new.Parameters) + } else if hasOldParams || hasNewParams { + return false + } + + return true +} + // formatProcedureParametersForDrop formats procedure parameters for DROP PROCEDURE statements // Returns the full parameter signature including mode and name (e.g., "IN order_id integer, IN amount numeric") // This is necessary for proper procedure identification in PostgreSQL @@ -271,3 +325,31 @@ func formatProcedureParametersForDrop(procedure *ir.Procedure) string { } return strings.Join(paramParts, ", ") } + +// generateProcedureComment generates COMMENT ON PROCEDURE statement +func generateProcedureComment( + procedure *ir.Procedure, + targetSchema string, + diffType DiffType, + operation DiffOperation, + collector *diffCollector, +) { + procedureName := qualifyEntityName(procedure.Schema, procedure.Name, targetSchema) + argsList := procedure.GetArguments() + + var sql string + if procedure.Comment == "" { + sql = fmt.Sprintf("COMMENT ON PROCEDURE %s(%s) IS NULL;", procedureName, argsList) + } else { + sql = fmt.Sprintf("COMMENT ON PROCEDURE %s(%s) IS %s;", procedureName, argsList, quoteString(procedure.Comment)) + } + + context := &diffContext{ + Type: diffType, + Operation: operation, + Path: fmt.Sprintf("%s.%s", procedure.Schema, procedure.Name), + Source: procedure, + CanRunInTransaction: true, + } + collector.collect(context, sql) +} diff --git a/testdata/diff/comment/add_function_comment/diff.sql b/testdata/diff/comment/add_function_comment/diff.sql new file mode 100644 index 00000000..e201efa9 --- /dev/null +++ b/testdata/diff/comment/add_function_comment/diff.sql @@ -0,0 +1 @@ +COMMENT ON FUNCTION calculate_total(numeric, integer) IS 'Calculates total price from unit price and quantity'; diff --git a/testdata/diff/comment/add_function_comment/new.sql b/testdata/diff/comment/add_function_comment/new.sql new file mode 100644 index 00000000..22619617 --- /dev/null +++ b/testdata/diff/comment/add_function_comment/new.sql @@ -0,0 +1,6 @@ +CREATE FUNCTION public.calculate_total(price numeric, quantity integer) +RETURNS numeric +LANGUAGE sql +AS $$SELECT price * quantity$$; + +COMMENT ON FUNCTION public.calculate_total(numeric, integer) IS 'Calculates total price from unit price and quantity'; diff --git a/testdata/diff/comment/add_function_comment/old.sql b/testdata/diff/comment/add_function_comment/old.sql new file mode 100644 index 00000000..5ae0f1e8 --- /dev/null +++ b/testdata/diff/comment/add_function_comment/old.sql @@ -0,0 +1,4 @@ +CREATE FUNCTION public.calculate_total(price numeric, quantity integer) +RETURNS numeric +LANGUAGE sql +AS $$SELECT price * quantity$$; diff --git a/testdata/diff/comment/add_function_comment/plan.json b/testdata/diff/comment/add_function_comment/plan.json new file mode 100644 index 00000000..ba8cbffa --- /dev/null +++ b/testdata/diff/comment/add_function_comment/plan.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.5.1", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "b6bab766c934e98996959773eed9f4a536ad858a300beac3fc74b5edc0359228" + }, + "groups": [ + { + "steps": [ + { + "sql": "COMMENT ON FUNCTION calculate_total(numeric, integer) IS 'Calculates total price from unit price and quantity';", + "type": "function", + "operation": "alter", + "path": "public.calculate_total" + } + ] + } + ] +} diff --git a/testdata/diff/comment/add_function_comment/plan.sql b/testdata/diff/comment/add_function_comment/plan.sql new file mode 100644 index 00000000..e201efa9 --- /dev/null +++ b/testdata/diff/comment/add_function_comment/plan.sql @@ -0,0 +1 @@ +COMMENT ON FUNCTION calculate_total(numeric, integer) IS 'Calculates total price from unit price and quantity'; diff --git a/testdata/diff/comment/add_function_comment/plan.txt b/testdata/diff/comment/add_function_comment/plan.txt new file mode 100644 index 00000000..708ed747 --- /dev/null +++ b/testdata/diff/comment/add_function_comment/plan.txt @@ -0,0 +1,12 @@ +Plan: 1 to modify. + +Summary by type: + functions: 1 to modify + +Functions: + ~ calculate_total + +DDL to be executed: +-------------------------------------------------- + +COMMENT ON FUNCTION calculate_total(numeric, integer) IS 'Calculates total price from unit price and quantity'; diff --git a/testdata/diff/comment/add_procedure_comment/diff.sql b/testdata/diff/comment/add_procedure_comment/diff.sql new file mode 100644 index 00000000..a183c11b --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/diff.sql @@ -0,0 +1 @@ +COMMENT ON PROCEDURE process_order(integer) IS 'Processes a single order by ID'; diff --git a/testdata/diff/comment/add_procedure_comment/new.sql b/testdata/diff/comment/add_procedure_comment/new.sql new file mode 100644 index 00000000..fa064e1e --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/new.sql @@ -0,0 +1,5 @@ +CREATE PROCEDURE public.process_order(IN order_id integer) +LANGUAGE sql +AS $$SELECT 1$$; + +COMMENT ON PROCEDURE public.process_order(integer) IS 'Processes a single order by ID'; diff --git a/testdata/diff/comment/add_procedure_comment/old.sql b/testdata/diff/comment/add_procedure_comment/old.sql new file mode 100644 index 00000000..61e92c42 --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/old.sql @@ -0,0 +1,3 @@ +CREATE PROCEDURE public.process_order(IN order_id integer) +LANGUAGE sql +AS $$SELECT 1$$; diff --git a/testdata/diff/comment/add_procedure_comment/plan.json b/testdata/diff/comment/add_procedure_comment/plan.json new file mode 100644 index 00000000..2c1557ad --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/plan.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.5.1", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "f2a1199280f3ed3bb4f7dad3602c7f0fcacfce9d79e40201b48b5bf7325f5c64" + }, + "groups": [ + { + "steps": [ + { + "sql": "COMMENT ON PROCEDURE process_order(integer) IS 'Processes a single order by ID';", + "type": "procedure", + "operation": "alter", + "path": "public.process_order" + } + ] + } + ] +} diff --git a/testdata/diff/comment/add_procedure_comment/plan.sql b/testdata/diff/comment/add_procedure_comment/plan.sql new file mode 100644 index 00000000..a183c11b --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/plan.sql @@ -0,0 +1 @@ +COMMENT ON PROCEDURE process_order(integer) IS 'Processes a single order by ID'; diff --git a/testdata/diff/comment/add_procedure_comment/plan.txt b/testdata/diff/comment/add_procedure_comment/plan.txt new file mode 100644 index 00000000..9ba33199 --- /dev/null +++ b/testdata/diff/comment/add_procedure_comment/plan.txt @@ -0,0 +1,12 @@ +Plan: 1 to modify. + +Summary by type: + procedures: 1 to modify + +Procedures: + ~ process_order + +DDL to be executed: +-------------------------------------------------- + +COMMENT ON PROCEDURE process_order(integer) IS 'Processes a single order by ID';