Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w8CyW-000JCK-01 for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Apr 2026 08:00:24 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w8CyT-004WNL-1x for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Apr 2026 08:00:22 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w8CyT-004WND-0d for pgsql-hackers@lists.postgresql.org; Thu, 02 Apr 2026 08:00:21 +0000 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w8CyR-000000009Js-1AsU for pgsql-hackers@postgresql.org; Thu, 02 Apr 2026 08:00:20 +0000 Received: by mail-pg1-x52f.google.com with SMTP id 41be03b00d2f7-c76b070f109so361429a12.0 for ; Thu, 02 Apr 2026 01:00:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775116818; x=1775721618; darn=postgresql.org; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=f7mzymniH8zLrtgZyIbT9JwAv0ygfzTN4vjb3WH43jU=; b=PDl5kt7kZ/9ewydS1WZJxCXrzyRr+iQkK/OOgYb6F8LKWhDYYt8aLXZ85KaQAsqC62 IxylqVcGW3OUzJCcG7f+8aXu7XeKsur7fe2UUR7Mi2OgnAiGZoo3i9mQtQCB1dmlshbc 1z+kQFXLcBpi86iDwWQ02RerQV0s3muzJReLk+fYEX/cNWQwexQzYx1kqmEb1ofB7/db UPkj9MdgNGJqoQ65qBVkHt4G7WxqRh+5Lh0JFdo9jkWR/1lAVrD+HshSg6VhoeV4mSDz VJe1mpiRmB+D0LZMZrTuQGMv62uy4EG+BNvNmBDlttzaX8n3IzyRarGtM0TS1BMwMcsC 5Ntw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775116818; x=1775721618; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=f7mzymniH8zLrtgZyIbT9JwAv0ygfzTN4vjb3WH43jU=; b=ZytmS9ii6Gxkn/49oC38n4Thi9Ubnx9xR0ECq1rG7bat5aPw06GdkpHgIVnJtUNdCS sSm7K9PmZvEQM+rYnSuT/LyGLwzSTB09IyzwjCrhrZ0vb22GrEj74cCie7pc5H1Aviui I/o2pfBAiGBPLNKGj9i+Psy9iPTAyQSvWHMriGXAl4DOjk/FYTao3EKvnKgUxmScWyY0 FNnGF5+7H99MrKv6HlNtYANufYuXr18UkWw2yZWytDxpsF8ChxiMPdI5tY35LHC0QCDV L8sAdgiZJT8nDuUTlYVelhwcSYGe1A+WXJYshUgy29zIyUOUQ6EsMeescdDO/f6DFeIj VMpQ== X-Forwarded-Encrypted: i=1; AJvYcCUjHYBcGYO3PHzFdu2Y3z3lhIyo+w+LsdpdmGTxKOeULoly1lBb3j5WfkcpPkJgqg9LcXvKN2Ab8sRmkMsr@postgresql.org X-Gm-Message-State: AOJu0YyLQmkZXEM/Deux4jJ6/UwmkglOjOUN5HsCVwG8hqPG/qF8h7di ygCYhOK2r+qDu60bVUmMKZJgr13DSg/tog36auvTcxZrVS7QbjIqLpik X-Gm-Gg: AeBDietGIizRjW9k3Aq5dR6wf5ajhP2IbiAL/P8FLHjs3uOR05cwVQix1Z3WfwutW95 LmwYrJkJl6JJU+VuIWt3o5MOmfX62MU68/0HjuF+bfdYBRF1R0UaIHtb6EPdAlMREUtoQmQZbO7 xdCAhIbdLTLrIKkRoXtBvq2PP3ZPe41vtmCpjbIhr17uv/RUB95dxxbTdbe4U3Ilw6P2Z5+ABD1 OW5DiaqS0ljJBup/THfMBalia/+A3EtppjsR576C6o8oDC5k+MOpxwf5sOEAwQ4AHK2ZiZ2GYh/ ocqP5nDyClXx9iIBbSBzG6HeD4lY4gjXdOZ8Q8I7MM0U4FGfxrLUzEsSFjbojWUQRY+MY5WZ8Ts uZZa3rrkiKIj0uB4h+8fdWlmz/mcEix8WV1FNQz8qB0LcksTA9KaNZsF4JaDrrDV7X27ikNnxvU okN1PU7d7WzWmvJA1AP1w+VoxGh3CZxEY= X-Received: by 2002:a17:903:38c7:b0:2b2:4a9a:b168 with SMTP id d9443c01a7336-2b269aa545cmr65737485ad.11.1775116817311; Thu, 02 Apr 2026 01:00:17 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b2749a3af9sm18276435ad.63.2026.04.02.01.00.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Apr 2026 01:00:16 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3 From: Chao Li In-Reply-To: Date: Thu, 2 Apr 2026 15:59:37 +0800 Cc: Junwang Zhao , Haibo Yan , Pavel Stehule , PostgreSQL-development , Tomas Vondra Content-Transfer-Encoding: quoted-printable Message-Id: References: <2BE661BA-D909-4093-BF78-DB9B0C099337@gmail.com> <77FA04FE-1F84-4DA1-8855-8BBFD8CC889A@gmail.com> To: Amit Langote X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > On Apr 2, 2026, at 15:41, Amit Langote = wrote: >=20 > On Wed, Apr 1, 2026 at 9:18=E2=80=AFPM Amit Langote = wrote: >> On Wed, Apr 1, 2026 at 8:56=E2=80=AFPM Junwang Zhao = wrote: >>> On Wed, Apr 1, 2026 at 5:51=E2=80=AFPM Amit Langote = wrote: >>>>=20 >>>> On Wed, Apr 1, 2026 at 5:51=E2=80=AFPM Amit Langote = wrote: >>>>> On Wed, Apr 1, 2026 at 12:54=E2=80=AFAM Junwang Zhao = wrote: >>>>>> + if (riinfo->fpmeta =3D=3D NULL) >>>>>> + { >>>>>> + /* Reload to ensure it's valid. */ >>>>>> + riinfo =3D = ri_LoadConstraintInfo(riinfo->constraint_id); >>>>>>=20 >>>>>> I was thinking of wrapping the reload in a conditional check like >>>>>> `!riinfo->valid`, since `riinfo` can be valid even when `fpmeta = =3D=3D NULL`. >>>>>> However, `if (riinfo->fpmeta =3D=3D NULL)` should rarely be = true, so the >>>>>> unconditional reload is harmless, and the code is cleaner. >>>>>>=20 >>>>>> +1 to the fix. >>>>>=20 >>>>> Thanks for checking. >>>>>=20 >>>>> I have just pushed a slightly modified version of that. >>>>>=20 >>>>>>> 0002 is the rebased batching patch. >>>>>>=20 >>>>>> The change of RI_FastPathEntry from storing riinfo to fk_relid >>>>>> makes sense to me. I'll do another review on 0002 tomorrow. >>>>>=20 >>>>> Here's another version. >>>>>=20 >>>>> This time, I have another fixup patch (0001) to make FastPathMeta >>>>> self-contained by copying the FmgrInfo structs it needs out of >>>>> RI_CompareHashEntry rather than storing pointers into it. This = avoids >>>>> any dependency on those cache entries remaining stable. I'll push >>>>> that once the just committed patch has seen enough BF animals. >>>>=20 >>>> Pushed. >>>>=20 >>>>> 0002 is rebased over that. >>>>=20 >>>> Rebased again. >>>=20 >>> +static void >>> +ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel) >>> +{ >>> + /* Reload; may have been invalidated since last batch = accumulation. */ >>> + const RI_ConstraintInfo *riinfo =3D = ri_LoadConstraintInfo(fpentry->conoid); >>>=20 >>> ... >>> + if (riinfo->fpmeta =3D=3D NULL) >>> + { >>> + /* Reload to ensure it's valid. */ >>> + riinfo =3D ri_LoadConstraintInfo(riinfo->constraint_id); >>> + ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo, >>> + fk_rel, idx_rel); >>> + } >>>=20 >>> ri_LoadConstraintInfo is currently invoked twice within >>> ri_FastPathBatchFlush. Should we eliminate the second call? >>=20 >> I think we can't because the entry may be stale by the time we get to >> the ri_populate_fastpath_metadata() call due to intervening steps; >> even something as benign-looking index_beginscan() may call code = paths >> that can trigger invalidation in rare cases. Maybe predictably in >> CLOBBER_CACHE_ALWAYS builds. >>=20 >>> Alternatively, we could refactor ri_FastPathBatchFlush to accept >>> an additional parameter, `const RI_ConstraintInfo *riinfo`, so we >>> can remove the need for the first call. In that case, we need to = call >>> ri_LoadConstraintInfo in ri_FastPathEndBatch. >>=20 >> Yeah, I think that's fine. Done that way in the attached. >>=20 >> Also, I realized that we could do: >>=20 >> @@ -2937,7 +2937,7 @@ ri_FastPathBatchFlush(RI_FastPathEntry = *fpentry, >> Relation fk_rel) >> fk_rel, idx_rel); >> } >> Assert(riinfo->fpmeta); >> - if (riinfo->nkeys =3D=3D 1) >> + if (riinfo->nkeys =3D=3D 1 && fpentry->batch_count > 1) >> violation_index =3D ri_FastPathFlushArray(fpentry, fk_slot, = riinfo, >> fk_rel, snapshot, = scandesc); >>=20 >> so that the fixed overhead of ri_FastPathFlushArray (allocating >> matched[] array on stack and constructing ArrayType, etc.) is not = paid >> unnecessarily for single-row batches. >=20 > There's another case in which it is not ok to use FlushArray and that > is if the index AM's amsearcharray is false (should be true in all > cases because the unique index used for PK is always btree). Added an > Assert to that effect next to where SK_SEARCHARRAY is set in > ri_FastPathFlushArray rather than a runtime check in the dispatch > condition. >=20 > Patch updated. Also added a comment about invalidation requirement or > lack thereof for RI_FastPathEntry, rename AfterTriggerBatchIsActive() > to simply AfterTriggerIsActive(), fixed the comments in trigger.h > describing the callback mechanism. >=20 > Will push tomorrow morning (Friday) barring objections. >=20 > --=20 > Thanks, Amit Langote > With a quick eyeball review, I found a typo: ``` + * relcache invalidation. The entry itself is torn down at batch at = batch end ``` There are two =E2=80=9Cat batch=E2=80=9D. I plan to spend time testing and tracing this patch tomorrow. But I = don=E2=80=99t want to block your progress, if I find anything, I will = report to you. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/