aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/appendinfo.c19
-rw-r--r--src/backend/optimizer/util/pathnode.c11
-rw-r--r--src/backend/optimizer/util/plancat.c4
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;