From 187683f6ea153e8be1a5c067b3546e70b15ccd47 Mon Sep 17 00:00:00 2001 From: amit Date: Tue, 19 Dec 2017 10:43:45 +0900 Subject: [PATCH v2 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 | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 6bfca2a4af..242dc56d87 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -166,11 +166,7 @@ typedef struct CopyStateData bool volatile_defexprs; /* is any of defexprs volatile? */ List *range_table; - /* Tuple-routing support info */ - PartitionTupleRouting *partition_tuple_routing; - TransitionCaptureState *transition_capture; - TupleConversionMap **transition_tupconv_maps; /* * These variables are used to reduce overhead in textual COPY FROM. @@ -2286,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; @@ -2304,6 +2301,8 @@ CopyFrom(CopyState cstate) Size bufferedTuplesSize = 0; int firstBufferedLineNo = 0; + PartitionTupleRouting *proute = NULL; + Assert(cstate->rel); /* @@ -2469,10 +2468,15 @@ CopyFrom(CopyState cstate) */ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - PartitionTupleRouting *proute; + ModifyTable *node = makeNode(ModifyTable); - proute = cstate->partition_tuple_routing = - ExecSetupPartitionTupleRouting(NULL, cstate->rel, 1, estate); + /* Just need make this field appear valid. */ + node->nominalRelation = 1; + mtstate->ps.plan = (Plan *) node; + mtstate->ps.state = estate; + mtstate->resultRelInfo = resultRelInfo; + proute = mtstate->mt_partition_tuple_routing = + ExecSetupPartitionTupleRouting(mtstate, cstate->rel, 1, estate); /* * If we are capturing transition tuples, they may need to be @@ -2484,11 +2488,11 @@ CopyFrom(CopyState cstate) { int i; - cstate->transition_tupconv_maps = (TupleConversionMap **) + mtstate->mt_transition_tupconv_maps = (TupleConversionMap **) palloc0(sizeof(TupleConversionMap *) * proute->num_partitions); for (i = 0; i < proute->num_partitions; ++i) { - cstate->transition_tupconv_maps[i] = + mtstate->mt_transition_tupconv_maps[i] = convert_tuples_by_name(RelationGetDescr(proute->partitions[i]->ri_RelationDesc), RelationGetDescr(cstate->rel), gettext_noop("could not convert row type")); @@ -2509,7 +2513,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_tuple_routing != NULL || + mtstate->mt_partition_tuple_routing != NULL || cstate->volatile_defexprs) { useHeapMultiInsert = false; @@ -2584,11 +2588,10 @@ CopyFrom(CopyState cstate) ExecStoreTuple(tuple, slot, InvalidBuffer, false); /* Determine the partition to heap_insert the tuple into */ - if (cstate->partition_tuple_routing) + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { 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, @@ -2651,7 +2654,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 { @@ -2832,8 +2835,8 @@ CopyFrom(CopyState cstate) ExecCloseIndices(resultRelInfo); /* Close all the partitioned tables, leaf partitions, and their indices */ - if (cstate->partition_tuple_routing) - ExecCleanupTupleRouting(cstate->partition_tuple_routing); + if (proute) + ExecCleanupTupleRouting(proute); /* Close any trigger target relations */ ExecCleanUpTriggerState(estate); -- 2.11.0