On 2018/03/23 13:57, Pavan Deolasee wrote:
> On Fri, Mar 23, 2018 at 10:00 AM, Amit Langote wrote:
>> I managed to apply it by ignoring the errors, but couldn't get make check
>> to pass; attached regressions.diffs if you want to take a look.
>
> Thanks. Are you sure you're using a clean repo? I suspect you'd a previous
> version of the patch applied and hence the apply errors now. I also suspect
> that you may have made a mistake while resolving the conflicts while
> applying the patch (since a file at the same path existed). The failures
> also seem related to past version of the patch.
> 
> I just checked with a freshly checked out repo and the patches apply
> correctly on the current master and regression passes too.
> http://commitfest.cputube.org/ also reported success overnight.

You're right, I seem to have messed something up.  Sorry about the noise.

Also, it seems that the delta patch I sent in the last email didn't
contain all the changes I had to make.  It didn't contain, for example,
replacing adjust_and_expand_inherited_tlist() with
adjust_partition_tlist().  I guess you'll know when you rebase anyway.

Sorry that this is me coming a bit late to this thread, but I noticed a
few things in patch that I thought I should comment on.

1. White space errors

$ git diff master --check
src/backend/executor/execPartition.c:737: trailing whitespace.
+        /*
src/backend/executor/nodeMerge.c:90: indent with spaces.
+        PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing;
src/backend/executor/nodeMerge.c:116: trailing whitespace.
+
src/backend/executor/nodeMerge.c:565: new blank line at EOF.

2. Sorry if this has been discussed before, but is it OK to use AclMode
like this:

+
+    AclMode     mt_merge_subcommands;   /* Flags show which cmd types are
+                                         * present */

3. I think the comment above this should be updated to explain why the
map_index is being set to the leaf index in case of MERGE instead of the
subplan index as is done in case of plain UPDATE:

