@@ -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,
400401errdetail ("\"%s\" is a window function." ,procedureName ) :
4014020 )));
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 ,
413424format_procedure (HeapTupleGetOid (oldtup )))));
414425
415426/*
@@ -434,7 +445,9 @@ ProcedureCreate(const char *procedureName,
434445(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
435446errmsg ("cannot change return type of existing function" ),
436447errdetail ("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 ,
438451format_procedure (HeapTupleGetOid (oldtup )))));
439452}
440453
@@ -477,7 +490,9 @@ ProcedureCreate(const char *procedureName,
477490(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
478491errmsg ("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 ,
481496format_procedure (HeapTupleGetOid (oldtup )))));
482497}
483498}
@@ -501,7 +516,9 @@ ProcedureCreate(const char *procedureName,
501516ereport (ERROR ,
502517(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
503518errmsg ("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 ,
505522format_procedure (HeapTupleGetOid (oldtup )))));
506523
507524proargdefaults = SysCacheGetAttr (PROCNAMEARGSNSP ,oldtup ,
@@ -527,7 +544,9 @@ ProcedureCreate(const char *procedureName,
527544ereport (ERROR ,
528545(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
529546errmsg ("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 ,
531550format_procedure (HeapTupleGetOid (oldtup )))));
532551newlc = lnext (newlc );
533552}