]> granicus.if.org Git - postgresql/commitdiff
Move partition_tuple_slot out of EState.
authorRobert Haas <rhaas@postgresql.org>
Wed, 4 Jan 2017 18:05:29 +0000 (13:05 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 4 Jan 2017 18:16:59 +0000 (13:16 -0500)
Commit 2ac3ef7a01df859c62d0a02333b646d65eaec5ff added a TupleTapleSlot
for partition tuple slot to EState (es_partition_tuple_slot) but it's
more logical to have it as part of ModifyTableState
(mt_partition_tuple_slot) and CopyState (partition_tuple_slot).

Discussion: http://postgr.es/m/1bd459d9-4c0c-197a-346e-e5e59e217d97@lab.ntt.co.jp

Amit Langote, per a gripe from me

src/backend/commands/copy.c
src/backend/executor/execMain.c
src/backend/executor/nodeModifyTable.c
src/include/executor/executor.h
src/include/nodes/execnodes.h

index 77a8631de1270fa667423573ce4e433078beaa43..071b97dee132a0356ed98c710ea248ab2fb138a1 100644 (file)
@@ -161,11 +161,14 @@ typedef struct CopyStateData
        ExprState **defexprs;           /* array of default att expressions */
        bool            volatile_defexprs;              /* is any of defexprs volatile? */
        List       *range_table;
+
        PartitionDispatch *partition_dispatch_info;
-       int                     num_dispatch;
-       int                     num_partitions;
-       ResultRelInfo *partitions;
+       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 */
        TupleConversionMap **partition_tupconv_maps;
+       TupleTableSlot *partition_tuple_slot;
 
        /*
         * These variables are used to reduce overhead in textual COPY FROM.
@@ -1409,6 +1412,7 @@ BeginCopy(ParseState *pstate,
                        PartitionDispatch  *partition_dispatch_info;
                        ResultRelInfo      *partitions;
                        TupleConversionMap **partition_tupconv_maps;
+                       TupleTableSlot     *partition_tuple_slot;
                        int                                     num_parted,
                                                                num_partitions;
 
@@ -1416,12 +1420,14 @@ BeginCopy(ParseState *pstate,
                                                                                   &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;
                }
        }
        else
@@ -2435,15 +2441,6 @@ CopyFrom(CopyState cstate)
        /* Triggers might need a slot as well */
        estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
 
-       /*
-        * Initialize a dedicated slot to manipulate tuples of any given
-        * partition's rowtype.
-        */
-       if (cstate->partition_dispatch_info)
-               estate->es_partition_tuple_slot = ExecInitExtraTupleSlot(estate);
-       else
-               estate->es_partition_tuple_slot = NULL;
-
        /*
         * It's more efficient to prepare a bunch of tuples for insertion, and
         * insert them in one heap_multi_insert() call, than call heap_insert()
@@ -2591,7 +2588,7 @@ CopyFrom(CopyState cstate)
                                 * we're finished dealing with the partition.
                                 */
                                oldslot = slot;
-                               slot = estate->es_partition_tuple_slot;
+                               slot = cstate->partition_tuple_slot;
                                Assert(slot != NULL);
                                ExecSetSlotDescriptor(slot, RelationGetDescr(partrel));
                                ExecStoreTuple(tuple, slot, InvalidBuffer, true);
@@ -2756,6 +2753,9 @@ CopyFrom(CopyState cstate)
                        ExecCloseIndices(resultRelInfo);
                        heap_close(resultRelInfo->ri_RelationDesc, NoLock);
                }
+
+               /* Release the standalone partition tuple descriptor */
+               ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
        }
 
        FreeExecutorState(estate);
