diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index a0d8259663..09d16f4509 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -327,37 +327,6 @@ ExecInsert(ModifyTableState *mtstate, if (mtstate->mt_partition_dispatch_info) { int leaf_part_index; - ResultRelInfo *rootResultRelInfo; - - /* - * For UPDATE, the resultRelInfo is not the root partitioned table, so - * we should convert the tuple into root's tuple descriptor, since - * ExecFindPartition() starts the search from root. The tuple - * conversion map list is in the order of mtstate->resultRelInfo[], so - * to retrieve the one for this resultRel, we need to know the position - * of the resultRel in mtstate->resultRelInfo[]. - */ - if (mtstate->operation == CMD_UPDATE) - { - int map_index = resultRelInfo - mtstate->resultRelInfo; - TupleConversionMap *tupconv_map; - - Assert(mtstate->rootResultRelInfo != NULL); - rootResultRelInfo = mtstate->rootResultRelInfo; - - /* resultRelInfo must be one of the per-subplan result rels. */ - Assert(resultRelInfo >= mtstate->resultRelInfo && - resultRelInfo <= mtstate->resultRelInfo + mtstate->mt_nplans - 1); - - tupconv_map = tupconv_map_for_subplan(mtstate, map_index); - tuple = ConvertPartitionTupleSlot(mtstate, - tupconv_map, - tuple, - mtstate->mt_root_tuple_slot, - &slot); - } - else - rootResultRelInfo = resultRelInfo; /* * Away we go ... If we end up not finding a partition after all, @@ -367,7 +336,7 @@ ExecInsert(ModifyTableState *mtstate, * the ResultRelInfo and TupleConversionMap for the partition, * respectively. */ - leaf_part_index = ExecFindPartition(rootResultRelInfo, + leaf_part_index = ExecFindPartition(resultRelInfo, mtstate->mt_partition_dispatch_info, slot, estate); @@ -1178,6 +1147,8 @@ lreplace:; { bool tuple_deleted; TupleTableSlot *ret_slot; + TupleConversionMap *tupconv_map; + int subplan_off; /* * When an UPDATE is run with a leaf partition, we would not have @@ -1227,8 +1198,30 @@ lreplace:; if (mtstate->mt_transition_capture) saved_tcs_map = mtstate->mt_transition_capture->tcs_map; + + /* + * For UPDATE, the resultRelInfo is not the root partitioned + * table, so we should convert the tuple into root's tuple + * descriptor, since ExecInsert() starts the search from root. + */ + subplan_off = resultRelInfo - mtstate->resultRelInfo; + tupconv_map = tupconv_map_for_subplan(mtstate, subplan_off); + tuple = ConvertPartitionTupleSlot(mtstate, + tupconv_map, + tuple, + mtstate->mt_root_tuple_slot, + &slot); + + /* + * Make it look like to ExecInsert() that we are inserting the + * tuple into the root table. + */ + Assert(mtstate->rootResultRelInfo != NULL); + estate->es_result_relation_info = mtstate->rootResultRelInfo; ret_slot = ExecInsert(mtstate, slot, planSlot, NULL, ONCONFLICT_NONE, estate, canSetTag); + /* Restore for the next tuple. */ + estate->es_result_relation_info = resultRelInfo; if (mtstate->mt_transition_capture) {