diff options
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r-- | src/backend/optimizer/util/appendinfo.c | 19 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 11 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 4 |
3 files changed, 23 insertions, 11 deletions
diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c index 2f06fa743c2..9d4bb470270 100644 --- a/src/backend/optimizer/util/appendinfo.c +++ b/src/backend/optimizer/util/appendinfo.c @@ -774,8 +774,8 @@ add_row_identity_var(PlannerInfo *root, Var *orig_var, Assert(orig_var->varlevelsup == 0); /* - * If we're doing non-inherited UPDATE/DELETE, there's little need for - * ROWID_VAR shenanigans. Just shove the presented Var into the + * If we're doing non-inherited UPDATE/DELETE/MERGE, there's little need + * for ROWID_VAR shenanigans. Just shove the presented Var into the * processed_tlist, and we're done. */ if (rtindex == root->parse->resultRelation) @@ -862,14 +862,16 @@ add_row_identity_columns(PlannerInfo *root, Index rtindex, char relkind = target_relation->rd_rel->relkind; Var *var; - Assert(commandType == CMD_UPDATE || commandType == CMD_DELETE); + Assert(commandType == CMD_UPDATE || commandType == CMD_DELETE || commandType == CMD_MERGE); - if (relkind == RELKIND_RELATION || + if (commandType == CMD_MERGE || + relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW || relkind == RELKIND_PARTITIONED_TABLE) { /* - * Emit CTID so that executor can find the row to update or delete. + * Emit CTID so that executor can find the row to merge, update or + * delete. */ var = makeVar(rtindex, SelfItemPointerAttributeNumber, @@ -942,8 +944,11 @@ distribute_row_identity_vars(PlannerInfo *root) RelOptInfo *target_rel; ListCell *lc; - /* There's nothing to do if this isn't an inherited UPDATE/DELETE. */ - if (parse->commandType != CMD_UPDATE && parse->commandType != CMD_DELETE) + /* + * There's nothing to do if this isn't an inherited UPDATE/DELETE/MERGE. + */ + if (parse->commandType != CMD_UPDATE && parse->commandType != CMD_DELETE && + parse->commandType != CMD_MERGE) { Assert(root->row_identity_vars == NIL); return; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 5c32c96b71c..99df76b6b71 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -3620,6 +3620,7 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, * 'rowMarks' is a list of PlanRowMarks (non-locking only) * 'onconflict' is the ON CONFLICT clause, or NULL * 'epqParam' is the ID of Param for EvalPlanQual re-eval + * 'mergeActionLists' is a list of lists of MERGE actions (one per rel) */ ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, @@ -3631,13 +3632,14 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, - int epqParam) + List *mergeActionLists, int epqParam) { ModifyTablePath *pathnode = makeNode(ModifyTablePath); - Assert(operation == CMD_UPDATE ? - list_length(resultRelations) == list_length(updateColnosLists) : - updateColnosLists == NIL); + Assert(operation == CMD_MERGE || + (operation == CMD_UPDATE ? + list_length(resultRelations) == list_length(updateColnosLists) : + updateColnosLists == NIL)); Assert(withCheckOptionLists == NIL || list_length(resultRelations) == list_length(withCheckOptionLists)); Assert(returningLists == NIL || @@ -3697,6 +3699,7 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, pathnode->rowMarks = rowMarks; pathnode->onconflict = onconflict; pathnode->epqParam = epqParam; + pathnode->mergeActionLists = mergeActionLists; return pathnode; } diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index a5002ad8955..df97b799174 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -2167,6 +2167,10 @@ has_row_triggers(PlannerInfo *root, Index rti, CmdType event) trigDesc->trig_delete_before_row)) result = true; break; + /* There is no separate event for MERGE, only INSERT/UPDATE/DELETE */ + case CMD_MERGE: + result = false; + break; default: elog(ERROR, "unrecognized CmdType: %d", (int) event); break; |