Ruleutils_17 Add support for MERGE ... WHEN NOT MATCHED BY SOURCE

Relevant PG commit:
0294df2f1f842dfb0eed79007b21016f486a3c6c
0294df2f1f
m3hm3t/pg17_isolation_test_cmd_from
naisila 2024-07-11 14:12:16 +02:00
parent d2648f4988
commit 6b4889f7b4
No known key found for this signature in database
GPG Key ID: A824BA9862D73E6D
1 changed files with 39 additions and 2 deletions

View File

@ -3752,6 +3752,7 @@ get_merge_query_def(Query *query, deparse_context *context,
StringInfo buf = context->buf;
RangeTblEntry *rte;
ListCell *lc;
bool haveNotMatchedBySource;
/* Insert the WITH clause if given */
get_with_clause(query, context);
@ -3801,7 +3802,26 @@ get_merge_query_def(Query *query, deparse_context *context,
get_from_clause(query, " USING ", context);
appendContextKeyword(context, " ON ",
-PRETTYINDENT_STD, PRETTYINDENT_STD, 2);
get_rule_expr(query->jointree->quals, context, false);
get_rule_expr(query->mergeJoinCondition, context, false);
/*
* Test for any NOT MATCHED BY SOURCE actions. If there are none, then
* any NOT MATCHED BY TARGET actions are output as "WHEN NOT MATCHED", per
* SQL standard. Otherwise, we have a non-SQL-standard query, so output
* "BY SOURCE" / "BY TARGET" qualifiers for all NOT MATCHED actions, to be
* more explicit.
*/
haveNotMatchedBySource = false;
foreach(lc, query->mergeActionList)
{
MergeAction *action = lfirst_node(MergeAction, lc);
if (action->matchKind == MERGE_WHEN_NOT_MATCHED_BY_SOURCE)
{
haveNotMatchedBySource = true;
break;
}
}
/* Print each merge action */
foreach(lc, query->mergeActionList)
@ -3810,7 +3830,24 @@ get_merge_query_def(Query *query, deparse_context *context,
appendContextKeyword(context, " WHEN ",
-PRETTYINDENT_STD, PRETTYINDENT_STD, 2);
appendStringInfo(buf, "%sMATCHED", action->matched ? "" : "NOT ");
switch (action->matchKind)
{
case MERGE_WHEN_MATCHED:
appendStringInfo(buf, "MATCHED");
break;
case MERGE_WHEN_NOT_MATCHED_BY_SOURCE:
appendStringInfo(buf, "NOT MATCHED BY SOURCE");
break;
case MERGE_WHEN_NOT_MATCHED_BY_TARGET:
if (haveNotMatchedBySource)
appendStringInfo(buf, "NOT MATCHED BY TARGET");
else
appendStringInfo(buf, "NOT MATCHED");
break;
default:
elog(ERROR, "unrecognized matchKind: %d",
(int) action->matchKind);
}
if (action->qual)
{