From 03ec63385251f31bdf95006258617d10eda94709 Mon Sep 17 00:00:00 2001 From: amit Date: Mon, 5 Feb 2018 13:38:05 +0900 Subject: [PATCH v24 1/2] Refactor partition tuple conversion maps handling code tupconv_map_for_subplan() currently assumes that it gets to use the Relation pointer for *all* leaf partitions. That is, both those that exist in mtstate->resultRelInfo array and those that don't and hence would be initialized by ExecSetupPartitionTupleRouting(). However, an upcoming patch will change ExecSetupPartitionTupleRouting such that leaf partitions' ResultRelInfo are no longer initialized there. So make it stop relying on the latter. --- src/backend/executor/execPartition.c | 87 ++++++++++++++++++++++++++-------- src/backend/executor/nodeModifyTable.c | 23 ++------- src/include/executor/execPartition.h | 2 + 3 files changed, 73 insertions(+), 39 deletions(-) diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 106a96d910..f2a920f4c3 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -373,40 +373,89 @@ ExecSetupChildParentMapForLeaf(PartitionTupleRouting *proute) } /* - * TupConvMapForLeaf -- Get the tuple conversion map for a given leaf partition - * index. + * ChildParentTupConvMap -- Return tuple conversion map to convert tuples of + * 'partrel' into those of 'rootrel' + * + * If the function was previously called for this partition, we would've + * either already created the map and stored the same at + * proute->child_parent_tupconv_maps[index] or found out that such a map + * is not needed and thus set proute->child_parent_map_not_required[index]. */ -TupleConversionMap * -TupConvMapForLeaf(PartitionTupleRouting *proute, - ResultRelInfo *rootRelInfo, int leaf_index) +static TupleConversionMap * +ChildParentTupConvMap(Relation partrel, Relation rootrel, + PartitionTupleRouting *proute, int index) { - ResultRelInfo **resultRelInfos = proute->partitions; - TupleConversionMap **map; - TupleDesc tupdesc; + TupleConversionMap *map; /* Don't call this if we're not supposed to be using this type of map. */ Assert(proute->child_parent_tupconv_maps != NULL); /* If it's already known that we don't need a map, return NULL. */ - if (proute->child_parent_map_not_required[leaf_index]) + if (proute->child_parent_map_not_required[index]) return NULL; /* If we've already got a map, return it. */ - map = &proute->child_parent_tupconv_maps[leaf_index]; - if (*map != NULL) - return *map; + map = proute->child_parent_tupconv_maps[index]; + if (map != NULL) + return map; /* No map yet; try to create one. */ - tupdesc = RelationGetDescr(resultRelInfos[leaf_index]->ri_RelationDesc); - *map = - convert_tuples_by_name(tupdesc, - RelationGetDescr(rootRelInfo->ri_RelationDesc), - gettext_noop("could not convert row type")); + map = convert_tuples_by_name(RelationGetDescr(partrel), + RelationGetDescr(rootrel), + gettext_noop("could not convert row type")); /* If it turns out no map is needed, remember for next time. */ - proute->child_parent_map_not_required[leaf_index] = (*map == NULL); + proute->child_parent_map_not_required[index] = (map == NULL); + + return map; +} + +/* + * TupConvMapForLeaf -- Get the tuple conversion map for a given leaf partition + * index. + * + * Call this only if it's known that the partition at leaf_index has been + * initialized. + */ +TupleConversionMap * +TupConvMapForLeaf(PartitionTupleRouting *proute, + ResultRelInfo *rootRelInfo, int leaf_index) +{ + ResultRelInfo **resultrels = proute->partitions; + + Assert(resultrels[leaf_index] != NULL); - return *map; + return ChildParentTupConvMap(resultrels[leaf_index]->ri_RelationDesc, + rootRelInfo->ri_RelationDesc, proute, + leaf_index); +} + +/* + * TupConvMapForSubplan -- Get the tuple conversion map for a partition given + * its subplan index. + * + * Call this if it's unclear whether the partition's ResultRelInfo has been + * initialized in mtstate->mt_partition_tuple_routing. + */ +TupleConversionMap * +TupConvMapForSubplan(ModifyTableState *mtstate, int subplan_index) +{ + int leaf_index; + PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; + ResultRelInfo *resultrels = mtstate->resultRelInfo, + *rootRelInfo = (mtstate->rootResultRelInfo != NULL) + ? mtstate->rootResultRelInfo + : mtstate->resultRelInfo; + + Assert(proute != NULL && + proute->subplan_partition_offsets != NULL && + subplan_index < proute->num_subplan_partition_offsets); + leaf_index = proute->subplan_partition_offsets[subplan_index]; + + Assert(subplan_index >= 0 && subplan_index < mtstate->mt_nplans); + return ChildParentTupConvMap(resultrels[subplan_index].ri_RelationDesc, + rootRelInfo->ri_RelationDesc, + proute, leaf_index); } /* diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 2a8ecbd830..d054da5330 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1804,27 +1804,10 @@ tupconv_map_for_subplan(ModifyTableState *mtstate, int whichplan) * array *only* if partition-indexed array is not required. */ if (mtstate->mt_per_subplan_tupconv_maps == NULL) - { - int leaf_index; - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - - /* - * If subplan-indexed array is NULL, things should have been arranged - * to convert the subplan index to partition index. - */ - Assert(proute && proute->subplan_partition_offsets != NULL && - whichplan < proute->num_subplan_partition_offsets); + return TupConvMapForSubplan(mtstate, whichplan); - leaf_index = proute->subplan_partition_offsets[whichplan]; - - return TupConvMapForLeaf(proute, getTargetResultRelInfo(mtstate), - leaf_index); - } - else - { - Assert(whichplan >= 0 && whichplan < mtstate->mt_nplans); - return mtstate->mt_per_subplan_tupconv_maps[whichplan]; - } + Assert(whichplan >= 0 && whichplan < mtstate->mt_nplans); + return mtstate->mt_per_subplan_tupconv_maps[whichplan]; } /* ---------------------------------------------------------------- diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h index 3df9c498bb..a75a37060a 100644 --- a/src/include/executor/execPartition.h +++ b/src/include/executor/execPartition.h @@ -112,6 +112,8 @@ extern int ExecFindPartition(ResultRelInfo *resultRelInfo, extern void ExecSetupChildParentMapForLeaf(PartitionTupleRouting *proute); extern TupleConversionMap *TupConvMapForLeaf(PartitionTupleRouting *proute, ResultRelInfo *rootRelInfo, int leaf_index); +extern TupleConversionMap *TupConvMapForSubplan(ModifyTableState *mtstate, + int subplan_index); extern HeapTuple ConvertPartitionTupleSlot(TupleConversionMap *map, HeapTuple tuple, TupleTableSlot *new_slot, -- 2.11.0