@@ -375,6 +375,7 @@ ProcedureCreate(const char *procedureName,
375375Form_pg_proc oldproc = (Form_pg_proc ) GETSTRUCT (oldtup );
376376Datum proargnames ;
377377bool isnull ;
378+ const char * dropcmd ;
378379
379380if (!replace )
380381ereport (ERROR ,
@@ -400,16 +401,26 @@ ProcedureCreate(const char *procedureName,
400401 errdetail ("\"%s\" is a window function." , procedureName ) :
401402 0 )));
402403
404+ dropcmd = (prokind == PROKIND_PROCEDURE ? "DROP PROCEDURE" : "DROP FUNCTION" );
405+
403406/*
404407 * Not okay to change the return type of the existing proc, since
405408 * existing rules, views, etc may depend on the return type.
409+ *
410+ * In case of a procedure, a changing return type means that whether
411+ * the procedure has output parameters was changed. Since there is no
412+ * user visible return type, we produce a more specific error message.
406413 */
407414if (returnType != oldproc -> prorettype ||
408415returnsSet != oldproc -> proretset )
409416ereport (ERROR ,
410417(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
411- errmsg ("cannot change return type of existing function" ),
412- errhint ("Use DROP FUNCTION %s first." ,
418+ prokind == PROKIND_PROCEDURE
419+ ? errmsg ("cannot change whether a procedure has output parameters" )
420+ : errmsg ("cannot change return type of existing function" ),
421+ /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
422+ errhint ("Use %s %s first." ,
423+ dropcmd ,
413424 format_procedure (HeapTupleGetOid (oldtup )))));
414425
415426/*
@@ -434,7 +445,9 @@ ProcedureCreate(const char *procedureName,
434445(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
435446 errmsg ("cannot change return type of existing function" ),
436447 errdetail ("Row type defined by OUT parameters is different." ),
437- errhint ("Use DROP FUNCTION %s first." ,
448+ /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
449+ errhint ("Use %s %s first." ,
450+ dropcmd ,
438451 format_procedure (HeapTupleGetOid (oldtup )))));
439452}
440453
@@ -477,7 +490,9 @@ ProcedureCreate(const char *procedureName,
477490(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
478491 errmsg ("cannot change name of input parameter \"%s\"" ,
479492old_arg_names [j ]),
480- errhint ("Use DROP FUNCTION %s first." ,
493+ /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
494+ errhint ("Use %s %s first." ,
495+ dropcmd ,
481496 format_procedure (HeapTupleGetOid (oldtup )))));
482497}
483498}
@@ -501,7 +516,9 @@ ProcedureCreate(const char *procedureName,
501516ereport (ERROR ,
502517(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
503518 errmsg ("cannot remove parameter defaults from existing function" ),
504- errhint ("Use DROP FUNCTION %s first." ,
519+ /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
520+ errhint ("Use %s %s first." ,
521+ dropcmd ,
505522 format_procedure (HeapTupleGetOid (oldtup )))));
506523
507524proargdefaults = SysCacheGetAttr (PROCNAMEARGSNSP , oldtup ,
@@ -527,7 +544,9 @@ ProcedureCreate(const char *procedureName,
527544ereport (ERROR ,
528545(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
529546 errmsg ("cannot change data type of existing parameter default value" ),
530- errhint ("Use DROP FUNCTION %s first." ,
547+ /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
548+ errhint ("Use %s %s first." ,
549+ dropcmd ,
531550 format_procedure (HeapTupleGetOid (oldtup )))));
532551newlc = lnext (newlc );
533552}
0 commit comments