v32-0003-Row-pattern-recognition-patch-rewriter.patch
application/octet-stream
Filename: v32-0003-Row-pattern-recognition-patch-rewriter.patch
Type: application/octet-stream
Part: 2
Message:
Re: Row pattern recognition
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v32-0003
Subject: Row pattern recognition patch (rewriter).
| File | + | − |
|---|---|---|
| src/backend/utils/adt/ruleutils.c | 112 | 0 |
From 54e4464c49958398f5ceabd70dab0a823e33c563 Mon Sep 17 00:00:00 2001
From: Tatsuo Ishii <ishii@postgresql.org>
Date: Sat, 16 Aug 2025 17:33:32 +0900
Subject: [PATCH v32 3/9] Row pattern recognition patch (rewriter).
---
src/backend/utils/adt/ruleutils.c | 112 ++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3d6e6bdbfd2..902cd577c27 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -438,6 +438,10 @@ static void get_rule_groupingset(GroupingSet *gset, List *targetlist,
bool omit_parens, deparse_context *context);
static void get_rule_orderby(List *orderList, List *targetList,
bool force_colno, deparse_context *context);
+static void get_rule_pattern(List *patternVariable, List *patternRegexp,
+ bool force_colno, deparse_context *context);
+static void get_rule_define(List *defineClause, List *patternVariables,
+ bool force_colno, deparse_context *context);
static void get_rule_windowclause(Query *query, deparse_context *context);
static void get_rule_windowspec(WindowClause *wc, List *targetList,
deparse_context *context);
@@ -6739,6 +6743,67 @@ get_rule_orderby(List *orderList, List *targetList,
}
}
+/*
+ * Display a PATTERN clause.
+ */
+static void
+get_rule_pattern(List *patternVariable, List *patternRegexp,
+ bool force_colno, deparse_context *context)
+{
+ StringInfo buf = context->buf;
+ const char *sep;
+ ListCell *lc_var,
+ *lc_reg = list_head(patternRegexp);
+
+ sep = "";
+ appendStringInfoChar(buf, '(');
+ foreach(lc_var, patternVariable)
+ {
+ char *variable = strVal((String *) lfirst(lc_var));
+ char *regexp = NULL;
+
+ if (lc_reg != NULL)
+ {
+ regexp = strVal((String *) lfirst(lc_reg));
+
+ lc_reg = lnext(patternRegexp, lc_reg);
+ }
+
+ appendStringInfo(buf, "%s%s", sep, variable);
+ if (regexp !=NULL)
+ appendStringInfoString(buf, regexp);
+
+ sep = " ";
+ }
+ appendStringInfoChar(buf, ')');
+}
+
+/*
+ * Display a DEFINE clause.
+ */
+static void
+get_rule_define(List *defineClause, List *patternVariables,
+ bool force_colno, deparse_context *context)
+{
+ StringInfo buf = context->buf;
+ const char *sep;
+ ListCell *lc_var,
+ *lc_def;
+
+ sep = " ";
+ Assert(list_length(patternVariables) == list_length(defineClause));
+
+ forboth(lc_var, patternVariables, lc_def, defineClause)
+ {
+ char *varName = strVal(lfirst(lc_var));
+ TargetEntry *te = (TargetEntry *) lfirst(lc_def);
+
+ appendStringInfo(buf, "%s%s AS ", sep, varName);
+ get_rule_expr((Node *) te->expr, context, false);
+ sep = ",\n ";
+ }
+}
+
/*
* Display a WINDOW clause.
*
@@ -6819,6 +6884,7 @@ get_rule_windowspec(WindowClause *wc, List *targetList,
get_rule_orderby(wc->orderClause, targetList, false, context);
needspace = true;
}
+
/* framing clause is never inherited, so print unless it's default */
if (wc->frameOptions & FRAMEOPTION_NONDEFAULT)
{
@@ -6827,7 +6893,53 @@ get_rule_windowspec(WindowClause *wc, List *targetList,
get_window_frame_options(wc->frameOptions,
wc->startOffset, wc->endOffset,
context);
+ needspace = true;
}
+
+ /* RPR */
+ if (wc->rpSkipTo == ST_NEXT_ROW)
+ {
+ if (needspace)
+ appendStringInfoChar(buf, ' ');
+ appendStringInfoString(buf,
+ "\n AFTER MATCH SKIP TO NEXT ROW ");
+ needspace = true;
+ }
+ else if (wc->rpSkipTo == ST_PAST_LAST_ROW)
+ {
+ if (needspace)
+ appendStringInfoChar(buf, ' ');
+ appendStringInfoString(buf,
+ "\n AFTER MATCH SKIP PAST LAST ROW ");
+ needspace = true;
+ }
+ if (wc->initial)
+ {
+ if (needspace)
+ appendStringInfoChar(buf, ' ');
+ appendStringInfoString(buf, "\n INITIAL");
+ needspace = true;
+ }
+ if (wc->patternVariable)
+ {
+ if (needspace)
+ appendStringInfoChar(buf, ' ');
+ appendStringInfoString(buf, "\n PATTERN ");
+ get_rule_pattern(wc->patternVariable, wc->patternRegexp,
+ false, context);
+ needspace = true;
+ }
+
+ if (wc->defineClause)
+ {
+ if (needspace)
+ appendStringInfoChar(buf, ' ');
+ appendStringInfoString(buf, "\n DEFINE\n");
+ get_rule_define(wc->defineClause, wc->patternVariable,
+ false, context);
+ appendStringInfoChar(buf, ' ');
+ }
+
appendStringInfoChar(buf, ')');
}
--
2.25.1