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
This commit is contained in:
Heikki Linnakangas 2020-10-19 14:11:57 +03:00
parent 6973533650
commit fb5883da86
7 changed files with 45 additions and 65 deletions

View File

@ -3119,7 +3119,7 @@ CopyFrom(CopyState cstate)
* We might need to convert from the root rowtype to the partition * We might need to convert from the root rowtype to the partition
* rowtype. * rowtype.
*/ */
map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap; map = resultRelInfo->ri_RootToPartitionMap;
if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert) if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert)
{ {
/* non batch insert */ /* non batch insert */
@ -3127,7 +3127,7 @@ CopyFrom(CopyState cstate)
{ {
TupleTableSlot *new_slot; 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); myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
} }
} }

View File

@ -1243,7 +1243,9 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo->ri_TrigOldSlot = NULL; resultRelInfo->ri_TrigOldSlot = NULL;
resultRelInfo->ri_TrigNewSlot = NULL; resultRelInfo->ri_TrigNewSlot = NULL;
resultRelInfo->ri_PartitionRoot = partition_root; 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_ChildToRootMap = NULL;
resultRelInfo->ri_CopyMultiInsertBuffer = NULL; resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
} }

View File

@ -261,7 +261,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate,
* If the partition's ResultRelInfo does not yet exist in 'proute' then we set * 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 * 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 * 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. * rootResultRelInfo is the relation named in the query.
* *
@ -307,6 +307,7 @@ ExecFindPartition(ModifyTableState *mtstate,
while (dispatch != NULL) while (dispatch != NULL)
{ {
int partidx = -1; int partidx = -1;
bool is_leaf;
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
@ -346,8 +347,10 @@ ExecFindPartition(ModifyTableState *mtstate,
errtable(rel))); 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 reached the leaf -- hurray, we're done. Look to see if
* we've already got a ResultRelInfo for this partition. * we've already got a ResultRelInfo for this partition.
@ -382,7 +385,10 @@ ExecFindPartition(ModifyTableState *mtstate,
/* Verify this ResultRelInfo allows INSERTs */ /* Verify this ResultRelInfo allows INSERTs */
CheckValidResultRel(rri, CMD_INSERT); 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, ExecInitRoutingInfo(mtstate, estate, proute, dispatch,
rri, partidx); rri, partidx);
} }
@ -464,8 +470,6 @@ ExecFindPartition(ModifyTableState *mtstate,
*/ */
if (partidx == partdesc->boundinfo->default_index) if (partidx == partdesc->boundinfo->default_index)
{ {
PartitionRoutingInfo *partrouteinfo = rri->ri_PartitionInfo;
/* /*
* The tuple must match the partition's layout for the constraint * The tuple must match the partition's layout for the constraint
* expression to be evaluated successfully. If the partition is * 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 * So if we have to convert, do it from the root slot; if not, use
* the root slot as-is. * the root slot as-is.
*/ */
if (partrouteinfo) if (is_leaf)
{ {
TupleConversionMap *map = partrouteinfo->pi_RootToPartitionMap; TupleConversionMap *map = rri->ri_RootToPartitionMap;
if (map) if (map)
slot = execute_attr_map_slot(map->attrMap, rootslot, slot = execute_attr_map_slot(map->attrMap, rootslot,
partrouteinfo->pi_PartitionTupleSlot); rri->ri_PartitionTupleSlot);
else else
slot = rootslot; slot = rootslot;
} }
@ -788,7 +792,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
{ {
TupleConversionMap *map; TupleConversionMap *map;
map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap; map = leaf_part_rri->ri_RootToPartitionMap;
Assert(node->onConflictSet != NIL); Assert(node->onConflictSet != NIL);
Assert(rootResultRelInfo->ri_onConflict != NULL); Assert(rootResultRelInfo->ri_onConflict != NULL);
@ -949,18 +953,15 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
int partidx) int partidx)
{ {
MemoryContext oldcxt; MemoryContext oldcxt;
PartitionRoutingInfo *partrouteinfo;
int rri_index; int rri_index;
oldcxt = MemoryContextSwitchTo(proute->memcxt); oldcxt = MemoryContextSwitchTo(proute->memcxt);
partrouteinfo = palloc(sizeof(PartitionRoutingInfo));
/* /*
* Set up a tuple conversion map to convert a tuple routed to the * Set up a tuple conversion map to convert a tuple routed to the
* partition from the parent's type to the partition's. * partition from the parent's type to the partition's.
*/ */
partrouteinfo->pi_RootToPartitionMap = partRelInfo->ri_RootToPartitionMap =
convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot),
RelationGetDescr(partRelInfo->ri_RelationDesc)); RelationGetDescr(partRelInfo->ri_RelationDesc));
@ -970,7 +971,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
* for various operations that are applied to tuples after routing, such * for various operations that are applied to tuples after routing, such
* as checking constraints. * as checking constraints.
*/ */
if (partrouteinfo->pi_RootToPartitionMap != NULL) if (partRelInfo->ri_RootToPartitionMap != NULL)
{ {
Relation partrel = partRelInfo->ri_RelationDesc; Relation partrel = partRelInfo->ri_RelationDesc;
@ -979,11 +980,11 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
* partition's TupleDesc; TupleDesc reference will be released at the * partition's TupleDesc; TupleDesc reference will be released at the
* end of the command. * end of the command.
*/ */
partrouteinfo->pi_PartitionTupleSlot = partRelInfo->ri_PartitionTupleSlot =
table_slot_create(partrel, &estate->es_tupleTable); table_slot_create(partrel, &estate->es_tupleTable);
} }
else else
partrouteinfo->pi_PartitionTupleSlot = NULL; partRelInfo->ri_PartitionTupleSlot = NULL;
/* /*
* If the partition is a foreign table, let the FDW init itself for * 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 != NULL)
partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo); partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo);
partRelInfo->ri_PartitionInfo = partrouteinfo;
partRelInfo->ri_CopyMultiInsertBuffer = NULL; partRelInfo->ri_CopyMultiInsertBuffer = NULL;
/* /*

View File

@ -1172,8 +1172,8 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate,
planSlot, estate, canSetTag); planSlot, estate, canSetTag);
/* /*
* Reset the transition state that may possibly have been written * Reset the transition state that may possibly have been written by
* by INSERT. * INSERT.
*/ */
if (mtstate->mt_transition_capture) if (mtstate->mt_transition_capture)
mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL;
@ -1874,7 +1874,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
ResultRelInfo **partRelInfo) ResultRelInfo **partRelInfo)
{ {
ResultRelInfo *partrel; ResultRelInfo *partrel;
PartitionRoutingInfo *partrouteinfo;
TupleConversionMap *map; TupleConversionMap *map;
/* /*
@ -1885,8 +1884,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
* UPDATE to another partition becomes a DELETE+INSERT. * UPDATE to another partition becomes a DELETE+INSERT.
*/ */
partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate); 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 * 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. * Convert the tuple, if necessary.
*/ */
map = partrouteinfo->pi_RootToPartitionMap; map = partrel->ri_RootToPartitionMap;
if (map != NULL) 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); 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). * to the format of the table mentioned in the query (root relation).
* It's needed for update tuple routing, because the routing starts * It's needed for update tuple routing, because the routing starts
* from the root relation. It's also needed for capturing transition * from the root relation. It's also needed for capturing transition
* tuples, because the transition tuple store can only store tuples * tuples, because the transition tuple store can only store tuples in
* in the root table format. * the root table format.
* *
* For INSERT, the map is only initialized for a given partition when * For INSERT, the map is only initialized for a given partition when
* the partition itself is first initialized by ExecFindPartition(). * the partition itself is first initialized by ExecFindPartition().
@ -2363,9 +2360,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
ExecSetupPartitionTupleRouting(estate, mtstate, rel); ExecSetupPartitionTupleRouting(estate, mtstate, rel);
/* /*
* For update row movement we'll need a dedicated slot to store the * For update row movement we'll need a dedicated slot to store the tuples
* tuples that have been converted from partition format to the root * that have been converted from partition format to the root table
* table format. * format.
*/ */
if (update_tuple_routing_needed) if (update_tuple_routing_needed)
mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL); mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL);

