|
61 | 61 | #include "parser/parse_func.h" |
62 | 62 | #include "parser/parse_type.h" |
63 | 63 | #include "pgstat.h" |
| 64 | +#include "storage/lmgr.h" |
64 | 65 | #include "tcop/pquery.h" |
65 | 66 | #include "tcop/utility.h" |
66 | 67 | #include "utils/acl.h" |
@@ -1383,9 +1384,21 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) |
1383 | 1384 |
|
1384 | 1385 | ObjectAddressSet(address, ProcedureRelationId, funcOid); |
1385 | 1386 |
|
| 1387 | + /* Lock the function so nobody else can do anything with it. */ |
| 1388 | + LockDatabaseObject(ProcedureRelationId, funcOid, 0, AccessExclusiveLock); |
| 1389 | + |
| 1390 | + /* |
| 1391 | + * It is possible that by the time we acquire the lock on function, |
| 1392 | + * concurrent DDL has removed it. We can test this by checking the |
| 1393 | + * existence of function. We get the tuple again to avoid the risk |
| 1394 | + * of function definition getting changed. |
| 1395 | + */ |
1386 | 1396 | tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid)); |
1387 | | - if (!HeapTupleIsValid(tup)) /* should not happen */ |
1388 | | - elog(ERROR, "cache lookup failed for function %u", funcOid); |
| 1397 | + if (!HeapTupleIsValid(tup)) |
| 1398 | + ereport(ERROR, |
| 1399 | + errcode(ERRCODE_UNDEFINED_OBJECT), |
| 1400 | + errmsg("function \"%s\" does not exist", |
| 1401 | + NameListToString(stmt->func->objname))); |
1389 | 1402 |
|
1390 | 1403 | procForm = (Form_pg_proc) GETSTRUCT(tup); |
1391 | 1404 |
|
|
0 commit comments