nocfbot-0004-Reclassify-DEFINE-qualifier-check.txt

text/plain

Filename: nocfbot-0004-Reclassify-DEFINE-qualifier-check.txt
Type: text/plain
Part: 3
Message: Re: Row pattern recognition
From af9f50ed1522bda716d10edf932bc5aeb4b0cb37 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Tue, 5 May 2026 11:36:53 +0900
Subject: [PATCH 04/11] Reclassify DEFINE qualifier check and reword diagnostic
 to "expression"

Split the pre-check into three branches: pattern variable ->
FEATURE_NOT_SUPPORTED, range variable (via refnameNamespaceItem) ->
SYNTAX_ERROR, anything else -> fall through to normal resolution.
Reword "qualified column reference" to "qualified expression" since
the quoted token may include an indirection target on composite
types (e.g. (A.items).amount).
---
 src/backend/parser/parse_expr.c        | 31 +++++++---
 src/test/regress/expected/rpr_base.out | 80 +++++++++++++++++++++++---
 src/test/regress/sql/rpr_base.sql      | 61 ++++++++++++++++++--
 3 files changed, 153 insertions(+), 19 deletions(-)

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index f145342e1fb..69148328719 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -628,11 +628,24 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 	if (node != NULL)
 		return node;
 
-	/*
-	 * Qualified column references in DEFINE are not supported.  This covers
-	 * both FROM-clause range variables (prohibited by §6.5) and pattern
-	 * variable qualified names (e.g. UP.price), which are valid per §4.16
-	 * but not yet implemented.
+	/*----------
+	 * Qualified references in DEFINE need a tri-classification:
+	 *
+	 *	  pattern variable qualifier (e.g. UP.price): valid per 19075-5 4.16
+	 *	  but not yet implemented -- raise FEATURE_NOT_SUPPORTED.
+	 *
+	 *	  FROM-clause range variable qualifier: prohibited by 19075-5 6.5
+	 *	  -- raise SYNTAX_ERROR.
+	 *
+	 *	  any other qualifier (typo, undefined name): fall through and let
+	 *	  normal column resolution produce a sensible error.
+	 *
+	 * The quoted text reflects only the ColumnRef portion; a trailing field
+	 * selection on a composite type (e.g. ".amount" in "(A.items).amount")
+	 * lives in the surrounding A_Indirection node and is not included here.
+	 * That can be revisited when MEASURES support adds indirection-aware
+	 * traversal.
+	 *----------
 	 */
 	if (pstate->p_expr_kind == EXPR_KIND_RPR_DEFINE &&
 		list_length(cref->fields) != 1)
@@ -653,15 +666,17 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 		if (is_pattern_var)
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-					 errmsg("pattern variable qualified column reference \"%s\" is not supported in DEFINE clause",
+					 errmsg("pattern variable qualified expression \"%s\" is not supported in DEFINE clause",
 							NameListToString(cref->fields)),
 					 parser_errposition(pstate, cref->location)));
-		else
+		else if (refnameNamespaceItem(pstate, NULL, qualifier,
+									  cref->location, NULL) != NULL)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
-					 errmsg("range variable qualified column reference \"%s\" is not allowed in DEFINE clause",
+					 errmsg("range variable qualified expression \"%s\" is not allowed in DEFINE clause",
 							NameListToString(cref->fields)),
 					 parser_errposition(pstate, cref->location)));
