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;