]> granicus.if.org Git - postgresql/commitdiff
Improve error messages for CREATE OR REPLACE PROCEDURE
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 8 Aug 2018 18:39:26 +0000 (20:39 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Sat, 18 Aug 2018 20:05:43 +0000 (22:05 +0200)
Change the hint to recommend DROP PROCEDURE instead of FUNCTION.  Also
make the error message when changing the return type more specific to
the case of procedures.

Reported-by: Jeremy Evans <code@jeremyevans.net>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
src/backend/catalog/pg_proc.c

index 9b4015d0d4a9e695bac5e76244b5f652d8708013..0c817047cd181241d11ed997b08a764f5e83d84a 100644 (file)
@@ -375,6 +375,7 @@ ProcedureCreate(const char *procedureName,
                Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup);
                Datum           proargnames;
                bool            isnull;
+               const char *dropcmd;
 
                if (!replace)
                        ereport(ERROR,
@@ -400,16 +401,26 @@ ProcedureCreate(const char *procedureName,
                                          errdetail("\"%s\" is a window function.", procedureName) :
                                          0)));
 
+               dropcmd = (prokind == PROKIND_PROCEDURE ? "DROP PROCEDURE" : "DROP FUNCTION");
+
                /*
                 * Not okay to change the return type of the existing proc, since
                 * existing rules, views, etc may depend on the return type.
+                *
+                * In case of a procedure, a changing return type means that whether
+                * the procedure has output parameters was changed.  Since there is no
+                * user visible return type, we produce a more specific error message.
                 */
                if (returnType != oldproc->prorettype ||
                        returnsSet != oldproc->proretset)
                        ereport(ERROR,
                                        (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-                                        errmsg("cannot change return type of existing function"),
-                                        errhint("Use DROP FUNCTION %s first.",
+                                        prokind == PROKIND_PROCEDURE
+                                        ? errmsg("cannot change whether a procedure has output parameters")
+                                        : errmsg("cannot change return type of existing function"),
+                                        /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
+                                        errhint("Use %s %s first.",
+                                                        dropcmd,
                                                         format_procedure(HeapTupleGetOid(oldtup)))));
 
                /*
@@ -434,7 +445,9 @@ ProcedureCreate(const char *procedureName,
                                                (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
                                                 errmsg("cannot change return type of existing function"),
                                                 errdetail("Row type defined by OUT parameters is different."),
-                                                errhint("Use DROP FUNCTION %s first.",
+                                                /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
+                                                errhint("Use %s %s first.",
+                                                                dropcmd,
                                                                 format_procedure(HeapTupleGetOid(oldtup)))));
                }
 
@@ -477,7 +490,9 @@ ProcedureCreate(const char *procedureName,
                                                        (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
                                                         errmsg("cannot change name of input parameter \"%s\"",
                                                                        old_arg_names[j]),
-                                                        errhint("Use DROP FUNCTION %s first.",
+                                                        /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
+                                                        errhint("Use %s %s first.",
+                                                                        dropcmd,
                                                                         format_procedure(HeapTupleGetOid(oldtup)))));
                        }
                }
@@ -501,7 +516,9 @@ ProcedureCreate(const char *procedureName,
                                ereport(ERROR,
                                                (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
                                                 errmsg("cannot remove parameter defaults from existing function"),
-                                                errhint("Use DROP FUNCTION %s first.",
+                                                /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
+                                                errhint("Use %s %s first.",
+                                                                dropcmd,
                                                                 format_procedure(HeapTupleGetOid(oldtup)))));
 
                        proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup,
@@ -527,7 +544,9 @@ ProcedureCreate(const char *procedureName,
                                        ereport(ERROR,
                                                        (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
                                                         errmsg("cannot change data type of existing parameter default value"),
-                                                        errhint("Use DROP FUNCTION %s first.",
+                                                        /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
+                                                        errhint("Use %s %s first.",
+                                                                        dropcmd,
                                                                         format_procedure(HeapTupleGetOid(oldtup)))));
                                newlc = lnext(newlc);
                        }