+		/* else: unknown qualifier -- fall through to normal resolution */
 	}
 
 	/*----------
diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out
index a63211ff364..86abb96c177 100644
--- a/src/test/regress/expected/rpr_base.out
+++ b/src/test/regress/expected/rpr_base.out
@@ -3074,10 +3074,10 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS A.val > 0
 );
-ERROR:  pattern variable qualified column reference "a.val" is not supported in DEFINE clause
+ERROR:  pattern variable qualified expression "a.val" is not supported in DEFINE clause
 LINE 7:     DEFINE A AS A.val > 0
                         ^
--- Expected: ERROR: pattern variable qualified column reference "a.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "a.val" is not supported
 -- PATTERN-only variable qualified name: not supported even without DEFINE entry
 SELECT COUNT(*) OVER w
 FROM rpr_err
@@ -3087,10 +3087,10 @@ WINDOW w AS (
     PATTERN (A+ B+)
     DEFINE A AS B.val > 0
 );
-ERROR:  pattern variable qualified column reference "b.val" is not supported in DEFINE clause
+ERROR:  pattern variable qualified expression "b.val" is not supported in DEFINE clause
 LINE 7:     DEFINE A AS B.val > 0
                         ^
--- Expected: ERROR: pattern variable qualified column reference "b.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "b.val" is not supported
 -- DEFINE-only variable qualified name: still a pattern variable, not a range variable
 SELECT COUNT(*) OVER w
 FROM rpr_err
@@ -3103,7 +3103,7 @@ WINDOW w AS (
 ERROR:  DEFINE variable "b" is not used in PATTERN
 LINE 7:     DEFINE A AS val > 0, B AS B.val > 0
                                  ^
--- Expected: ERROR: pattern variable qualified column reference "b.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "b.val" is not supported
 -- FROM-clause range variable qualified name: not allowed (prohibited by SQL standard 6.5)
 SELECT COUNT(*) OVER w
 FROM rpr_err
@@ -3113,10 +3113,76 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS rpr_err.val > 0
 );
-ERROR:  range variable qualified column reference "rpr_err.val" is not allowed in DEFINE clause
+ERROR:  range variable qualified expression "rpr_err.val" is not allowed in DEFINE clause
 LINE 7:     DEFINE A AS rpr_err.val > 0
                         ^
--- Expected: ERROR: range variable qualified column reference "rpr_err.val" is not allowed
+-- Expected: ERROR: range variable qualified expression "rpr_err.val" is not allowed
+-- Unknown qualifier (neither pattern var nor range var): the DEFINE pre-check
+-- must fall through so that normal column resolution produces a sensible error.
+SELECT COUNT(*) OVER w
+FROM rpr_err
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS nosuch.val > 0
+);
+ERROR:  missing FROM-clause entry for table "nosuch"
+LINE 7:     DEFINE A AS nosuch.val > 0
+                        ^
+-- Expected: ERROR: missing FROM-clause entry for table "nosuch"
+-- Unqualified composite field access in DEFINE works: no qualifier means no
+-- pattern/range-var navigation, so the pre-check skips and normal resolution
+-- handles "(items).amount" via A_Indirection on the current row.
+CREATE TYPE rpr_item AS (name TEXT, amount INT);
+CREATE TEMP TABLE rpr_composite (id int, items rpr_item);
+INSERT INTO rpr_composite VALUES (1, ROW('a',5)), (2, ROW('b',15)), (3, ROW('c',25));
+SELECT id, (items).amount, COUNT(*) OVER w AS cnt
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP TO NEXT ROW
+    PATTERN (A+)
+    DEFINE A AS (items).amount > 10
+);
+ id | amount | cnt 
+----+--------+-----
+  1 |      5 |   0
+  2 |     15 |   2
+  3 |     25 |   1
+(3 rows)
+
+-- Expected: rows where (items).amount > 10 form matches; counts reflect frame size
+-- Composite type field selection (qualified forms): the ColumnRef portion ("A.items" or
+-- "rpr_composite.items") is what gets quoted; the trailing ".amount" lives in
+-- the surrounding A_Indirection node and is not visible to the pre-check.
+SELECT COUNT(*) OVER w
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS (A.items).amount > 10
+);
+ERROR:  pattern variable qualified expression "a.items" is not supported in DEFINE clause
+LINE 7:     DEFINE A AS (A.items).amount > 10
+                         ^
+-- Expected: ERROR: pattern variable qualified expression "a.items" is not supported
+SELECT COUNT(*) OVER w
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS (rpr_composite.items).amount > 10
+);
+ERROR:  range variable qualified expression "rpr_composite.items" is not allowed in DEFINE clause
+LINE 7:     DEFINE A AS (rpr_composite.items).amount > 10
+                         ^
+-- Expected: ERROR: range variable qualified expression "rpr_composite.items" is not allowed
+DROP TABLE rpr_composite;
+DROP TYPE rpr_item;
 -- Semantic errors
 -- Undefined column in DEFINE
 SELECT COUNT(*) OVER w
diff --git a/src/test/regress/sql/rpr_base.sql b/src/test/regress/sql/rpr_base.sql
index 86ed06fec68..e8c72706720 100644
--- a/src/test/regress/sql/rpr_base.sql
+++ b/src/test/regress/sql/rpr_base.sql
@@ -2092,7 +2092,7 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS A.val > 0
 );
--- Expected: ERROR: pattern variable qualified column reference "a.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "a.val" is not supported
 
 -- PATTERN-only variable qualified name: not supported even without DEFINE entry
 SELECT COUNT(*) OVER w
@@ -2103,7 +2103,7 @@ WINDOW w AS (
     PATTERN (A+ B+)
     DEFINE A AS B.val > 0
 );
--- Expected: ERROR: pattern variable qualified column reference "b.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "b.val" is not supported
 
 -- DEFINE-only variable qualified name: still a pattern variable, not a range variable
 SELECT COUNT(*) OVER w
@@ -2114,7 +2114,7 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS val > 0, B AS B.val > 0
 );
--- Expected: ERROR: pattern variable qualified column reference "b.val" is not supported
+-- Expected: ERROR: pattern variable qualified expression "b.val" is not supported
 
 -- FROM-clause range variable qualified name: not allowed (prohibited by SQL standard 6.5)
 SELECT COUNT(*) OVER w
@@ -2125,7 +2125,60 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS rpr_err.val > 0
 );
--- Expected: ERROR: range variable qualified column reference "rpr_err.val" is not allowed
+-- Expected: ERROR: range variable qualified expression "rpr_err.val" is not allowed
+
+-- Unknown qualifier (neither pattern var nor range var): the DEFINE pre-check
+-- must fall through so that normal column resolution produces a sensible error.
+SELECT COUNT(*) OVER w
+FROM rpr_err
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS nosuch.val > 0
+);
+-- Expected: ERROR: missing FROM-clause entry for table "nosuch"
+
+-- Unqualified composite field access in DEFINE works: no qualifier means no
+-- pattern/range-var navigation, so the pre-check skips and normal resolution
+-- handles "(items).amount" via A_Indirection on the current row.
+CREATE TYPE rpr_item AS (name TEXT, amount INT);
+CREATE TEMP TABLE rpr_composite (id int, items rpr_item);
+INSERT INTO rpr_composite VALUES (1, ROW('a',5)), (2, ROW('b',15)), (3, ROW('c',25));
+SELECT id, (items).amount, COUNT(*) OVER w AS cnt
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP TO NEXT ROW
+    PATTERN (A+)
+    DEFINE A AS (items).amount > 10
+);
+-- Expected: rows where (items).amount > 10 form matches; counts reflect frame size
+
+-- Composite type field selection (qualified forms): the ColumnRef portion ("A.items" or
+-- "rpr_composite.items") is what gets quoted; the trailing ".amount" lives in
+-- the surrounding A_Indirection node and is not visible to the pre-check.
+SELECT COUNT(*) OVER w
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS (A.items).amount > 10
+);
+-- Expected: ERROR: pattern variable qualified expression "a.items" is not supported
+SELECT COUNT(*) OVER w
+FROM rpr_composite
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    PATTERN (A+)
+    DEFINE A AS (rpr_composite.items).amount > 10
+);
+-- Expected: ERROR: range variable qualified expression "rpr_composite.items" is not allowed
+DROP TABLE rpr_composite;
+DROP TYPE rpr_item;
 
 -- Semantic errors
 
-- 
2.50.1 (Apple Git-155)