From a56b8d8d1bf3aaff3e38b072052ecdbc8e8c4615 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Tue, 7 Jul 2026 10:36:09 +0900 Subject: [PATCH] Improve row pattern recognition comments and documentation Address further review comments from Jian He on the row pattern recognition code: - Correct the nfa_eval_var_match header. A NULL varMatched does not mean "no DEFINE clauses exist"; it forces every VAR to not match, and nfa_match() is called that way at a frame boundary and at partition-end finalization. Describe that actual behavior instead. - Drop the duplicated sentence atop the nfa_match loop. The END-chain advance it described is already covered by the function header comment and the inline block below, so reduce it to a single line. - Move the note about the unsupported MEASURES and SUBSET subclauses out of the WINDOW clause description and into a new "Row Pattern Recognition" subsection under Compatibility, where the other missing-standard-feature notes live. Suggested-by: Jian He --- doc/src/sgml/ref/select.sgml | 20 +++++++++++++------- src/backend/executor/execRPR.c | 11 ++++------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 00f469a2ce0..71d03e4a4c7 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -1208,13 +1208,6 @@ DEFINE definition_variable_name AS so this limit is rarely reached in practice. - - The SQL standard defines more subclauses: MEASURES - and SUBSET. They are not currently supported - in PostgreSQL. Also in the standard there are - more variations in AFTER MATCH clause. - - The purpose of a WINDOW clause is to specify the behavior of window functions appearing in the query's @@ -2328,6 +2321,19 @@ SELECT 2+2; + + Row Pattern Recognition + + + PostgreSQL supports row pattern recognition + within the WINDOW clause. The SQL standard defines + more subclauses: MEASURES and + SUBSET. They are not currently supported + in PostgreSQL. Also in the standard there are + more variations in the AFTER MATCH clause. + + + Nonstandard Clauses diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 0127ae82925..e0d9637b3e5 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -754,8 +754,9 @@ nfa_absorb_contexts(WindowAggState *winstate) * Evaluate if a VAR element matches the current row. * * varMatched is a pre-evaluated boolean array indexed by varId, computed - * once per row by evaluating all DEFINE expressions. NULL means no DEFINE - * clauses exist (only possible during early development/testing). + * once per row by evaluating all DEFINE expressions. A NULL varMatched makes + * every VAR not match; nfa_match() is called that way to force a mismatch at a + * frame boundary and at partition-end finalization. * * Per ISO/IEC 19075-5 Feature R020, pattern variables not listed in DEFINE * are implicitly TRUE -- they match every row. This is checked via @@ -808,11 +809,7 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched, RPRNFAState *state; RPRNFAState *nextState; - /* - * Evaluate VAR elements against current row. For VARs that reach max - * count with END next, advance through the chain of END elements inline - * so absorb phase can compare states at comparison points. - */ + /* Evaluate VAR elements against current row. */ for (state = ctx->states; state != NULL; state = nextState) { RPRPatternElement *elem = &elements[state->elemIdx];