mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Simplify and encapsulate tuple routing support code.
Instead of having ExecSetupPartitionTupleRouting return multiple out parameters, have it return a pointer to a structure containing all of those different things. Also, provide and use a cleanup function, ExecCleanupTupleRouting, instead of cleaning up all of the resources allocated by ExecSetupPartitionTupleRouting individually. Amit Khandekar, reviewed by Amit Langote, David Rowley, and me Discussion: http://postgr.es/m/CAJ3gD9fWfxgKC+PfJZF3hkgAcNOy-LpfPxVYitDEXKHjeieWQQ@mail.gmail.com
This commit is contained in:
@ -166,12 +166,9 @@ typedef struct CopyStateData
|
||||
bool volatile_defexprs; /* is any of defexprs volatile? */
|
||||
List *range_table;
|
||||
|
||||
PartitionDispatch *partition_dispatch_info;
|
||||
int num_dispatch; /* Number of entries in the above array */
|
||||
int num_partitions; /* Number of members in the following arrays */
|
||||
ResultRelInfo **partitions; /* Per partition result relation pointers */
|
||||
TupleConversionMap **partition_tupconv_maps;
|
||||
TupleTableSlot *partition_tuple_slot;
|
||||
/* Tuple-routing support info */
|
||||
PartitionTupleRouting *partition_tuple_routing;
|
||||
|
||||
TransitionCaptureState *transition_capture;
|
||||
TupleConversionMap **transition_tupconv_maps;
|
||||
|
||||
@ -2472,28 +2469,10 @@ CopyFrom(CopyState cstate)
|
||||
*/
|
||||
if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||
{
|
||||
PartitionDispatch *partition_dispatch_info;
|
||||
ResultRelInfo **partitions;
|
||||
TupleConversionMap **partition_tupconv_maps;
|
||||
TupleTableSlot *partition_tuple_slot;
|
||||
int num_parted,
|
||||
num_partitions;
|
||||
PartitionTupleRouting *proute;
|
||||
|
||||
ExecSetupPartitionTupleRouting(NULL,
|
||||
cstate->rel,
|
||||
1,
|
||||
estate,
|
||||
&partition_dispatch_info,
|
||||
&partitions,
|
||||
&partition_tupconv_maps,
|
||||
&partition_tuple_slot,
|
||||
&num_parted, &num_partitions);
|
||||
cstate->partition_dispatch_info = partition_dispatch_info;
|
||||
cstate->num_dispatch = num_parted;
|
||||
cstate->partitions = partitions;
|
||||
cstate->num_partitions = num_partitions;
|
||||
cstate->partition_tupconv_maps = partition_tupconv_maps;
|
||||
cstate->partition_tuple_slot = partition_tuple_slot;
|
||||
proute = cstate->partition_tuple_routing =
|
||||
ExecSetupPartitionTupleRouting(NULL, cstate->rel, 1, estate);
|
||||
|
||||
/*
|
||||
* If we are capturing transition tuples, they may need to be
|
||||
@ -2506,11 +2485,11 @@ CopyFrom(CopyState cstate)
|
||||
int i;
|
||||
|
||||
cstate->transition_tupconv_maps = (TupleConversionMap **)
|
||||
palloc0(sizeof(TupleConversionMap *) * cstate->num_partitions);
|
||||
for (i = 0; i < cstate->num_partitions; ++i)
|
||||
palloc0(sizeof(TupleConversionMap *) * proute->num_partitions);
|
||||
for (i = 0; i < proute->num_partitions; ++i)
|
||||
{
|
||||
cstate->transition_tupconv_maps[i] =
|
||||
convert_tuples_by_name(RelationGetDescr(cstate->partitions[i]->ri_RelationDesc),
|
||||
convert_tuples_by_name(RelationGetDescr(proute->partitions[i]->ri_RelationDesc),
|
||||
RelationGetDescr(cstate->rel),
|
||||
gettext_noop("could not convert row type"));
|
||||
}
|
||||
@ -2530,7 +2509,7 @@ CopyFrom(CopyState cstate)
|
||||
if ((resultRelInfo->ri_TrigDesc != NULL &&
|
||||
(resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
|
||||
resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) ||
|
||||
cstate->partition_dispatch_info != NULL ||
|
||||
cstate->partition_tuple_routing != NULL ||
|
||||
cstate->volatile_defexprs)
|
||||
{
|
||||
useHeapMultiInsert = false;
|
||||
@ -2605,10 +2584,11 @@ CopyFrom(CopyState cstate)
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
|
||||
/* Determine the partition to heap_insert the tuple into */
|
||||
if (cstate->partition_dispatch_info)
|
||||
if (cstate->partition_tuple_routing)
|
||||
{
|
||||
int leaf_part_index;
|
||||
TupleConversionMap *map;
|
||||
PartitionTupleRouting *proute = cstate->partition_tuple_routing;
|
||||
|
||||
/*
|
||||
* Away we go ... If we end up not finding a partition after all,
|
||||
@ -2619,11 +2599,11 @@ CopyFrom(CopyState cstate)
|
||||
* partition, respectively.
|
||||
*/
|
||||
leaf_part_index = ExecFindPartition(resultRelInfo,
|
||||
cstate->partition_dispatch_info,
|
||||
proute->partition_dispatch_info,
|
||||
slot,
|
||||
estate);
|
||||
Assert(leaf_part_index >= 0 &&
|
||||
leaf_part_index < cstate->num_partitions);
|
||||
leaf_part_index < proute->num_partitions);
|
||||
|
||||
/*
|
||||
* If this tuple is mapped to a partition that is not same as the
|
||||
@ -2641,7 +2621,7 @@ CopyFrom(CopyState cstate)
|
||||
* to the selected partition.
|
||||
*/
|
||||
saved_resultRelInfo = resultRelInfo;
|
||||
resultRelInfo = cstate->partitions[leaf_part_index];
|
||||
resultRelInfo = proute->partitions[leaf_part_index];
|
||||
|
||||
/* We do not yet have a way to insert into a foreign partition */
|
||||
if (resultRelInfo->ri_FdwRoutine)
|
||||
@ -2688,7 +2668,7 @@ CopyFrom(CopyState cstate)
|
||||
* We might need to convert from the parent rowtype to the
|
||||
* partition rowtype.
|
||||
*/
|
||||
map = cstate->partition_tupconv_maps[leaf_part_index];
|
||||
map = proute->partition_tupconv_maps[leaf_part_index];
|
||||
if (map)
|
||||
{
|
||||
Relation partrel = resultRelInfo->ri_RelationDesc;
|
||||
@ -2700,7 +2680,7 @@ CopyFrom(CopyState cstate)
|
||||
* point on. Use a dedicated slot from this point on until
|
||||
* we're finished dealing with the partition.
|
||||
*/
|
||||
slot = cstate->partition_tuple_slot;
|
||||
slot = proute->partition_tuple_slot;
|
||||
Assert(slot != NULL);
|
||||
ExecSetSlotDescriptor(slot, RelationGetDescr(partrel));
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, true);
|
||||
@ -2852,34 +2832,8 @@ CopyFrom(CopyState cstate)
|
||||
ExecCloseIndices(resultRelInfo);
|
||||
|
||||
/* Close all the partitioned tables, leaf partitions, and their indices */
|
||||
if (cstate->partition_dispatch_info)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Remember cstate->partition_dispatch_info[0] corresponds to the root
|
||||
* partitioned table, which we must not try to close, because it is
|
||||
* the main target table of COPY that will be closed eventually by
|
||||
* DoCopy(). Also, tupslot is NULL for the root partitioned table.
|
||||
*/
|
||||
for (i = 1; i < cstate->num_dispatch; i++)
|
||||
{
|
||||
PartitionDispatch pd = cstate->partition_dispatch_info[i];
|
||||
|
||||
heap_close(pd->reldesc, NoLock);
|
||||
ExecDropSingleTupleTableSlot(pd->tupslot);
|
||||
}
|
||||
for (i = 0; i < cstate->num_partitions; i++)
|
||||
{
|
||||
ResultRelInfo *resultRelInfo = cstate->partitions[i];
|
||||
|
||||
ExecCloseIndices(resultRelInfo);
|
||||
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
|
||||
}
|
||||
|
||||
/* Release the standalone partition tuple descriptor */
|
||||
ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
|
||||
}
|
||||
if (cstate->partition_tuple_routing)
|
||||
ExecCleanupTupleRouting(cstate->partition_tuple_routing);
|
||||
|
||||
/* Close any trigger target relations */
|
||||
ExecCleanUpTriggerState(estate);
|
||||
|
Reference in New Issue
Block a user