Skip to content

Commit d83423d

Browse files
committed
Improve error messages for CREATE OR REPLACE PROCEDURE
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>
1 parent 4718326 commit d83423d

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

src/backend/catalog/pg_proc.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)