index 7e3c207018f36a2e0fc7dd6a1bd0ba5af7642941..eb9b528c4e4800df885c185f1d2bd4371f1137cf 100644 (file)
@@ -3012,6 +3012,9 @@ EvalPlanQualEnd(EPQState *epqstate)
  *             entry for every leaf partition (required to convert input tuple based
  *             on the root table's rowtype to a leaf partition's rowtype after tuple
  *             routing is done
+ * 'partition_tuple_slot' receives a standalone TupleTableSlot to be used
+ *             to manipulate any given leaf partition's rowtype after that partition
+ *             is chosen by tuple-routing.
  * 'num_parted' receives the number of partitioned tables in the partition
  *             tree (= the number of entries in the 'pd' output array)
  * 'num_partitions' receives the number of leaf partitions in the partition
@@ -3026,6 +3029,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
                                                           PartitionDispatch **pd,
                                                           ResultRelInfo **partitions,
                                                           TupleConversionMap ***tup_conv_maps,
+                                                          TupleTableSlot **partition_tuple_slot,
                                                           int *num_parted, int *num_partitions)
 {
        TupleDesc       tupDesc = RelationGetDescr(rel);
@@ -3043,6 +3047,14 @@ ExecSetupPartitionTupleRouting(Relation rel,
        *tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions *
                                                                                   sizeof(TupleConversionMap *));
 
+       /*
+        * Initialize an empty slot that will be used to manipulate tuples of any
+        * given partition's rowtype.  It is attached to the caller-specified node
+        * (such as ModifyTableState) and released when the node finishes
+        * processing.
+        */
+       *partition_tuple_slot = MakeTupleTableSlot();
+
        leaf_part_rri = *partitions;
        i = 0;
        foreach(cell, leaf_parts)
index c7dd148944eabf3506e856a6a542c3ca98dfdeb0..aa364707f8d321550eff2d182b349161370095dc 100644 (file)
@@ -329,7 +329,7 @@ ExecInsert(ModifyTableState *mtstate,
                         * Use the dedicated slot for that.
                         */
                        oldslot = slot;
-                       slot = estate->es_partition_tuple_slot;
+                       slot = mtstate->mt_partition_tuple_slot;
                        Assert(slot != NULL);
                        ExecSetSlotDescriptor(slot, RelationGetDescr(partrel));
                        ExecStoreTuple(tuple, slot, InvalidBuffer, true);
@@ -1738,6 +1738,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
                PartitionDispatch  *partition_dispatch_info;
                ResultRelInfo      *partitions;
                TupleConversionMap **partition_tupconv_maps;
+               TupleTableSlot     *partition_tuple_slot;
                int                                     num_parted,
                                                        num_partitions;
 
@@ -1745,21 +1746,15 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
                                                                           &partition_dispatch_info,
                                                                           &partitions,
                                                                           &partition_tupconv_maps,
+                                                                          &partition_tuple_slot,
                                                                           &num_parted, &num_partitions);
                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;
-
-               /*
-                * Initialize a dedicated slot to manipulate tuples of any given
-                * partition's rowtype.
-                */
-               estate->es_partition_tuple_slot = ExecInitExtraTupleSlot(estate);
+               mtstate->mt_partition_tuple_slot = partition_tuple_slot;
        }
-       else
-               estate->es_partition_tuple_slot = NULL;
 
        /*
         * Initialize any WITH CHECK OPTION constraints if needed.
@@ -2100,6 +2095,10 @@ ExecEndModifyTable(ModifyTableState *node)
                heap_close(resultRelInfo->ri_RelationDesc, NoLock);
        }
 
+       /* Release the standalone partition tuple descriptor, if any */
+       if (node->mt_partition_tuple_slot)
+               ExecDropSingleTupleTableSlot(node->mt_partition_tuple_slot);
+
        /*
         * Free the exprcontext
         */
index a3fa5f076714126fd23402a9ce2bd44f1c39483a..4a7074edd70e9ac00108ec73f4870180ea18a5ed 100644 (file)
@@ -217,6 +217,7 @@ extern void ExecSetupPartitionTupleRouting(Relation rel,
                                                           PartitionDispatch **pd,
                                                           ResultRelInfo **partitions,
                                                           TupleConversionMap ***tup_conv_maps,
+                                                          TupleTableSlot **partition_tuple_slot,
                                                           int *num_parted, int *num_partitions);
 extern int ExecFindPartition(ResultRelInfo *resultRelInfo,
                                  PartitionDispatch *pd,
index 486555eac4c867bc8779d6ce54da2f0963d5b130..0e05d472c90728e285429a566f249803855677fc 100644 (file)
@@ -384,9 +384,6 @@ typedef struct EState
        TupleTableSlot *es_trig_oldtup_slot;            /* for TriggerEnabled */
        TupleTableSlot *es_trig_newtup_slot;            /* for TriggerEnabled */
 
-       /* Slot used to manipulate a tuple after it is routed to a partition */
-       TupleTableSlot *es_partition_tuple_slot;
-
        /* Parameter info: */
        ParamListInfo es_param_list_info;       /* values of external params */
        ParamExecData *es_param_exec_vals;      /* values of internal params */
@@ -1165,6 +1162,7 @@ typedef struct ModifyTableState
        ResultRelInfo  *mt_partitions;  /* Per partition result relation */
        TupleConversionMap **mt_partition_tupconv_maps;
                                                                        /* Per partition tuple conversion map */
+       TupleTableSlot *mt_partition_tuple_slot;
 } ModifyTableState;
 
 /* ----------------