From a87be8a84d467d65cc0b6cf02655fc3b2b9a458f Mon Sep 17 00:00:00 2001 From: amit Date: Tue, 19 Dec 2017 10:43:45 +0900 Subject: [PATCH 1/4] Teach CopyFrom to use ModifyTableState for tuple-routing This removes all fields of CopyStateData that were meant for tuple routing and instead uses ModifyTableState that has all those fields, including transition_tupconv_maps. In COPY's case, transition_tupconv_maps is only required if tuple routing is being used, so it's safe. --- src/backend/commands/copy.c | 79 ++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 254be28ae4..c82103e1c5 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -166,14 +166,7 @@ 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; TransitionCaptureState *transition_capture; - TupleConversionMap **transition_tupconv_maps; /* * These variables are used to reduce overhead in textual COPY FROM. @@ -2289,6 +2282,7 @@ CopyFrom(CopyState cstate) ResultRelInfo *resultRelInfo; ResultRelInfo *saved_resultRelInfo = NULL; EState *estate = CreateExecutorState(); /* for ExecConstraints() */ + ModifyTableState *mtstate = makeNode(ModifyTableState); ExprContext *econtext; TupleTableSlot *myslot; MemoryContext oldcontext = CurrentMemoryContext; @@ -2478,22 +2472,28 @@ CopyFrom(CopyState cstate) TupleTableSlot *partition_tuple_slot; int num_parted, num_partitions; - - ExecSetupPartitionTupleRouting(NULL, + ModifyTable *node = makeNode(ModifyTable); + + /* Just need make this field appear valid. */ + node->nominalRelation = 1; + mtstate->ps.plan = (Plan *) node; + mtstate->ps.state = estate; + mtstate->resultRelInfo = resultRelInfo; + ExecSetupPartitionTupleRouting(mtstate, cstate->rel, - 1, + node->nominalRelation, 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; + mtstate->mt_partition_dispatch_info = partition_dispatch_info; + mtstate->mt_num_dispatch = num_parted; + mtstate->mt_partitions = partitions; + mtstate->mt_num_partitions = num_partitions; + mtstate->mt_partition_tupconv_maps = partition_tupconv_maps; + mtstate->mt_partition_tuple_slot = partition_tuple_slot; /* * If we are capturing transition tuples, they may need to be @@ -2505,12 +2505,13 @@ CopyFrom(CopyState cstate) { int i; - cstate->transition_tupconv_maps = (TupleConversionMap **) - palloc0(sizeof(TupleConversionMap *) * cstate->num_partitions); - for (i = 0; i < cstate->num_partitions; ++i) + mtstate->mt_transition_tupconv_maps = (TupleConversionMap **) + palloc0(sizeof(TupleConversionMap *) * + mtstate->mt_num_partitions); + for (i = 0; i < mtstate->mt_num_partitions; ++i) { - cstate->transition_tupconv_maps[i] = - convert_tuples_by_name(RelationGetDescr(cstate->partitions[i]->ri_RelationDesc), + mtstate->mt_transition_tupconv_maps[i] = + convert_tuples_by_name(RelationGetDescr(mtstate->mt_partitions[i]->ri_RelationDesc), RelationGetDescr(cstate->rel), gettext_noop("could not convert row type")); } @@ -2530,7 +2531,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 || + mtstate->mt_partition_dispatch_info != NULL || cstate->volatile_defexprs) { useHeapMultiInsert = false; @@ -2605,7 +2606,7 @@ CopyFrom(CopyState cstate) ExecStoreTuple(tuple, slot, InvalidBuffer, false); /* Determine the partition to heap_insert the tuple into */ - if (cstate->partition_dispatch_info) + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { int leaf_part_index; TupleConversionMap *map; @@ -2619,11 +2620,11 @@ CopyFrom(CopyState cstate) * partition, respectively. */ leaf_part_index = ExecFindPartition(resultRelInfo, - cstate->partition_dispatch_info, + mtstate->mt_partition_dispatch_info, slot, estate); Assert(leaf_part_index >= 0 && - leaf_part_index < cstate->num_partitions); + leaf_part_index < mtstate->mt_num_partitions); /* * If this tuple is mapped to a partition that is not same as the @@ -2641,7 +2642,8 @@ CopyFrom(CopyState cstate) * to the selected partition. */ saved_resultRelInfo = resultRelInfo; - resultRelInfo = cstate->partitions[leaf_part_index]; + resultRelInfo = mtstate->mt_partitions[leaf_part_index]; + Assert(resultRelInfo != NULL); /* We do not yet have a way to insert into a foreign partition */ if (resultRelInfo->ri_FdwRoutine) @@ -2671,7 +2673,7 @@ CopyFrom(CopyState cstate) */ cstate->transition_capture->tcs_original_insert_tuple = NULL; cstate->transition_capture->tcs_map = - cstate->transition_tupconv_maps[leaf_part_index]; + mtstate->mt_transition_tupconv_maps[leaf_part_index]; } else { @@ -2688,7 +2690,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 = mtstate->mt_partition_tupconv_maps[leaf_part_index]; if (map) { Relation partrel = resultRelInfo->ri_RelationDesc; @@ -2700,7 +2702,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 = mtstate->mt_partition_tuple_slot; Assert(slot != NULL); ExecSetSlotDescriptor(slot, RelationGetDescr(partrel)); ExecStoreTuple(tuple, slot, InvalidBuffer, true); @@ -2852,7 +2854,7 @@ CopyFrom(CopyState cstate) ExecCloseIndices(resultRelInfo); /* Close all the partitioned tables, leaf partitions, and their indices */ - if (cstate->partition_dispatch_info) + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { int i; @@ -2862,23 +2864,26 @@ CopyFrom(CopyState cstate) * 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++) + for (i = 1; i < mtstate->mt_num_dispatch; i++) { - PartitionDispatch pd = cstate->partition_dispatch_info[i]; + PartitionDispatch pd = mtstate->mt_partition_dispatch_info[i]; heap_close(pd->reldesc, NoLock); ExecDropSingleTupleTableSlot(pd->tupslot); } - for (i = 0; i < cstate->num_partitions; i++) + for (i = 0; i < mtstate->mt_num_partitions; i++) { - ResultRelInfo *resultRelInfo = cstate->partitions[i]; + ResultRelInfo *resultRelInfo = mtstate->mt_partitions[i]; - ExecCloseIndices(resultRelInfo); - heap_close(resultRelInfo->ri_RelationDesc, NoLock); + if (resultRelInfo) + { + ExecCloseIndices(resultRelInfo); + heap_close(resultRelInfo->ri_RelationDesc, NoLock); + } } /* Release the standalone partition tuple descriptor */ - ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot); + ExecDropSingleTupleTableSlot(mtstate->mt_partition_tuple_slot); } /* Close any trigger target relations */ -- 2.11.0