Commit 60f7c0ab authored by Robert Haas's avatar Robert Haas

Use ResultRelInfo ** rather than ResultRelInfo * for tuple routing.

The previous convention doesn't lend itself to creating ResultRelInfos
lazily, as we already do in ExecGetTriggerResultRel.  This patch
doesn't make anything lazier than before, but the pending patch for
UPDATE tuple routing proposes to do so (and there might be other
opportunities as well).

Amit Khandekar with some adjustments by me.

Discussion: http://postgr.es/m/CA+TgmoYPVP9Lyf6vUFA5DwxS4c--x6LOj2y36BsJaYtp62eXPQ@mail.gmail.com
parent 305cf1fd
...@@ -167,7 +167,7 @@ typedef struct CopyStateData ...@@ -167,7 +167,7 @@ typedef struct CopyStateData
PartitionDispatch *partition_dispatch_info; PartitionDispatch *partition_dispatch_info;
int num_dispatch; /* Number of entries in the above array */ int num_dispatch; /* Number of entries in the above array */
int num_partitions; /* Number of members in the following arrays */ int num_partitions; /* Number of members in the following arrays */
ResultRelInfo *partitions; /* Per partition result relation */ ResultRelInfo **partitions; /* Per partition result relation pointers */
TupleConversionMap **partition_tupconv_maps; TupleConversionMap **partition_tupconv_maps;
TupleTableSlot *partition_tuple_slot; TupleTableSlot *partition_tuple_slot;
TransitionCaptureState *transition_capture; TransitionCaptureState *transition_capture;
...@@ -2459,7 +2459,7 @@ CopyFrom(CopyState cstate) ...@@ -2459,7 +2459,7 @@ CopyFrom(CopyState cstate)
if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{ {
PartitionDispatch *partition_dispatch_info; PartitionDispatch *partition_dispatch_info;
ResultRelInfo *partitions; ResultRelInfo **partitions;
TupleConversionMap **partition_tupconv_maps; TupleConversionMap **partition_tupconv_maps;
TupleTableSlot *partition_tuple_slot; TupleTableSlot *partition_tuple_slot;
int num_parted, int num_parted,
...@@ -2495,7 +2495,7 @@ CopyFrom(CopyState cstate) ...@@ -2495,7 +2495,7 @@ CopyFrom(CopyState cstate)
for (i = 0; i < cstate->num_partitions; ++i) for (i = 0; i < cstate->num_partitions; ++i)
{ {
cstate->transition_tupconv_maps[i] = cstate->transition_tupconv_maps[i] =
convert_tuples_by_name(RelationGetDescr(cstate->partitions[i].ri_RelationDesc), convert_tuples_by_name(RelationGetDescr(cstate->partitions[i]->ri_RelationDesc),
RelationGetDescr(cstate->rel), RelationGetDescr(cstate->rel),
gettext_noop("could not convert row type")); gettext_noop("could not convert row type"));
} }
...@@ -2626,7 +2626,7 @@ CopyFrom(CopyState cstate) ...@@ -2626,7 +2626,7 @@ CopyFrom(CopyState cstate)
* to the selected partition. * to the selected partition.
*/ */
saved_resultRelInfo = resultRelInfo; saved_resultRelInfo = resultRelInfo;
resultRelInfo = cstate->partitions + leaf_part_index; resultRelInfo = cstate->partitions[leaf_part_index];
/* We do not yet have a way to insert into a foreign partition */ /* We do not yet have a way to insert into a foreign partition */
if (resultRelInfo->ri_FdwRoutine) if (resultRelInfo->ri_FdwRoutine)
...@@ -2856,7 +2856,7 @@ CopyFrom(CopyState cstate) ...@@ -2856,7 +2856,7 @@ CopyFrom(CopyState cstate)
} }
for (i = 0; i < cstate->num_partitions; i++) for (i = 0; i < cstate->num_partitions; i++)
{ {
ResultRelInfo *resultRelInfo = cstate->partitions + i; ResultRelInfo *resultRelInfo = cstate->partitions[i];
ExecCloseIndices(resultRelInfo); ExecCloseIndices(resultRelInfo);
heap_close(resultRelInfo->ri_RelationDesc, NoLock); heap_close(resultRelInfo->ri_RelationDesc, NoLock);
......
...@@ -3242,7 +3242,7 @@ EvalPlanQualEnd(EPQState *epqstate) ...@@ -3242,7 +3242,7 @@ EvalPlanQualEnd(EPQState *epqstate)
* Output arguments: * Output arguments:
* 'pd' receives an array of PartitionDispatch objects with one entry for * 'pd' receives an array of PartitionDispatch objects with one entry for
* every partitioned table in the partition tree * every partitioned table in the partition tree
* 'partitions' receives an array of ResultRelInfo objects with one entry for * 'partitions' receives an array of ResultRelInfo* objects with one entry for
* every leaf partition in the partition tree * every leaf partition in the partition tree
* 'tup_conv_maps' receives an array of TupleConversionMap objects with one * 'tup_conv_maps' receives an array of TupleConversionMap objects with one
* entry for every leaf partition (required to convert input tuple based * entry for every leaf partition (required to convert input tuple based
...@@ -3265,7 +3265,7 @@ ExecSetupPartitionTupleRouting(Relation rel, ...@@ -3265,7 +3265,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
Index resultRTindex, Index resultRTindex,
EState *estate, EState *estate,
PartitionDispatch **pd, PartitionDispatch **pd,
ResultRelInfo **partitions, ResultRelInfo ***partitions,
TupleConversionMap ***tup_conv_maps, TupleConversionMap ***tup_conv_maps,
TupleTableSlot **partition_tuple_slot, TupleTableSlot **partition_tuple_slot,
int *num_parted, int *num_partitions) int *num_parted, int *num_partitions)
...@@ -3283,8 +3283,8 @@ ExecSetupPartitionTupleRouting(Relation rel, ...@@ -3283,8 +3283,8 @@ ExecSetupPartitionTupleRouting(Relation rel,
(void) find_all_inheritors(RelationGetRelid(rel), RowExclusiveLock, NULL); (void) find_all_inheritors(RelationGetRelid(rel), RowExclusiveLock, NULL);
*pd = RelationGetPartitionDispatchInfo(rel, num_parted, &leaf_parts); *pd = RelationGetPartitionDispatchInfo(rel, num_parted, &leaf_parts);
*num_partitions = list_length(leaf_parts); *num_partitions = list_length(leaf_parts);
*partitions = (ResultRelInfo *) palloc(*num_partitions * *partitions = (ResultRelInfo **) palloc(*num_partitions *
sizeof(ResultRelInfo)); sizeof(ResultRelInfo *));
*tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions * *tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions *
sizeof(TupleConversionMap *)); sizeof(TupleConversionMap *));
...@@ -3296,7 +3296,8 @@ ExecSetupPartitionTupleRouting(Relation rel, ...@@ -3296,7 +3296,8 @@ ExecSetupPartitionTupleRouting(Relation rel,
*/ */
*partition_tuple_slot = MakeTupleTableSlot(); *partition_tuple_slot = MakeTupleTableSlot();
leaf_part_rri = *partitions; leaf_part_rri = (ResultRelInfo *) palloc0(*num_partitions *
sizeof(ResultRelInfo));
i = 0; i = 0;
foreach(cell, leaf_parts) foreach(cell, leaf_parts)
{ {
...@@ -3341,7 +3342,7 @@ ExecSetupPartitionTupleRouting(Relation rel, ...@@ -3341,7 +3342,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
estate->es_leaf_result_relations = estate->es_leaf_result_relations =
lappend(estate->es_leaf_result_relations, leaf_part_rri); lappend(estate->es_leaf_result_relations, leaf_part_rri);
leaf_part_rri++; (*partitions)[i] = leaf_part_rri++;
i++; i++;
} }
} }
......
...@@ -303,7 +303,7 @@ ExecInsert(ModifyTableState *mtstate, ...@@ -303,7 +303,7 @@ ExecInsert(ModifyTableState *mtstate,
* the selected partition. * the selected partition.
*/ */
saved_resultRelInfo = resultRelInfo; saved_resultRelInfo = resultRelInfo;
resultRelInfo = mtstate->mt_partitions + leaf_part_index; resultRelInfo = mtstate->mt_partitions[leaf_part_index];
/* We do not yet have a way to insert into a foreign partition */ /* We do not yet have a way to insert into a foreign partition */
if (resultRelInfo->ri_FdwRoutine) if (resultRelInfo->ri_FdwRoutine)
...@@ -1498,34 +1498,43 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) ...@@ -1498,34 +1498,43 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate)
if (mtstate->mt_transition_capture != NULL || if (mtstate->mt_transition_capture != NULL ||
mtstate->mt_oc_transition_capture != NULL) mtstate->mt_oc_transition_capture != NULL)
{ {
ResultRelInfo *resultRelInfos;
int numResultRelInfos; int numResultRelInfos;
/* Find the set of partitions so that we can find their TupleDescs. */ numResultRelInfos = (mtstate->mt_partition_tuple_slot != NULL ?
mtstate->mt_num_partitions :
mtstate->mt_nplans);
/*
* Build array of conversion maps from each child's TupleDesc to the
* one used in the tuplestore. The map pointers may be NULL when no
* conversion is necessary, which is hopefully a common case for
* partitions.
*/
mtstate->mt_transition_tupconv_maps = (TupleConversionMap **)
palloc0(sizeof(TupleConversionMap *) * numResultRelInfos);
/* Choose the right set of partitions */
if (mtstate->mt_partition_dispatch_info != NULL) if (mtstate->mt_partition_dispatch_info != NULL)
{ {
/* /*
* For INSERT via partitioned table, so we need TupleDescs based * For tuple routing among partitions, we need TupleDescs based
* on the partition routing table. * on the partition routing table.
*/ */
resultRelInfos = mtstate->mt_partitions; ResultRelInfo **resultRelInfos = mtstate->mt_partitions;
numResultRelInfos = mtstate->mt_num_partitions;
for (i = 0; i < numResultRelInfos; ++i)
{
mtstate->mt_transition_tupconv_maps[i] =
convert_tuples_by_name(RelationGetDescr(resultRelInfos[i]->ri_RelationDesc),
RelationGetDescr(targetRelInfo->ri_RelationDesc),
gettext_noop("could not convert row type"));
}
} }
else else
{ {
/* Otherwise we need the ResultRelInfo for each subplan. */ /* Otherwise we need the ResultRelInfo for each subplan. */
resultRelInfos = mtstate->resultRelInfo; ResultRelInfo *resultRelInfos = mtstate->resultRelInfo;
numResultRelInfos = mtstate->mt_nplans;
}
/*
* Build array of conversion maps from each child's TupleDesc to the
* one used in the tuplestore. The map pointers may be NULL when no
* conversion is necessary, which is hopefully a common case for
* partitions.
*/
mtstate->mt_transition_tupconv_maps = (TupleConversionMap **)
palloc0(sizeof(TupleConversionMap *) * numResultRelInfos);
for (i = 0; i < numResultRelInfos; ++i) for (i = 0; i < numResultRelInfos; ++i)
{ {
mtstate->mt_transition_tupconv_maps[i] = mtstate->mt_transition_tupconv_maps[i] =
...@@ -1533,6 +1542,7 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) ...@@ -1533,6 +1542,7 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate)
RelationGetDescr(targetRelInfo->ri_RelationDesc), RelationGetDescr(targetRelInfo->ri_RelationDesc),
gettext_noop("could not convert row type")); gettext_noop("could not convert row type"));
} }
}
/* /*
* Install the conversion map for the first plan for UPDATE and DELETE * Install the conversion map for the first plan for UPDATE and DELETE
...@@ -1935,7 +1945,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -1935,7 +1945,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{ {
PartitionDispatch *partition_dispatch_info; PartitionDispatch *partition_dispatch_info;
ResultRelInfo *partitions; ResultRelInfo **partitions;
TupleConversionMap **partition_tupconv_maps; TupleConversionMap **partition_tupconv_maps;
TupleTableSlot *partition_tuple_slot; TupleTableSlot *partition_tuple_slot;
int num_parted, int num_parted,
...@@ -2014,14 +2024,16 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -2014,14 +2024,16 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
mtstate->mt_nplans == 1); mtstate->mt_nplans == 1);
wcoList = linitial(node->withCheckOptionLists); wcoList = linitial(node->withCheckOptionLists);
plan = mtstate->mt_plans[0]; plan = mtstate->mt_plans[0];
resultRelInfo = mtstate->mt_partitions;
for (i = 0; i < mtstate->mt_num_partitions; i++) for (i = 0; i < mtstate->mt_num_partitions; i++)
{ {
Relation partrel = resultRelInfo->ri_RelationDesc; Relation partrel;
List *mapped_wcoList; List *mapped_wcoList;
List *wcoExprs = NIL; List *wcoExprs = NIL;
ListCell *ll; ListCell *ll;
resultRelInfo = mtstate->mt_partitions[i];
partrel = resultRelInfo->ri_RelationDesc;
/* varno = node->nominalRelation */ /* varno = node->nominalRelation */
mapped_wcoList = map_partition_varattnos(wcoList, mapped_wcoList = map_partition_varattnos(wcoList,
node->nominalRelation, node->nominalRelation,
...@@ -2037,7 +2049,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -2037,7 +2049,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
resultRelInfo->ri_WithCheckOptions = mapped_wcoList; resultRelInfo->ri_WithCheckOptions = mapped_wcoList;
resultRelInfo->ri_WithCheckOptionExprs = wcoExprs; resultRelInfo->ri_WithCheckOptionExprs = wcoExprs;
resultRelInfo++;
} }
} }
...@@ -2088,13 +2099,15 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -2088,13 +2099,15 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* will suffice. This only occurs for the INSERT case; UPDATE/DELETE * will suffice. This only occurs for the INSERT case; UPDATE/DELETE
* are handled above. * are handled above.
*/ */
resultRelInfo = mtstate->mt_partitions;
returningList = linitial(node->returningLists); returningList = linitial(node->returningLists);
for (i = 0; i < mtstate->mt_num_partitions; i++) for (i = 0; i < mtstate->mt_num_partitions; i++)
{ {
Relation partrel = resultRelInfo->ri_RelationDesc; Relation partrel;
List *rlist; List *rlist;
resultRelInfo = mtstate->mt_partitions[i];
partrel = resultRelInfo->ri_RelationDesc;
/* varno = node->nominalRelation */ /* varno = node->nominalRelation */
rlist = map_partition_varattnos(returningList, rlist = map_partition_varattnos(returningList,
node->nominalRelation, node->nominalRelation,
...@@ -2102,7 +2115,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -2102,7 +2115,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
resultRelInfo->ri_projectReturning = resultRelInfo->ri_projectReturning =
ExecBuildProjectionInfo(rlist, econtext, slot, &mtstate->ps, ExecBuildProjectionInfo(rlist, econtext, slot, &mtstate->ps,
resultRelInfo->ri_RelationDesc->rd_att); resultRelInfo->ri_RelationDesc->rd_att);
resultRelInfo++;
} }
} }
else else
...@@ -2376,7 +2388,7 @@ ExecEndModifyTable(ModifyTableState *node) ...@@ -2376,7 +2388,7 @@ ExecEndModifyTable(ModifyTableState *node)
} }
for (i = 0; i < node->mt_num_partitions; i++) for (i = 0; i < node->mt_num_partitions; i++)
{ {
ResultRelInfo *resultRelInfo = node->mt_partitions + i; ResultRelInfo *resultRelInfo = node->mt_partitions[i];
ExecCloseIndices(resultRelInfo); ExecCloseIndices(resultRelInfo);
heap_close(resultRelInfo->ri_RelationDesc, NoLock); heap_close(resultRelInfo->ri_RelationDesc, NoLock);
......
...@@ -210,7 +210,7 @@ extern void ExecSetupPartitionTupleRouting(Relation rel, ...@@ -210,7 +210,7 @@ extern void ExecSetupPartitionTupleRouting(Relation rel,
Index resultRTindex, Index resultRTindex,
EState *estate, EState *estate,
PartitionDispatch **pd, PartitionDispatch **pd,
ResultRelInfo **partitions, ResultRelInfo ***partitions,
TupleConversionMap ***tup_conv_maps, TupleConversionMap ***tup_conv_maps,
TupleTableSlot **partition_tuple_slot, TupleTableSlot **partition_tuple_slot,
int *num_parted, int *num_partitions); int *num_parted, int *num_partitions);
......
...@@ -979,7 +979,7 @@ typedef struct ModifyTableState ...@@ -979,7 +979,7 @@ typedef struct ModifyTableState
int mt_num_dispatch; /* Number of entries in the above array */ int mt_num_dispatch; /* Number of entries in the above array */
int mt_num_partitions; /* Number of members in the following int mt_num_partitions; /* Number of members in the following
* arrays */ * arrays */
ResultRelInfo *mt_partitions; /* Per partition result relation */ ResultRelInfo **mt_partitions; /* Per partition result relation pointers */
TupleConversionMap **mt_partition_tupconv_maps; TupleConversionMap **mt_partition_tupconv_maps;
/* Per partition tuple conversion map */ /* Per partition tuple conversion map */
TupleTableSlot *mt_partition_tuple_slot; TupleTableSlot *mt_partition_tuple_slot;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment