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 1w8aME-000gBA-0B for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Apr 2026 08:58:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w8aMA-00AK5j-2a for pgsql-hackers@arkaria.postgresql.org; Fri, 03 Apr 2026 08:58:23 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w8aMA-00AK5a-1X for pgsql-hackers@lists.postgresql.org; Fri, 03 Apr 2026 08:58:22 +0000 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w8aM8-00000000LYF-184R for pgsql-hackers@postgresql.org; Fri, 03 Apr 2026 08:58:22 +0000 Received: by mail-pg1-x530.google.com with SMTP id 41be03b00d2f7-c76864f4e58so686615a12.1 for ; Fri, 03 Apr 2026 01:58:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775206699; x=1775811499; darn=postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=huOW9tQifaFv5/iYktFgcw/czdlYppdrj0lhQfsnR8w=; b=Oz+TvMt10GPzwzNY6x8FV48fhflZGtcFLSKgRMZv2nuDAVEEli6dk3KDK60nNTscMu NTxT3L/jUO0OZMVpdZ91EGW53H5aXUvKo4NesW9yvvAGROE8lwkfR5B94lbHy/ZfG+Ry Rvei2/vdnwG5yKgw+st3OUhoFQQ3WN5plLeU/doqGAcz3dpNMBKvoBqy9w/aqOfAGtkl eZyOgWWBpFZTlRVEfj56VPiSQuZTkpL3AVab1HmgbeLxcoR57EID7goSbGWQiUAI7Wcm VbvlIUJGf5lEuTrP6+ug6Cgh7m/9Lz9lQNfVePXxNDkIFgu2kYGe5shNZpOEJQ9/jWs6 AJyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775206699; x=1775811499; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=huOW9tQifaFv5/iYktFgcw/czdlYppdrj0lhQfsnR8w=; b=JLzPCo4qgQXUclioOWQHQYRM4q8iYjxbBVWovgtYAI091XDB2mQRKQiAKfaeqhbrjQ Q/VbHji11fGz9y+4iaHAEpDrEsVt1gD7KFr71MO5b0IfSGHXlK5P2OzHW2V9LlN+FrGh 6uYk/vOpq80VBPzAF2DQK8lmREBYHLMRDn7fuXBDY8tIayp8nvAeCwCz2Fg54qWgZW5u ryceytGP4cJLtiwq4w3wph7LQKedNQwwJB2CqgW0WFrKD58Fo/1SliTjyBMFfqTQ4WE9 h81Tj7nsYrIeCjP/T9WbvU0uP1OEGCsmNeZhgQGbrwjlCSeip0Xdy1aYm2rTRbbSIicI AxNg== X-Forwarded-Encrypted: i=1; AJvYcCVMprucFjbSFB13i+QrQ3+GCvkcFiNifhJzNeo+NPQj3rSM81Dcw+e4woXVhoqCYP4yWV44Pemr4GYMRDtG@postgresql.org X-Gm-Message-State: AOJu0Yy7Es/JK7CN0kQ3L4iO/cRxHCt/tXQthzKyLe5uKkxVIA0tj7ia by3kXkfi7Dd7MQgJmcxaeiVMWk7ZpAq3irtJAcGG6+Pn+yLxw3AVitFCs3m5GUW48s3FvA== X-Gm-Gg: ATEYQzxrWgK9fQ/bLcnbe9l9SOoO74vIVhFMds3xNwxJkZgYSOLpdPJFflTzNwWSN5g a72s7HXizcQ9WSC7Ig8GL/ZAP2EropLDgc6D2dtqdjae5nynqGKmKn0Oh7AsSYPnwLacHZV2OPu FsYetrsM1aFbL3bfSaa3VQiP2XpKf2dx5XaeKDkvX3oOgo50zJSlNIeADVSPx1exNL84I80xh1R S2NMnvzYRBpKdqzxJLQ2pdZAew3ySTFjA0yWNv+AbSgoIvipdGEr7hmtQRqP5vlzO6ECMXmMo9N OqehVy0ub5EDHKkjnUEmPlkCq1gjsq76+Gmiw8Wn/DcuR0G9dvcXtVvHAK5eBJ7x/sUeRserpc3 4EI96fOxCd4+9/20ypKJ0ADA+EmL0k8tgQFbbFIwYKjVFHR17SwtDtFN7cHbQb/LtYkhvdIrP7L cuG5IVgMe+hn5K7LPUkm2UH3vYH32ru5c= X-Received: by 2002:a05:6a21:3287:b0:39b:f0a1:1498 with SMTP id adf61e73a8af0-39f2f25f4b4mr2266593637.48.1775206698497; Fri, 03 Apr 2026 01:58:18 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c76c657e703sm4641914a12.22.2026.04.03.01.58.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Apr 2026 01:58:17 -0700 (PDT) From: Chao Li Message-Id: Content-Type: multipart/mixed; boundary="Apple-Mail=_952447D7-1125-4AEC-84E5-8C3185133ABA" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3 Date: Fri, 3 Apr 2026 16:57:36 +0800 In-Reply-To: Cc: Junwang Zhao , Haibo Yan , Pavel Stehule , PostgreSQL-development , Tomas Vondra To: Amit Langote References: <2BE661BA-D909-4093-BF78-DB9B0C099337@gmail.com> <77FA04FE-1F84-4DA1-8855-8BBFD8CC889A@gmail.com> X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_952447D7-1125-4AEC-84E5-8C3185133ABA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Apr 3, 2026, at 13:52, Amit Langote = wrote: >=20 > Hi, >=20 > On Thu, Apr 2, 2026 at 5:00=E2=80=AFPM Chao Li = wrote: >>> On Apr 2, 2026, at 15:41, Amit Langote = wrote: >>> Will push tomorrow morning (Friday) barring objections. >>> >>=20 >> With a quick eyeball review, I found a typo: >> ``` >> + * relcache invalidation. The entry itself is torn down at batch at = batch end >> ``` >>=20 >> There are two =E2=80=9Cat batch=E2=80=9D. >=20 > Thanks for spotting that. Fixed and pushed. >=20 >> 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. >=20 > Sure, I didn't want to leave committing this to the weekend or the = next week. >=20 > --=20 > Thanks, Amit Langote Hi Amit, I spent several hours debugging this patch today, and I found a problem = where the batch mode doesn't seem to handle deferred RI triggers, = although the commit message suggests that it should. I traced this scenario: ``` CREATE TABLE pk (a int primary key); CREATE TABLE fk (a int references pk(a) DEFERRABLE INITIALLY DEFERRED); BEGIN; INSERT INTO fk VALUES (1); INSERT INTO pk VALUES (1); COMMIT; ``` When COMMIT is executed, it reaches RI_FKey_check(), where = AfterTriggerIsActive() checks whether afterTriggers.query_depth >=3D 0. = But in the deferred case, afterTriggers.query_depth is -1. =46rom the code: ``` if (ri_fastpath_is_applicable(riinfo)) { if (AfterTriggerIsActive()) { /* Batched path: buffer and probe in groups */ ri_FastPathBatchAdd(riinfo, fk_rel, newslot); } else { /* ALTER TABLE validation: per-row, no cache */ ri_FastPathCheck(riinfo, fk_rel, newslot); } return PointerGetDatum(NULL); } ``` So this ends up falling back to the per-row path for deferred RI checks = at COMMIT, even though the intent here seems to be only to bypass the = ALTER TABLE validation case, where batch callbacks would never fire, and = MyTriggerDepth is 0. So, maybe we can just check MyTriggerDepth>0 in = AfterTriggerIsActive(). I tried the attached fix. With it, deferred triggers go through the = batch mode, and all existing tests still pass. But I am still new to PG = development, so I=E2=80=99m not sure whether I may have missed = something. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_952447D7-1125-4AEC-84E5-8C3185133ABA Content-Disposition: attachment; filename=fix_deferred_trigger.diff Content-Type: application/octet-stream; x-unix-mode=0644; name="fix_deferred_trigger.diff" Content-Transfer-Encoding: 7bit diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 90e94fb8a5a..63355ebb02f 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -6806,10 +6806,10 @@ RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback, * Allocate in TopTransactionContext so the item survives for the duration * of the batch, which may span multiple trigger invocations. * - * Must be called while afterTriggers is active (query_depth >= 0); + * Must be called while afterTriggers is active (MyTriggerDepth > 0); * callbacks registered outside a trigger-firing context would never fire. */ - Assert(afterTriggers.query_depth >= 0); + Assert(MyTriggerDepth > 0); oldcxt = MemoryContextSwitchTo(TopTransactionContext); item = palloc(sizeof(AfterTriggerCallbackItem)); item->callback = callback; @@ -6858,5 +6858,5 @@ FireAfterTriggerBatchCallbacks(void) bool AfterTriggerIsActive(void) { - return afterTriggers.query_depth >= 0; + return MyTriggerDepth > 0; } --Apple-Mail=_952447D7-1125-4AEC-84E5-8C3185133ABA--