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>