From fb958b5da86da69651f6fb9f540c2cfb1346cdc5 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 2 Dec 2022 10:35:55 +0100 Subject: Generalize ri_RootToPartitionMap to use for non-partition children ri_RootToPartitionMap is currently only initialized for tuple routing target partitions, though a future commit will need the ability to use it even for the non-partition child tables, so make adjustments to the decouple it from the partitioning code. Also, make it lazily initialized via ExecGetRootToChildMap(), making that function its preferred access path. Existing third-party code accessing it directly should no longer do so; consequently, it's been renamed to ri_RootToChildMap, which also makes it consistent with ri_ChildToRootMap. ExecGetRootToChildMap() houses the logic of setting the map appropriately depending on whether a given child relation is partition or not. To support this, also add a separate entry point for TupleConversionMap creation that receives an AttrMap. No new code here, just split an existing function in two. Author: Amit Langote Discussion: https://postgr.es/m/CA+HiwqEYUhDXSK5BTvG_xk=eaAEJCD4GS3C6uH7ybBvv+Z_Tmg@mail.gmail.com --- src/backend/executor/execUtils.c | 57 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'src/backend/executor/execUtils.c') diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 9695de85b9a..572c87e4536 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -1253,6 +1253,45 @@ ExecGetChildToRootMap(ResultRelInfo *resultRelInfo) return resultRelInfo->ri_ChildToRootMap; } +/* + * Returns the map needed to convert given root result relation's tuples to + * the rowtype of the given child relation. Note that a NULL result is valid + * and means that no conversion is needed. + */ +TupleConversionMap * +ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate) +{ + /* Mustn't get called for a non-child result relation. */ + Assert(resultRelInfo->ri_RootResultRelInfo); + + /* If we didn't already do so, compute the map for this child. */ + if (!resultRelInfo->ri_RootToChildMapValid) + { + ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo; + TupleDesc indesc = RelationGetDescr(rootRelInfo->ri_RelationDesc); + TupleDesc outdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + Relation childrel = resultRelInfo->ri_RelationDesc; + AttrMap *attrMap; + MemoryContext oldcontext; + + /* + * When this child table is not a partition (!relispartition), it may + * have columns that are not present in the root table, which we ask + * to ignore by passing true for missing_ok. + */ + oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + attrMap = build_attrmap_by_name_if_req(indesc, outdesc, + !childrel->rd_rel->relispartition); + if (attrMap) + resultRelInfo->ri_RootToChildMap = + convert_tuples_by_name_attrmap(indesc, outdesc, attrMap); + MemoryContextSwitchTo(oldcontext); + resultRelInfo->ri_RootToChildMapValid = true; + } + + return resultRelInfo->ri_RootToChildMap; +} + /* Return a bitmap representing columns being inserted */ Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate) @@ -1273,10 +1312,10 @@ ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate) { ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate); - if (relinfo->ri_RootToPartitionMap != NULL) - return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, - rte->insertedCols); + if (map != NULL) + return execute_attr_map_cols(map->attrMap, rte->insertedCols); else return rte->insertedCols; } @@ -1307,10 +1346,10 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate) { ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate); - if (relinfo->ri_RootToPartitionMap != NULL) - return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, - rte->updatedCols); + if (map != NULL) + return execute_attr_map_cols(map->attrMap, rte->updatedCols); else return rte->updatedCols; } @@ -1333,10 +1372,10 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate) { ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + TupleConversionMap *map = ExecGetRootToChildMap(relinfo, estate); - if (relinfo->ri_RootToPartitionMap != NULL) - return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, - rte->extraUpdatedCols); + if (map != NULL) + return execute_attr_map_cols(map->attrMap, rte->extraUpdatedCols); else return rte->extraUpdatedCols; } -- cgit v1.2.3