View File

@ -1572,7 +1572,6 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
ResultRelInfo *partrelinfo; ResultRelInfo *partrelinfo;
Relation partrel; Relation partrel;
TupleTableSlot *remoteslot_part; TupleTableSlot *remoteslot_part;
PartitionRoutingInfo *partinfo;
TupleConversionMap *map; TupleConversionMap *map;
MemoryContext oldctx; MemoryContext oldctx;
@ -1599,11 +1598,10 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
* partition's rowtype. Convert if needed or just copy, using a dedicated * partition's rowtype. Convert if needed or just copy, using a dedicated
* slot to store the tuple in any case. * slot to store the tuple in any case.
*/ */
partinfo = partrelinfo->ri_PartitionInfo; remoteslot_part = partrelinfo->ri_PartitionTupleSlot;
remoteslot_part = partinfo->pi_PartitionTupleSlot;
if (remoteslot_part == NULL) if (remoteslot_part == NULL)
remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable); remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable);
map = partinfo->pi_RootToPartitionMap; map = partrelinfo->ri_RootToPartitionMap;
if (map != NULL) if (map != NULL)
remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot, remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot,
remoteslot_part); remoteslot_part);
@ -1748,12 +1746,11 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
*/ */
oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
partrel = partrelinfo_new->ri_RelationDesc; partrel = partrelinfo_new->ri_RelationDesc;
partinfo = partrelinfo_new->ri_PartitionInfo; remoteslot_part = partrelinfo_new->ri_PartitionTupleSlot;
remoteslot_part = partinfo->pi_PartitionTupleSlot;
if (remoteslot_part == NULL) if (remoteslot_part == NULL)
remoteslot_part = table_slot_create(partrel, remoteslot_part = table_slot_create(partrel,
&estate->es_tupleTable); &estate->es_tupleTable);
map = partinfo->pi_RootToPartitionMap; map = partrelinfo_new->ri_RootToPartitionMap;
if (map != NULL) if (map != NULL)
{ {
remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot_part = execute_attr_map_slot(map->attrMap,

View File

@ -22,27 +22,6 @@
typedef struct PartitionDispatchData *PartitionDispatch; typedef struct PartitionDispatchData *PartitionDispatch;
typedef struct PartitionTupleRouting PartitionTupleRouting; 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 * PartitionedRelPruningData - Per-partitioned-table data for run-time pruning
* of partitions. For a multilevel partitioned table, we have one of these * of partitions. For a multilevel partitioned table, we have one of these

View File

@ -33,7 +33,6 @@
#include "utils/tuplestore.h" #include "utils/tuplestore.h"
struct PlanState; /* forward references in this file */ struct PlanState; /* forward references in this file */
struct PartitionRoutingInfo;
struct ParallelHashJoinState; struct ParallelHashJoinState;
struct ExecRowMark; struct ExecRowMark;
struct ExprState; struct ExprState;
@ -480,11 +479,17 @@ typedef struct ResultRelInfo
/* partition check expression state (NULL if not set up yet) */ /* partition check expression state (NULL if not set up yet) */
ExprState *ri_PartitionCheckExpr; 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; Relation ri_PartitionRoot;
TupleConversionMap *ri_RootToPartitionMap;
/* info for partition tuple routing (NULL if not set up yet) */ TupleTableSlot *ri_PartitionTupleSlot;
struct PartitionRoutingInfo *ri_PartitionInfo;
/* /*
* Map to convert child result relation tuples to the format of the table * Map to convert child result relation tuples to the format of the table