@@ -375,6 +375,7 @@ ProcedureCreate(const char *procedureName,
375375 Form_pg_proc oldproc = (Form_pg_proc ) GETSTRUCT (oldtup );
376376 Datum proargnames ;
377377 bool isnull ;
378+ const char * dropcmd ;
378379
379380 if (!replace )
380381 ereport (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 */
407414 if (returnType != oldproc -> prorettype ||
408415 returnsSet != oldproc -> proretset )
409416 ereport (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\"" ,
479492 old_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,
501516 ereport (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
507524 proargdefaults = SysCacheGetAttr (PROCNAMEARGSNSP , oldtup ,
@@ -527,7 +544,9 @@ ProcedureCreate(const char *procedureName,
527544 ereport (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 )))));
532551 newlc = lnext (newlc );
533552 }
0 commit comments