Re: Segfault in RI UPDATE CASCADE on partitioned tables with LIKE+ATTACH child (attnum drift)
amit <amitlangote09@gmail.com>
From: Amit Langote <amitlangote09@gmail.com>
To: David Rowley <dgrowleyml@gmail.com>
Cc: Dmitry Fomin <fomin.list@gmail.com>, pgsql-bugs@lists.postgresql.org
Date: 2025-10-17T10:36:43Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix incorrect logic for caching ResultRelInfos for triggers
- 2992b9a07ef0 15.15 landed
- a546964db6fb 16.11 landed
- 0d3074615380 17.7 landed
- a2387c32f2f8 18.1 landed
- 39dcfda2d23a 19 (unreleased) landed
On Fri, Oct 17, 2025 at 6:08 PM David Rowley <dgrowleyml@gmail.com> wrote: > On Fri, 17 Oct 2025 at 14:21, David Rowley <dgrowleyml@gmail.com> wrote: > > Thanks for the detailed report. It seems to have been caused by > > ba9a7e3921. For some reason the ResultRelInfo.ri_RootResultRelInfo > > isn't set for this partition which causes ExecGetChildToRootMap() to > > think no translation is required. > > The problem is with the ResultRelInfo caching that's in > ExecGetTriggerResultRel(). The code there tries looking into the > estate's es_opened_result_relations, es_tuple_routing_result_relations > and es_trig_target_relations Lists to see if the ResultRelInfo was > created before. In the problem case the ResultRelInfo is found in > es_trig_target_relations and unfortunately it's been set up by some > code in afterTriggerInvokeEvents() which passes a NULL rootRelInfo. > This means when ExecGetTriggerResultRel() is called again this time > passing the correct rootRelInfo, the cached one that has the NULL > ri_RootResultRelInfo is found and returned. > > This results in the ExecGetChildToRootMap() code doing the wrong thing > because it sees a NULL ri_RootResultRelInfo therefore does not > translate the slot into the slow format of the partitioned table. > > I've attached a patch which fixes the problem. I'm just not sure if > it's the right fix for the problem. I suspect the real problem is down > to the fact that ExecGetTriggerResultRel() passes a NULL rootRelInfo > in the first place. I just don't see a good way to figure out what the > parent table should be so we know to create a parent ResultRelInfo as > the trigger that is firing is for the partition, not the partitioned > table. I don't see any way to figure out that the trigger is being > fired because it's cascading an update of its parent partitioned > table... At a guess, it feels like there might be some fields missing > in AfterTriggerShared to figure this out. > > Any thoughts on this Amit? Thanks for the off-list heads-up, David. I'll need to play around with Dmitry's test case a bit before I can be sure, but I agree with your suspicion -- something's not right if a result rel without a root rel set ends up in a path where tuple conversion matters. -- Thanks, Amit Langote