From: | jian he <jian(dot)universality(at)gmail(dot)com> |
---|---|
To: | Yugo Nagata <nagata(at)sraoss(dot)co(dot)jp> |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: Prevent internal error at concurrent CREATE OR REPLACE FUNCTION |
Date: | 2025-05-27 02:03:58 |
Message-ID: | CACJufxHrVuQhdLhzkcB_4ofo5AP256LLg10ptxxGe9YoJeQY2A@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Tue, May 27, 2025 at 1:35 AM Yugo Nagata <nagata(at)sraoss(dot)co(dot)jp> wrote:
>
> > + /* Lock the function so nobody else can do anything with it. */
> > + LockDatabaseObject(ProcedureRelationId, oldproc->oid, 0, AccessExclusiveLock);
> > +
> > + /*
> > + * It is possible that by the time we acquire the lock on function,
> > + * concurrent DDL has removed it. We can test this by checking the
> > + * existence of function. We get the tuple again to avoid the risk
> > + * of function definition getting changed.
> > + */
> > + oldtup = SearchSysCacheCopy3(PROCNAMEARGSNSP,
> > + PointerGetDatum(procedureName),
> > + PointerGetDatum(parameterTypes),
> > + ObjectIdGetDatum(procNamespace));
> >
> > we already called LockDatabaseObject, concurrent DDL can
> > not do DROP FUNCTION or ALTER FUNCTION.
> > so no need to call SearchSysCacheCopy3 again?
>
> The function may be dropped *before* we call LockDatabaseObject.
> SearchSysCacheCopy3 is called for check this.
> Plese see AlterPublication() as a similar code example.
>
I am wondering, can we do it the following way for v2-0001?
/* Check for pre-existing definition */
oldtup = SearchSysCacheCopy3(PROCNAMEARGSNSP,
PointerGetDatum(procedureName),
PointerGetDatum(parameterTypes),
ObjectIdGetDatum(procNamespace));
if (HeapTupleIsValid(oldtup))
{
/* There is one; okay to replace it? */
Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup);
if (!replace)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_FUNCTION),
errmsg("function \"%s\" already exists with same
argument types",
procedureName)));
/*
* It is possible that by the time we acquire the lock on function,
* concurrent DDL has removed it. We can test this by checking the
* existence of function. We get the tuple again to avoid the risk
* of function definition getting changed.
*/
if (!ConditionalLockDatabaseObject(ProcedureRelationId,
oldproc->oid, 0, AccessExclusiveLock))
oldtup = SearchSysCacheCopy3(PROCNAMEARGSNSP,
PointerGetDatum(procedureName),
PointerGetDatum(parameterTypes),
ObjectIdGetDatum(procNamespace));
}
From | Date | Subject | |
---|---|---|---|
Next Message | Quan Zongliang | 2025-05-27 03:06:46 | Standardize the definition of the subtype field of AlterDomainStmt |
Previous Message | Michael Paquier | 2025-05-27 00:58:34 | Re: queryId constant squashing does not support prepared statements |