From: Tatsuo Ishii Date: Tue, 31 Dec 2024 08:53:27 +0900 Subject: [PATCH v27 6/9] Row pattern recognition patch (docs). --- doc/src/sgml/advanced.sgml | 82 ++++++++++++++++++++++++++++++++++++ doc/src/sgml/func.sgml | 54 ++++++++++++++++++++++++ doc/src/sgml/ref/select.sgml | 38 ++++++++++++++++- 3 files changed, 172 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml index 755c9f1485..b0b1d1c51e 100644 --- a/doc/src/sgml/advanced.sgml +++ b/doc/src/sgml/advanced.sgml @@ -537,6 +537,88 @@ WHERE pos < 3; rank less than 3. + + Row pattern common syntax can be used to perform row pattern recognition + in a query. The row pattern common syntax includes two sub + clauses: DEFINE + and PATTERN. DEFINE defines + definition variables along with an expression. The expression must be a + logical expression, which means it must + return TRUE, FALSE + or NULL. The expression may comprise column references + and functions. Window functions, aggregate functions and subqueries are + not allowed. An example of DEFINE is as follows. + + +DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price), + DOWN AS price < PREV(price) + + + Note that PREV returns the price column in the + previous row if it's called in a context of row pattern recognition. Thus in + the second line the definition variable "UP" is TRUE + when the price column in the current row is greater than the price column + in the previous row. Likewise, "DOWN" is TRUE when when + the price column in the current row is lower than the price column in the + previous row. + + + Once DEFINE exists, PATTERN can be + used. PATTERN defines a sequence of rows that satisfies + certain conditions. For example following PATTERN + defines that a row starts with the condition "LOWPRICE", then one or more + rows satisfy "UP" and finally one or more rows satisfy "DOWN". Note that + "+" means one or more matches. Also you can use "*", which means zero or + more matches. If a sequence of rows which satisfies the PATTERN is found, + in the starting row of the sequence of rows all window functions and + aggregates are shown in the target list. Note that aggregations only look + into the matched rows, rather than whole frame. On the second or + subsequent rows all window functions are NULL. Aggregates are NULL or 0 + (count case) depending on its aggregation definition. For rows that do not + match on the PATTERN, all window functions and aggregates are shown AS + NULL too, except count showing 0. This is because the rows do not match, + thus they are in an empty frame. Example of a SELECT + using the DEFINE and PATTERN clause + is as follows. + + +SELECT company, tdate, price, + first_value(price) OVER w, + max(price) OVER w, + count(price) OVER w +FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + INITIAL + PATTERN (LOWPRICE UP+ DOWN+) + DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + + + company | tdate | price | first_value | max | count +----------+------------+-------+-------------+-----+------- + company1 | 2023-07-01 | 100 | 100 | 200 | 4 + company1 | 2023-07-02 | 200 | | | 0 + company1 | 2023-07-03 | 150 | | | 0 + company1 | 2023-07-04 | 140 | | | 0 + company1 | 2023-07-05 | 150 | | | 0 + company1 | 2023-07-06 | 90 | 90 | 130 | 4 + company1 | 2023-07-07 | 110 | | | 0 + company1 | 2023-07-08 | 130 | | | 0 + company1 | 2023-07-09 | 120 | | | 0 + company1 | 2023-07-10 | 130 | | | 0 +(10 rows) + + + When a query involves multiple window functions, it is possible to write out each one with a separate OVER clause, but this is diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 47370e581a..17a38c4046 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -23338,6 +23338,7 @@ SELECT count(*) FROM sometable; returns NULL if there is no such row. + @@ -23377,6 +23378,59 @@ SELECT count(*) FROM sometable; Other frame specifications can be used to obtain other effects. + + Row pattern recognition navigation functions are listed in + . These functions + can be used to describe DEFINE clause of Row pattern recognition. + + + + Row Pattern Navigation Functions + + + + + Function + + + Description + + + + + + + + + prev + + prev ( value anyelement ) + anyelement + + + Returns the column value at the previous row; + returns NULL if there is no previous row in the window frame. + + + + + + + next + + next ( value anyelement ) + anyelement + + + Returns the column value at the next row; + returns NULL if there is no next row in the window frame. + + + + + +
+ The SQL standard defines a RESPECT NULLS or diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index d7089eac0b..7e1c9989ba 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -969,8 +969,8 @@ WINDOW window_name AS ( frame_clause can be one of -{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ] -{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ] +{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ] [row_pattern_common_syntax] +{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ] [row_pattern_common_syntax] where frame_start @@ -1077,6 +1077,40 @@ EXCLUDE NO OTHERS a given peer group will be in the frame or excluded from it. + + The + optional row_pattern_common_syntax + defines the row pattern recognition condition for + this + window. row_pattern_common_syntax + includes following subclauses. AFTER MATCH SKIP PAST LAST + ROW or AFTER MATCH SKIP TO NEXT ROW controls + how to proceed to next row position after a match + found. With AFTER MATCH SKIP PAST LAST ROW (the + default) next row position is next to the last row of previous match. On + the other hand, with AFTER MATCH SKIP TO NEXT ROW next + row position is always next to the last row of previous + match. DEFINE defines definition variables along with a + boolean expression. PATTERN defines a sequence of rows + that satisfies certain conditions using variables defined + in DEFINE clause. If the variable is not defined in + the DEFINE clause, it is implicitly assumed + following is defined in the DEFINE clause. + + +variable_name AS TRUE + + + Note that the maximu number of variables defined + in DEFINE clause is 26. + + +[ AFTER MATCH SKIP PAST LAST ROW | AFTER MATCH SKIP TO NEXT ROW ] +PATTERN pattern_variable_name[+] [, ...] +DEFINE definition_varible_name AS expression [, ...] + + + The purpose of a WINDOW clause is to specify the behavior of window functions appearing in the query's -- 2.25.1 ----Next_Part(Tue_Dec_31_08_57_07_2024_963)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v27-0007-Row-pattern-recognition-patch-tests.patch"