diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 27 | ||||
-rw-r--r-- | src/backend/executor/execPartition.c | 6 | ||||
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 6 |
3 files changed, 33 insertions, 6 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 00bbcea2a5a..9ed8cd35380 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -984,12 +984,16 @@ InitPlan(QueryDesc *queryDesc, int eflags) * For INSERT ON CONFLICT, the result relation is required to support the * onConflictAction, regardless of whether a conflict actually occurs. * + * For MERGE, mergeActions is the list of actions that may be performed. The + * result relation is required to support every action, regardless of whether + * or not they are all executed. + * * Note: when changing this function, you probably also need to look at * CheckValidRowMarkRel. */ void CheckValidResultRelNew(ResultRelInfo *resultRelInfo, CmdType operation, - OnConflictAction onConflictAction) + OnConflictAction onConflictAction, List *mergeActions) { Relation resultRel = resultRelInfo->ri_RelationDesc; TriggerDesc *trigDesc = resultRel->trigdesc; @@ -1003,7 +1007,24 @@ CheckValidResultRelNew(ResultRelInfo *resultRelInfo, CmdType operation, { case RELKIND_RELATION: case RELKIND_PARTITIONED_TABLE: - CheckCmdReplicaIdentity(resultRel, operation); + + /* + * For MERGE, check that the target relation supports each action. + * For other operations, just check the operation itself. + */ + if (operation == CMD_MERGE) + { + ListCell *lc; + + foreach(lc, mergeActions) + { + MergeAction *action = (MergeAction *) lfirst(lc); + + CheckCmdReplicaIdentity(resultRel, action->commandType); + } + } + else + CheckCmdReplicaIdentity(resultRel, operation); /* * For INSERT ON CONFLICT DO UPDATE, additionally check that the @@ -1136,7 +1157,7 @@ CheckValidResultRelNew(ResultRelInfo *resultRelInfo, CmdType operation, void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation) { - return CheckValidResultRelNew(resultRelInfo, operation, ONCONFLICT_NONE); + return CheckValidResultRelNew(resultRelInfo, operation, ONCONFLICT_NONE, NIL); } /* diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 535ae2f09ff..9fb90b32858 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -364,7 +364,8 @@ ExecFindPartition(ModifyTableState *mtstate, /* Verify this ResultRelInfo allows INSERTs */ CheckValidResultRelNew(rri, CMD_INSERT, - node ? node->onConflictAction : ONCONFLICT_NONE); + node ? node->onConflictAction : ONCONFLICT_NONE, + NIL); /* * Initialize information needed to insert this and @@ -531,7 +532,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * required when the operation is CMD_UPDATE. */ CheckValidResultRelNew(leaf_part_rri, CMD_INSERT, - node ? node->onConflictAction : ONCONFLICT_NONE); + node ? node->onConflictAction : ONCONFLICT_NONE, + NIL); /* * Open partition indices. The user may have asked to check for conflicts diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index fc10729a6ef..8c8b895939c 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -4220,6 +4220,10 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) foreach(l, node->resultRelations) { Index resultRelation = lfirst_int(l); + List *mergeActions = NIL; + + if (node->mergeActionLists) + mergeActions = list_nth(node->mergeActionLists, i); if (resultRelInfo != mtstate->rootResultRelInfo) { @@ -4242,7 +4246,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * Verify result relation is a valid target for the current operation */ CheckValidResultRelNew(resultRelInfo, operation, - node->onConflictAction); + node->onConflictAction, mergeActions); resultRelInfo++; i++; |