From fb5883da86154c3126264bfd97b0cd6f293bcebd Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 19 Oct 2020 14:11:57 +0300 Subject: [PATCH] Remove PartitionRoutingInfo struct. The extra indirection neeeded to access its members via its enclosing ResultRelInfo seems pointless. Move all the fields from PartitionRoutingInfo to ResultRelInfo. Author: Amit Langote Reviewed-by: Alvaro Herrera Discussion: https://www.postgresql.org/message-id/CA%2BHiwqFViT47Zbr_ASBejiK7iDG8%3DQ1swQ-tjM6caRPQ67pT%3Dw%40mail.gmail.com --- src/backend/commands/copy.c | 4 +-- src/backend/executor/execMain.c | 4 ++- src/backend/executor/execPartition.c | 34 ++++++++++++------------ src/backend/executor/nodeModifyTable.c | 21 +++++++-------- src/backend/replication/logical/worker.c | 11 +++----- src/include/executor/execPartition.h | 21 --------------- src/include/nodes/execnodes.h | 15 +++++++---- 7 files changed, 45 insertions(+), 65 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index b4ccd35ec18..36ddcdccdb8 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -3119,7 +3119,7 @@ CopyFrom(CopyState cstate) * We might need to convert from the root rowtype to the partition * rowtype. */ - map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap; + map = resultRelInfo->ri_RootToPartitionMap; if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert) { /* non batch insert */ @@ -3127,7 +3127,7 @@ CopyFrom(CopyState cstate) { TupleTableSlot *new_slot; - new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot; + new_slot = resultRelInfo->ri_PartitionTupleSlot; myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot); } } diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index fcdd4b35674..aea04794487 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1243,7 +1243,9 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_TrigOldSlot = NULL; resultRelInfo->ri_TrigNewSlot = NULL; resultRelInfo->ri_PartitionRoot = partition_root; - resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */ + resultRelInfo->ri_RootToPartitionMap = NULL; /* set by + * ExecInitRoutingInfo */ + resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */ resultRelInfo->ri_ChildToRootMap = NULL; resultRelInfo->ri_CopyMultiInsertBuffer = NULL; } diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 08f91e59a7a..86594bd0565 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -261,7 +261,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, * If the partition's ResultRelInfo does not yet exist in 'proute' then we set * one up or reuse one from mtstate's resultRelInfo array. When reusing a * ResultRelInfo from the mtstate we verify that the relation is a valid - * target for INSERTs and then set up a PartitionRoutingInfo for it. + * target for INSERTs and initialize tuple routing information. * * rootResultRelInfo is the relation named in the query. * @@ -307,6 +307,7 @@ ExecFindPartition(ModifyTableState *mtstate, while (dispatch != NULL) { int partidx = -1; + bool is_leaf; CHECK_FOR_INTERRUPTS(); @@ -346,8 +347,10 @@ ExecFindPartition(ModifyTableState *mtstate, errtable(rel))); } - if (partdesc->is_leaf[partidx]) + is_leaf = partdesc->is_leaf[partidx]; + if (is_leaf) { + /* * We've reached the leaf -- hurray, we're done. Look to see if * we've already got a ResultRelInfo for this partition. @@ -382,7 +385,10 @@ ExecFindPartition(ModifyTableState *mtstate, /* Verify this ResultRelInfo allows INSERTs */ CheckValidResultRel(rri, CMD_INSERT); - /* Set up the PartitionRoutingInfo for it */ + /* + * Initialize information needed to insert this and + * subsequent tuples routed to this partition. + */ ExecInitRoutingInfo(mtstate, estate, proute, dispatch, rri, partidx); } @@ -464,8 +470,6 @@ ExecFindPartition(ModifyTableState *mtstate, */ if (partidx == partdesc->boundinfo->default_index) { - PartitionRoutingInfo *partrouteinfo = rri->ri_PartitionInfo; - /* * The tuple must match the partition's layout for the constraint * expression to be evaluated successfully. If the partition is @@ -478,13 +482,13 @@ ExecFindPartition(ModifyTableState *mtstate, * So if we have to convert, do it from the root slot; if not, use * the root slot as-is. */ - if (partrouteinfo) + if (is_leaf) { - TupleConversionMap *map = partrouteinfo->pi_RootToPartitionMap; + TupleConversionMap *map = rri->ri_RootToPartitionMap; if (map) slot = execute_attr_map_slot(map->attrMap, rootslot, - partrouteinfo->pi_PartitionTupleSlot); + rri->ri_PartitionTupleSlot); else slot = rootslot; } @@ -788,7 +792,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, { TupleConversionMap *map; - map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap; + map = leaf_part_rri->ri_RootToPartitionMap; Assert(node->onConflictSet != NIL); Assert(rootResultRelInfo->ri_onConflict != NULL); @@ -949,18 +953,15 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, int partidx) { MemoryContext oldcxt; - PartitionRoutingInfo *partrouteinfo; int rri_index; oldcxt = MemoryContextSwitchTo(proute->memcxt); - partrouteinfo = palloc(sizeof(PartitionRoutingInfo)); - /* * Set up a tuple conversion map to convert a tuple routed to the * partition from the parent's type to the partition's. */ - partrouteinfo->pi_RootToPartitionMap = + partRelInfo->ri_RootToPartitionMap = convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), RelationGetDescr(partRelInfo->ri_RelationDesc)); @@ -970,7 +971,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * for various operations that are applied to tuples after routing, such * as checking constraints. */ - if (partrouteinfo->pi_RootToPartitionMap != NULL) + if (partRelInfo->ri_RootToPartitionMap != NULL) { Relation partrel = partRelInfo->ri_RelationDesc; @@ -979,11 +980,11 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * partition's TupleDesc; TupleDesc reference will be released at the * end of the command. */ - partrouteinfo->pi_PartitionTupleSlot = + partRelInfo->ri_PartitionTupleSlot = table_slot_create(partrel, &estate->es_tupleTable); } else - partrouteinfo->pi_PartitionTupleSlot = NULL; + partRelInfo->ri_PartitionTupleSlot = NULL; /* * If the partition is a foreign table, let the FDW init itself for @@ -993,7 +994,6 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, partRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL) partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo); - partRelInfo->ri_PartitionInfo = partrouteinfo; partRelInfo->ri_CopyMultiInsertBuffer = NULL; /* diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 5f85fd7cd88..a33423c896e 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1172,8 +1172,8 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate, planSlot, estate, canSetTag); /* - * Reset the transition state that may possibly have been written - * by INSERT. + * Reset the transition state that may possibly have been written by + * INSERT. */ if (mtstate->mt_transition_capture) mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; @@ -1874,7 +1874,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, ResultRelInfo **partRelInfo) { ResultRelInfo *partrel; - PartitionRoutingInfo *partrouteinfo; TupleConversionMap *map; /* @@ -1885,8 +1884,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, * UPDATE to another partition becomes a DELETE+INSERT. */ partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate); - partrouteinfo = partrel->ri_PartitionInfo; - Assert(partrouteinfo != NULL); /* * If we're capturing transition tuples, we might need to convert from the @@ -1909,10 +1906,10 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, /* * Convert the tuple, if necessary. */ - map = partrouteinfo->pi_RootToPartitionMap; + map = partrel->ri_RootToPartitionMap; if (map != NULL) { - TupleTableSlot *new_slot = partrouteinfo->pi_PartitionTupleSlot; + TupleTableSlot *new_slot = partrel->ri_PartitionTupleSlot; slot = execute_attr_map_slot(map->attrMap, slot, new_slot); } @@ -2327,8 +2324,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * to the format of the table mentioned in the query (root relation). * It's needed for update tuple routing, because the routing starts * from the root relation. It's also needed for capturing transition - * tuples, because the transition tuple store can only store tuples - * in the root table format. + * tuples, because the transition tuple store can only store tuples in + * the root table format. * * For INSERT, the map is only initialized for a given partition when * the partition itself is first initialized by ExecFindPartition(). @@ -2363,9 +2360,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ExecSetupPartitionTupleRouting(estate, mtstate, rel); /* - * For update row movement we'll need a dedicated slot to store the - * tuples that have been converted from partition format to the root - * table format. + * For update row movement we'll need a dedicated slot to store the tuples + * that have been converted from partition format to the root table + * format. */ if (update_tuple_routing_needed) mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL); diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index b8e297c5d34..3a5b733ee38 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -1572,7 +1572,6 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, ResultRelInfo *partrelinfo; Relation partrel; TupleTableSlot *remoteslot_part; - PartitionRoutingInfo *partinfo; TupleConversionMap *map; MemoryContext oldctx; @@ -1599,11 +1598,10 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, * partition's rowtype. Convert if needed or just copy, using a dedicated * slot to store the tuple in any case. */ - partinfo = partrelinfo->ri_PartitionInfo; - remoteslot_part = partinfo->pi_PartitionTupleSlot; + remoteslot_part = partrelinfo->ri_PartitionTupleSlot; if (remoteslot_part == NULL) remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable); - map = partinfo->pi_RootToPartitionMap; + map = partrelinfo->ri_RootToPartitionMap; if (map != NULL) remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot, remoteslot_part); @@ -1748,12 +1746,11 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); partrel = partrelinfo_new->ri_RelationDesc; - partinfo = partrelinfo_new->ri_PartitionInfo; - remoteslot_part = partinfo->pi_PartitionTupleSlot; + remoteslot_part = partrelinfo_new->ri_PartitionTupleSlot; if (remoteslot_part == NULL) remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable); - map = partinfo->pi_RootToPartitionMap; + map = partrelinfo_new->ri_RootToPartitionMap; if (map != NULL) { remoteslot_part = execute_attr_map_slot(map->attrMap, diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h index 74c39911b2a..473c4cd84fc 100644 --- a/src/include/executor/execPartition.h +++ b/src/include/executor/execPartition.h @@ -22,27 +22,6 @@ typedef struct PartitionDispatchData *PartitionDispatch; typedef struct PartitionTupleRouting PartitionTupleRouting; -/* - * PartitionRoutingInfo - * - * Additional result relation information specific to routing tuples to a - * table partition. - */ -typedef struct PartitionRoutingInfo -{ - /* - * Map for converting tuples in root partitioned table format into - * partition format, or NULL if no conversion is required. - */ - TupleConversionMap *pi_RootToPartitionMap; - - /* - * Slot to store tuples in partition format, or NULL when no translation - * is required between root and partition. - */ - TupleTableSlot *pi_PartitionTupleSlot; -} PartitionRoutingInfo; - /* * PartitionedRelPruningData - Per-partitioned-table data for run-time pruning * of partitions. For a multilevel partitioned table, we have one of these diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 46789cb0070..6c0a7d68d61 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -33,7 +33,6 @@ #include "utils/tuplestore.h" struct PlanState; /* forward references in this file */ -struct PartitionRoutingInfo; struct ParallelHashJoinState; struct ExecRowMark; struct ExprState; @@ -480,11 +479,17 @@ typedef struct ResultRelInfo /* partition check expression state (NULL if not set up yet) */ ExprState *ri_PartitionCheckExpr; - /* relation descriptor for partitioned table's root, if any */ + /* + * Information needed by tuple routing target relations + * + * PartitionRoot gives the target relation mentioned in the query. + * RootToPartitionMap and PartitionTupleSlot, initialized by + * ExecInitRoutingInfo, are non-NULL if partition has a different tuple + * format than the root table. + */ Relation ri_PartitionRoot; - - /* info for partition tuple routing (NULL if not set up yet) */ - struct PartitionRoutingInfo *ri_PartitionInfo; + TupleConversionMap *ri_RootToPartitionMap; + TupleTableSlot *ri_PartitionTupleSlot; /* * Map to convert child result relation tuples to the format of the table -- 2.30.2