From e208f2fb3c2eaac6f7932f8c15afab789679e5ee Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 16 Mar 2018 14:29:28 -0300 Subject: [PATCH v5 1/3] Simplify ExecInsert API re. ON CONFLICT data Instead of passing the ON CONFLICT-related members of ModifyTableState into ExecInsert(), we can have that routine obtain them from the node, since that is already an argument into the function. While at it, remove arbiterIndexes from ModifyTableState, since that's just a copy of the list already in the ModifyTable node, to which the state node already has access. --- src/backend/executor/execPartition.c | 4 ++-- src/backend/executor/nodeModifyTable.c | 34 +++++++++++++++++++--------------- src/include/nodes/execnodes.h | 3 --- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index f6fe7cd61d..ce9a4e16cf 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -363,8 +363,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, if (partrel->rd_rel->relhasindex && leaf_part_rri->ri_IndexRelationDescs == NULL) ExecOpenIndices(leaf_part_rri, - (mtstate != NULL && - mtstate->mt_onconflict != ONCONFLICT_NONE)); + (node != NULL && + node->onConflictAction != ONCONFLICT_NONE)); /* * Build WITH CHECK OPTION constraints for the partition. Note that we diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 3332ae4bf3..745be7ba30 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -258,8 +258,6 @@ static TupleTableSlot * ExecInsert(ModifyTableState *mtstate, TupleTableSlot *slot, TupleTableSlot *planSlot, - List *arbiterIndexes, - OnConflictAction onconflict, EState *estate, bool canSetTag) { @@ -271,6 +269,8 @@ ExecInsert(ModifyTableState *mtstate, List *recheckIndexes = NIL; TupleTableSlot *result = NULL; TransitionCaptureState *ar_insert_trig_tcs; + ModifyTable *node = (ModifyTable *) mtstate->ps.plan; + OnConflictAction onconflict = node->onConflictAction; /* * get the heap tuple out of the tuple table slot, making sure we have a @@ -455,6 +455,7 @@ ExecInsert(ModifyTableState *mtstate, else { WCOKind wco_kind; + bool check_partition_constr; /* * We always check the partition constraint, including when the tuple @@ -463,8 +464,7 @@ ExecInsert(ModifyTableState *mtstate, * trigger might modify the tuple such that the partition constraint * is no longer satisfied, so we need to check in that case. */ - bool check_partition_constr = - (resultRelInfo->ri_PartitionCheck != NIL); + check_partition_constr = (resultRelInfo->ri_PartitionCheck != NIL); /* * Constraints might reference the tableoid column, so initialize @@ -510,6 +510,9 @@ ExecInsert(ModifyTableState *mtstate, uint32 specToken; ItemPointerData conflictTid; bool specConflict; + List *arbiterIndexes; + + arbiterIndexes = node->arbiterIndexes; /* * Do a non-conclusive check for conflicts first. @@ -627,7 +630,7 @@ ExecInsert(ModifyTableState *mtstate, if (resultRelInfo->ri_NumIndices > 0) recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false, NULL, - arbiterIndexes); + NIL); } } @@ -1217,8 +1220,8 @@ lreplace:; Assert(mtstate->rootResultRelInfo != NULL); estate->es_result_relation_info = mtstate->rootResultRelInfo; - ret_slot = ExecInsert(mtstate, slot, planSlot, NULL, - ONCONFLICT_NONE, estate, canSetTag); + ret_slot = ExecInsert(mtstate, slot, planSlot, + estate, canSetTag); /* * Revert back the active result relation and the active @@ -1582,6 +1585,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, static void fireBSTriggers(ModifyTableState *node) { + ModifyTable *plan = (ModifyTable *) node->ps.plan; ResultRelInfo *resultRelInfo = node->resultRelInfo; /* @@ -1596,7 +1600,7 @@ fireBSTriggers(ModifyTableState *node) { case CMD_INSERT: ExecBSInsertTriggers(node->ps.state, resultRelInfo); - if (node->mt_onconflict == ONCONFLICT_UPDATE) + if (plan->onConflictAction == ONCONFLICT_UPDATE) ExecBSUpdateTriggers(node->ps.state, resultRelInfo); break; @@ -1640,12 +1644,13 @@ getTargetResultRelInfo(ModifyTableState *node) static void fireASTriggers(ModifyTableState *node) { + ModifyTable *plan = (ModifyTable *) node->ps.plan; ResultRelInfo *resultRelInfo = getTargetResultRelInfo(node); switch (node->operation) { case CMD_INSERT: - if (node->mt_onconflict == ONCONFLICT_UPDATE) + if (plan->onConflictAction == ONCONFLICT_UPDATE) ExecASUpdateTriggers(node->ps.state, resultRelInfo, node->mt_oc_transition_capture); @@ -1673,6 +1678,7 @@ fireASTriggers(ModifyTableState *node) static void ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) { + ModifyTable *plan = (ModifyTable *) mtstate->ps.plan; ResultRelInfo *targetRelInfo = getTargetResultRelInfo(mtstate); /* Check for transition tables on the directly targeted relation. */ @@ -1680,8 +1686,8 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) MakeTransitionCaptureState(targetRelInfo->ri_TrigDesc, RelationGetRelid(targetRelInfo->ri_RelationDesc), mtstate->operation); - if (mtstate->operation == CMD_INSERT && - mtstate->mt_onconflict == ONCONFLICT_UPDATE) + if (plan->operation == CMD_INSERT && + plan->onConflictAction == ONCONFLICT_UPDATE) mtstate->mt_oc_transition_capture = MakeTransitionCaptureState(targetRelInfo->ri_TrigDesc, RelationGetRelid(targetRelInfo->ri_RelationDesc), @@ -2052,7 +2058,6 @@ ExecModifyTable(PlanState *pstate) { case CMD_INSERT: slot = ExecInsert(node, slot, planSlot, - node->mt_arbiterindexes, node->mt_onconflict, estate, node->canSetTag); break; case CMD_UPDATE: @@ -2136,8 +2141,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->mt_arowmarks = (List **) palloc0(sizeof(List *) * nplans); mtstate->mt_nplans = nplans; - mtstate->mt_onconflict = node->onConflictAction; - mtstate->mt_arbiterindexes = node->arbiterIndexes; /* set up epqstate with dummy subplan data for the moment */ EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, node->epqParam); @@ -2180,7 +2183,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) if (resultRelInfo->ri_RelationDesc->rd_rel->relhasindex && operation != CMD_DELETE && resultRelInfo->ri_IndexRelationDescs == NULL) - ExecOpenIndices(resultRelInfo, mtstate->mt_onconflict != ONCONFLICT_NONE); + ExecOpenIndices(resultRelInfo, + node->onConflictAction != ONCONFLICT_NONE); /* * If this is an UPDATE and a BEFORE UPDATE trigger is present, the diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index a953820f43..3b926014b6 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -989,9 +989,6 @@ typedef struct ModifyTableState List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */ EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ bool fireBSTriggers; /* do we need to fire stmt triggers? */ - OnConflictAction mt_onconflict; /* ON CONFLICT type */ - List *mt_arbiterindexes; /* unique index OIDs to arbitrate taking - * alt path */ TupleTableSlot *mt_existing; /* slot to store existing target tuple in */ List *mt_excludedtlist; /* the excluded pseudo relation's tlist */ TupleTableSlot *mt_conflproj; /* CONFLICT ... SET ... projection target */ -- 2.11.0