@@ -72,7 +72,6 @@ static TupleTableSlot *ExecPrepareTupleRouting(ModifyTableState *mtstate,
7272 ResultRelInfo * targetRelInfo ,
7373 TupleTableSlot * slot ,
7474 ResultRelInfo * * partRelInfo );
75- static ResultRelInfo * getTargetResultRelInfo (ModifyTableState * node );
7675static void ExecSetupChildParentMapForSubplan (ModifyTableState * mtstate );
7776static TupleConversionMap * tupconv_map_for_subplan (ModifyTableState * node ,
7877 int whichplan );
@@ -1186,7 +1185,6 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate,
11861185 saved_tcs_map = mtstate -> mt_transition_capture -> tcs_map ;
11871186
11881187 /* Tuple routing starts from the root table. */
1189- Assert (mtstate -> rootResultRelInfo != NULL );
11901188 * inserted_tuple = ExecInsert (mtstate , mtstate -> rootResultRelInfo , slot ,
11911189 planSlot , estate , canSetTag );
11921190
@@ -1796,15 +1794,7 @@ static void
17961794fireBSTriggers (ModifyTableState * node )
17971795{
17981796 ModifyTable * plan = (ModifyTable * ) node -> ps .plan ;
1799- ResultRelInfo * resultRelInfo = node -> resultRelInfo ;
1800-
1801- /*
1802- * If the node modifies a partitioned table, we must fire its triggers.
1803- * Note that in that case, node->resultRelInfo points to the first leaf
1804- * partition, not the root table.
1805- */
1806- if (node -> rootResultRelInfo != NULL )
1807- resultRelInfo = node -> rootResultRelInfo ;
1797+ ResultRelInfo * resultRelInfo = node -> rootResultRelInfo ;
18081798
18091799 switch (node -> operation )
18101800 {
@@ -1826,36 +1816,14 @@ fireBSTriggers(ModifyTableState *node)
18261816 }
18271817}
18281818
1829- /*
1830- * Return the target rel ResultRelInfo.
1831- *
1832- * This relation is the same as :
1833- * - the relation for which we will fire AFTER STATEMENT triggers.
1834- * - the relation into whose tuple format all captured transition tuples must
1835- * be converted.
1836- * - the root partitioned table.
1837- */
1838- static ResultRelInfo *
1839- getTargetResultRelInfo (ModifyTableState * node )
1840- {
1841- /*
1842- * Note that if the node modifies a partitioned table, node->resultRelInfo
1843- * points to the first leaf partition, not the root table.
1844- */
1845- if (node -> rootResultRelInfo != NULL )
1846- return node -> rootResultRelInfo ;
1847- else
1848- return node -> resultRelInfo ;
1849- }
1850-
18511819/*
18521820 * Process AFTER EACH STATEMENT triggers
18531821 */
18541822static void
18551823fireASTriggers (ModifyTableState * node )
18561824{
18571825 ModifyTable * plan = (ModifyTable * ) node -> ps .plan ;
1858- ResultRelInfo * resultRelInfo = getTargetResultRelInfo ( node ) ;
1826+ ResultRelInfo * resultRelInfo = node -> rootResultRelInfo ;
18591827
18601828 switch (node -> operation )
18611829 {
@@ -1889,7 +1857,7 @@ static void
18891857ExecSetupTransitionCaptureState (ModifyTableState * mtstate , EState * estate )
18901858{
18911859 ModifyTable * plan = (ModifyTable * ) mtstate -> ps .plan ;
1892- ResultRelInfo * targetRelInfo = getTargetResultRelInfo ( mtstate ) ;
1860+ ResultRelInfo * targetRelInfo = mtstate -> rootResultRelInfo ;
18931861
18941862 /* Check for transition tables on the directly targeted relation. */
18951863 mtstate -> mt_transition_capture =
@@ -2019,7 +1987,7 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
20191987static void
20201988ExecSetupChildParentMapForSubplan (ModifyTableState * mtstate )
20211989{
2022- ResultRelInfo * targetRelInfo = getTargetResultRelInfo ( mtstate ) ;
1990+ ResultRelInfo * targetRelInfo = mtstate -> rootResultRelInfo ;
20231991 ResultRelInfo * resultRelInfos = mtstate -> resultRelInfo ;
20241992 TupleDesc outdesc ;
20251993 int numResultRelInfos = mtstate -> mt_nplans ;
@@ -2355,13 +2323,31 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
23552323 palloc (nplans * sizeof (ResultRelInfo ));
23562324 mtstate -> mt_scans = (TupleTableSlot * * ) palloc0 (sizeof (TupleTableSlot * ) * nplans );
23572325
2358- /* If modifying a partitioned table, initialize the root table info */
2326+ /*----------
2327+ * Resolve the target relation. This is the same as:
2328+ *
2329+ * - the relation for which we will fire FOR STATEMENT triggers,
2330+ * - the relation into whose tuple format all captured transition tuples
2331+ * must be converted, and
2332+ * - the root partitioned table used for tuple routing.
2333+ *
2334+ * If it's a partitioned table, the root partition doesn't appear
2335+ * elsewhere in the plan and its RT index is given explicitly in
2336+ * node->rootRelation. Otherwise (i.e. table inheritance) the target
2337+ * relation is the first relation in the node->resultRelations list, and
2338+ * we will initialize it in the loop below.
2339+ *----------
2340+ */
23592341 if (node -> rootRelation > 0 )
23602342 {
23612343 mtstate -> rootResultRelInfo = makeNode (ResultRelInfo );
23622344 ExecInitResultRelation (estate , mtstate -> rootResultRelInfo ,
23632345 node -> rootRelation );
23642346 }
2347+ else
2348+ {
2349+ mtstate -> rootResultRelInfo = mtstate -> resultRelInfo ;
2350+ }
23652351
23662352 mtstate -> mt_arowmarks = (List * * ) palloc0 (sizeof (List * ) * nplans );
23672353 mtstate -> mt_nplans = nplans ;
@@ -2446,7 +2432,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
24462432 }
24472433
24482434 /* Get the target relation */
2449- rel = ( getTargetResultRelInfo ( mtstate )) -> ri_RelationDesc ;
2435+ rel = mtstate -> rootResultRelInfo -> ri_RelationDesc ;
24502436
24512437 /*
24522438 * If it's not a partitioned table after all, UPDATE tuple routing should
0 commit comments