On Tue, 27 May 2025 10:03:58 +0800
jian he <jian.universal...@gmail.com> wrote:

> On Tue, May 27, 2025 at 1:35 AM Yugo Nagata <nag...@sraoss.co.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));
>     }

No. This cannot prevent the error "ERROR: tuple concurrently updated"
because it doesn't wait for end of the concurrently running session
if the lock cannot be acquired.

Regards,
Yugo Nagata

-- 
Yugo Nagata <nag...@sraoss.co.jp>


Reply via email to