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 1viFPy-001Xqn-0J for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Jan 2026 17:21: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 1viFPw-0022sf-2o for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Jan 2026 17:21:25 +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 1viFPw-0022sH-1q for pgsql-bugs@lists.postgresql.org; Tue, 20 Jan 2026 17:21:24 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1viFPt-001SGr-1v for pgsql-bugs@lists.postgresql.org; Tue, 20 Jan 2026 17:21:24 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 60KHLKst1576969; Tue, 20 Jan 2026 12:21:20 -0500 From: Tom Lane To: Dean Rasheed cc: dwwoelfel@gmail.com, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #19380: Transition table in AFTER INSERT trigger misses rows from MERGE when used with INSERT in a CTE In-reply-to: References: <19380-4e293be2b4007248@postgresql.org> Comments: In-reply-to Dean Rasheed message dated "Tue, 20 Jan 2026 15:59:12 +0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1576967.1768929680.1@sss.pgh.pa.us> Date: Tue, 20 Jan 2026 12:21:20 -0500 Message-ID: <1576968.1768929680@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Dean Rasheed writes: > On Tue, 20 Jan 2026 at 08:58, PG Bug reporting form > wrote: >> In a CTE that inserts rows with both MERGE and INSERT, the transition table >> will not contain the rows from the MERGE. > It looks like the problem stems from this code in > MakeTransitionCaptureState() in commands/trigger.c: > table = GetAfterTriggersTableData(relid, cmdType); > where cmdType might be CMD_MERGE. > The problem is that MERGE really needs to use the same > AfterTriggersTableData structs as INSERT, UPDATE, and DELETE, so that > any captured tuples get added to the same tuplestores. Yeah, I had just come to the same conclusion when I saw your email. Using CMD_MERGE as the AfterTriggersTableData lookup key could be correct if MERGE were supposed to have separate transition tables, but AFAICT from the spec it isn't. > Attached is a rough patch doing that. I haven't read this in detail, but it seems like one issue to think about is whether it's okay to add fields to struct TransitionCaptureState in released branches? Although it's nominally an ABI break, I can't think of a reason why any extension would be manufacturing its own TransitionCaptureState structs rather than calling MakeTransitionCaptureState(), nor should an extension be touching the stated-to-be-private tcs_private field. So it seems like we should be able to get away with it. > I wonder if it would be possible to get rid of > ModifyTableState.mt_oc_transition_capture and just have INSERT ... ON > CONFLICT DO UPDATE use a single TransitionCaptureState in a similar > way to MERGE? Anyway, that's a separate idea, not relevant to this bug > fix. Yeah, that would have to be HEAD-only in any case; we're not going to change ModifyTableState in released branches. regards, tom lane