-            map_index = resultRelInfo - mtstate->resultRelInfo;
-            Assert(map_index >= 0 && map_index < mtstate->mt_nplans);
-            tupconv_map = tupconv_map_for_subplan(mtstate, map_index);
+            if (mtstate->operation == CMD_MERGE)
+            {
+                map_index = resultRelInfo->ri_PartitionLeafIndex;
+                Assert(mtstate->rootResultRelInfo == NULL);
+                tupconv_map = TupConvMapForLeaf(proute,
+                                mtstate->resultRelInfo,
+                                map_index);
+            }
+            else
+            {

4. Do you  think it would be possible at a later late to change this junk
attribute to contain something other than "tableoid"?

+                        if (operation == CMD_MERGE)
+                        {
+                            j->jf_otherJunkAttNo =
ExecFindJunkAttribute(j, "tableoid");
+                            if
(!AttributeNumberIsValid(j->jf_otherJunkAttNo))
+                                elog(ERROR, "could not find junk tableoid
column");
+
+                        }

Currently, it seems ExecMergeMatched will take this OID and look up the
partition (its ResultRelInfo) by calling ExecFindPartitionByOid which in
turn looks it up in the PartitionTupleRouting struct.  I'm imagining it
might be possible to instead return an integer that specifies "a partition
number".  Of course, nothing like that exists currently, but just curious
if we're going to be "stuck" with this junk attribute always containing
"tableoid".  Or maybe putting a "partition number" into the junk attribute
is not doable to begin with.

5. In ExecInitModifyTable, in the if (node->mergeActionList) block:

+
+        /* initialize slot for the existing tuple */
+        mtstate->mt_existing = ExecInitExtraTupleSlot(estate, NULL);

Maybe a good idea to Assert that mt_existing is NULL before.  Also, why
not set the slot's descriptor right away if tuple routing is not going to
be used.  I did it that way in the ON CONFLICT DO UPDATE patch.

6. I see that there is a slot called mergeSlot that becomes part of
ResultRelInfo of the table (partition) via ri_MergeState.  That means we
might end up creating as many slots as there are partitions (* number of
actions?).  Can't we have just one, say, mt_mergeproj in ModifyTableState
similar to mt_conflproj and just reset its descriptor before use.  I guess
reset will have happen before carrying out an action applied to a given
partition.  When I tried that (see attached delta), nothing got broken.

Thanks,
Amit
diff --git a/src/backend/executor/execPartition.c 
b/src/backend/executor/execPartition.c
index 86596b5a79..936e8e7e5b 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -681,9 +681,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
                        List       *matchedActionStates = NIL;
                        List       *notMatchedActionStates = NIL;
 
-                       leaf_part_rri->ri_mergeState->mergeSlot =
-                               ExecInitExtraTupleSlot(estate, NULL);
-
                        foreach (l, node->mergeActionList)
                        {
                                MergeAction *action = lfirst_node(MergeAction, 
l);
@@ -713,11 +710,9 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
 
                                /* build action projection state */
                                econtext = mtstate->ps.ps_ExprContext;
-                               
ExecSetSlotDescriptor(leaf_part_rri->ri_mergeState->mergeSlot,
-                                                                         
action_state->tupDesc);
                                action_state->proj =
                                        ExecBuildProjectionInfo(conv_tl, 
econtext,
-                                                       
leaf_part_rri->ri_mergeState->mergeSlot,
+                                                       mtstate->mt_mergeproj,
                                                        &mtstate->ps,
                                                        partrelDesc);
 
diff --git a/src/backend/executor/nodeMerge.c b/src/backend/executor/nodeMerge.c
index fed10db520..560fd5cf91 100644
--- a/src/backend/executor/nodeMerge.c
+++ b/src/backend/executor/nodeMerge.c
@@ -202,8 +202,7 @@ lmerge_matched:;
                                 * Project, no need for any other tasks prior 
to the
                                 * ExecUpdate.
                                 */
-                               
ExecSetSlotDescriptor(resultRelInfo->ri_mergeState->mergeSlot,
-                                                                         
action->tupDesc);
+                               ExecSetSlotDescriptor(mtstate->mt_mergeproj, 
action->tupDesc);
                                ExecProject(action->proj);
 
                                /*
@@ -212,7 +211,7 @@ lmerge_matched:;
                                 * attribute.
                                 */
                                slot = ExecUpdate(mtstate, tupleid, NULL,
-                                                                 
resultRelInfo->ri_mergeState->mergeSlot,
+                                                                 
mtstate->mt_mergeproj,
                                                                  slot, 
epqstate, estate,
                                                                  
&tuple_updated, &hufd,
                                                                  action, 
mtstate->canSetTag);
@@ -444,15 +443,14 @@ ExecMergeNotMatched(ModifyTableState *mtstate, EState 
*estate,
                                 * Project, no need for any other tasks prior 
to the
                                 * ExecInsert.
                                 */
-                               
ExecSetSlotDescriptor(resultRelInfo->ri_mergeState->mergeSlot,
-                                                                         
action->tupDesc);
+                               ExecSetSlotDescriptor(mtstate->mt_mergeproj, 
action->tupDesc);
                                ExecProject(action->proj);
 
                                /*
                                 * ExecPrepareTupleRouting may modify the 
passed-in slot. Hence
                                 * pass a local reference so that action->slot 
is not modified.
                                 */
-                               myslot = 
resultRelInfo->ri_mergeState->mergeSlot;
+                               myslot = mtstate->mt_mergeproj;
 
                                /* Prepare for tuple routing if needed. */
                                if (proute)
diff --git a/src/backend/executor/nodeModifyTable.c 
b/src/backend/executor/nodeModifyTable.c
index 4927bfebfa..2672a581a9 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -2668,8 +2668,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, 
int eflags)
                mtstate->mt_existing = ExecInitExtraTupleSlot(estate, NULL);
 
                /* initialise slot for merge actions */
-               resultRelInfo->ri_mergeState->mergeSlot =
-                       ExecInitExtraTupleSlot(estate, NULL);
+               mtstate->mt_mergeproj = ExecInitExtraTupleSlot(estate, NULL);
 
                /*
                 * Create a MergeActionState for each action on the 
mergeActionList
@@ -2691,13 +2690,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, 
int eflags)
                        tupDesc = ExecTypeFromTL((List *) action->targetList,
                                        
resultRelInfo->ri_RelationDesc->rd_rel->relhasoids);
                        action_state->tupDesc = tupDesc;
-                       
ExecSetSlotDescriptor(resultRelInfo->ri_mergeState->mergeSlot,
-                                                                 
action_state->tupDesc);
 
                        /* build action projection state */
                        action_state->proj =
                                ExecBuildProjectionInfo(action->targetList, 
econtext,
-                                               
resultRelInfo->ri_mergeState->mergeSlot, &mtstate->ps,
+                                               mtstate->mt_mergeproj, 
&mtstate->ps,
                                                
resultRelInfo->ri_RelationDesc->rd_att);
 
                        /*
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 36885ff888..13a81c88d1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -369,8 +369,6 @@ typedef struct MergeState
        List               *matchedActionStates;
        /* List of MERGE NOT MATCHED action states */
        List               *notMatchedActionStates;
-       /* Slot for MERGE actions */
-       TupleTableSlot *mergeSlot;
 } MergeState;
 
 /*
@@ -1065,6 +1063,8 @@ typedef struct ModifyTableState
        List       *mt_excludedtlist;   /* the excluded pseudo relation's tlist 
 */
        TupleTableSlot *mt_conflproj;   /* CONFLICT ... SET ... projection 
target */
 
+       TupleTableSlot *mt_mergeproj;   /* MERGE action projection target */
+
        /* Tuple-routing support info */
        struct PartitionTupleRouting *mt_partition_tuple_routing;
 

Reply via email to