This is an automated email from the ASF dual-hosted git repository.

mtaha pushed a commit to branch PG18
in repository https://gitbox.apache.org/repos/asf/age.git

commit 2ccdc6b951dc5e92e32ce32a41263c0b23e565e7
Author: John Gemignani <[email protected]>
AuthorDate: Tue Dec 9 11:15:26 2025 -0800

    Adjust 'could not find rte for' ERROR message (#2266)
    
    Adjusted the following type of error message. It was mentioned in
    issue 2263 as being incorrect, which it isn't. However, it did need
    some clarification added -
    
        ERROR:  could not find rte for <column name>
    
    Added a HINT for additional clarity -
    
        HINT:  variable <column name> does not exist within scope of usage
    
    For example:
    
        CREATE p0=(n0), (n1{k:EXISTS{WITH p0}}) RETURN 1
    
        ERROR:  could not find rte for p0
        LINE 3:     CREATE p0=(n0), (n1{k:EXISTS{WITH p0}})
                                                  ^
        HINT:  variable p0 does not exist within scope of usage
    
    Additionally, added pstate->p_expr_kind == EXPR_KIND_INSERT_TARGET to
    transform_cypher_clause_as_subquery.
    
    Updated existing regression tests.
    Added regression tests from issue.
    
    modified:   regress/expected/cypher_call.out
    modified:   regress/expected/cypher_subquery.out
    modified:   regress/expected/cypher_union.out
    modified:   regress/expected/cypher_with.out
    modified:   regress/expected/expr.out
    modified:   regress/expected/list_comprehension.out
    modified:   regress/expected/scan.out
    modified:   src/backend/parser/cypher_clause.c
    modified:   src/backend/parser/cypher_expr.c
---
 regress/expected/cypher_call.out        |  2 +
 regress/expected/cypher_subquery.out    |  4 ++
 regress/expected/cypher_union.out       |  1 +
 regress/expected/cypher_with.out        |  4 ++
 regress/expected/expr.out               | 66 +++++++++++++++++++++++++++++++++
 regress/expected/list_comprehension.out |  2 +
 regress/expected/scan.out               |  6 +++
 regress/sql/expr.sql                    | 27 ++++++++++++++
 src/backend/parser/cypher_clause.c      |  1 +
 src/backend/parser/cypher_expr.c        |  8 ++--
 10 files changed, 118 insertions(+), 3 deletions(-)

diff --git a/regress/expected/cypher_call.out b/regress/expected/cypher_call.out
index bb1185b9..08f97ba4 100644
--- a/regress/expected/cypher_call.out
+++ b/regress/expected/cypher_call.out
@@ -125,6 +125,7 @@ SELECT * FROM cypher('cypher_call', $$CALL sqrt(64) YIELD 
sqrt WHERE a = 8 RETUR
 ERROR:  could not find rte for a
 LINE 2: ...r('cypher_call', $$CALL sqrt(64) YIELD sqrt WHERE a = 8 RETU...
                                                              ^
+HINT:  variable a does not exist within scope of usage
 /* MATCH CALL RETURN, should fail */
 SELECT * FROM cypher('cypher_call', $$ MATCH (a) CALL sqrt(64) RETURN sqrt $$) 
as (sqrt agtype);
 ERROR:  Procedure call inside a query does not support naming results 
implicitly
@@ -171,6 +172,7 @@ SELECT * FROM cypher('cypher_call', $$ MATCH (a) CALL 
sqrt(64) YIELD sqrt WHERE
 ERROR:  could not find rte for b
 LINE 1: ...all', $$ MATCH (a) CALL sqrt(64) YIELD sqrt WHERE b = 8 RETU...
                                                              ^
+HINT:  variable b does not exist within scope of usage
 /* CALL MATCH YIELD WHERE UPDATE/RETURN */
 SELECT * FROM cypher('cypher_call', $$ CALL sqrt(64) YIELD sqrt WHERE sqrt > 1 
CREATE ({n:'c'}) $$) as (a agtype);
  a 
diff --git a/regress/expected/cypher_subquery.out 
b/regress/expected/cypher_subquery.out
index 934549f8..456b3a2c 100644
--- a/regress/expected/cypher_subquery.out
+++ b/regress/expected/cypher_subquery.out
@@ -135,6 +135,7 @@ SELECT * FROM cypher('subquery', $$ MATCH (a:person)
 ERROR:  could not find rte for c
 LINE 5:               RETURN c
                              ^
+HINT:  variable c does not exist within scope of usage
 --union, no returns
 SELECT * FROM cypher('subquery', $$ MATCH (a:person)
                                                                        WHERE 
EXISTS {
@@ -341,6 +342,7 @@ SELECT * FROM cypher('subquery', $$ RETURN 1,
 ERROR:  could not find rte for a
 LINE 4:                RETURN a
                               ^
+HINT:  variable a does not exist within scope of usage
 --- COUNT
 --count pattern subquery in where
 SELECT * FROM cypher('subquery', $$ MATCH (a:person)
@@ -540,6 +542,7 @@ SELECT * FROM cypher('subquery', $$ MATCH (a:person)
 ERROR:  could not find rte for b
 LINE 2:          RETURN a.name, COUNT{MATCH (a) RETURN b} $$)
                                                        ^
+HINT:  variable b does not exist within scope of usage
 --incorrect nested variable reference
 SELECT * FROM cypher('subquery', $$ MATCH (a:person)
                                                                        RETURN 
a.name, COUNT{MATCH (a)
@@ -549,6 +552,7 @@ SELECT * FROM cypher('subquery', $$ MATCH (a:person)
 ERROR:  could not find rte for b
 LINE 4:                RETURN b} $$)
                               ^
+HINT:  variable b does not exist within scope of usage
 --count nested with exists
 SELECT * FROM cypher('subquery', $$ MATCH (a:person)
                                                                        RETURN 
a.name,
diff --git a/regress/expected/cypher_union.out 
b/regress/expected/cypher_union.out
index 063354dd..14fa56e6 100644
--- a/regress/expected/cypher_union.out
+++ b/regress/expected/cypher_union.out
@@ -141,6 +141,7 @@ SELECT * FROM cypher('cypher_union', $$MATCH (n) RETURN n 
UNION ALL MATCH (m) RE
 ERROR:  could not find rte for n
 LINE 2: ..., $$MATCH (n) RETURN n UNION ALL MATCH (m) RETURN n$$) AS (r...
                                                              ^
+HINT:  variable n does not exist within scope of usage
 /*
  *UNION and UNION ALL, type casting
  */
diff --git a/regress/expected/cypher_with.out b/regress/expected/cypher_with.out
index e5f82aa2..99ea320a 100644
--- a/regress/expected/cypher_with.out
+++ b/regress/expected/cypher_with.out
@@ -267,6 +267,7 @@ $$) AS (a agtype, b agtype);
 ERROR:  could not find rte for b
 LINE 4:     RETURN m,b
                      ^
+HINT:  variable b does not exist within scope of usage
 SELECT * FROM cypher('cypher_with', $$
     MATCH (m)-[]->(b)
     WITH m AS start_node,b AS end_node
@@ -278,6 +279,7 @@ $$) AS (id agtype, node agtype);
 ERROR:  could not find rte for end_node
 LINE 7:     RETURN id(start_node),end_node.name
                                   ^
+HINT:  variable end_node does not exist within scope of usage
 -- Clean up
 SELECT drop_graph('cypher_with', true);
 NOTICE:  drop cascades to 4 other objects
@@ -320,6 +322,7 @@ $$) AS (n agtype, d agtype);
 ERROR:  could not find rte for d
 LINE 8:     RETURN c,d
                      ^
+HINT:  variable d does not exist within scope of usage
 -- Issue 396 (should error out)
 SELECT * FROM cypher('graph',$$
     CREATE (v),(u),(w),
@@ -338,6 +341,7 @@ $$) as (a agtype,b agtype);
 ERROR:  could not find rte for v
 LINE 4:     RETURN v,path_length
                    ^
+HINT:  variable v does not exist within scope of usage
 -- Clean up
 SELECT drop_graph('graph', true);
 NOTICE:  drop cascades to 6 other objects
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index d0546d8a..4be3bf90 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -3370,6 +3370,7 @@ $$) AS (toBooleanList agtype);
 ERROR:  could not find rte for fail
 LINE 2:     RETURN toBooleanList(fail)
                                  ^
+HINT:  variable fail does not exist within scope of usage
 SELECT * FROM cypher('expr', $$
     RETURN toBooleanList("fail")
 $$) AS (toBooleanList agtype);
@@ -3513,6 +3514,7 @@ $$) AS (toFloatList agtype);
 ERROR:  could not find rte for failed
 LINE 2:     RETURN toFloatList([failed])
                                 ^
+HINT:  variable failed does not exist within scope of usage
 SELECT * FROM cypher('expr', $$
     RETURN toFloatList("failed")
 $$) AS (toFloatList agtype);
@@ -3892,12 +3894,14 @@ $$) AS (toStringList agtype);
 ERROR:  could not find rte for b
 LINE 2:     RETURN toStringList([['a', b]]) 
                                        ^
+HINT:  variable b does not exist within scope of usage
 SELECT * FROM cypher('expr', $$ 
     RETURN toStringList([test]) 
 $$) AS (toStringList agtype);
 ERROR:  could not find rte for test
 LINE 2:     RETURN toStringList([test]) 
                                  ^
+HINT:  variable test does not exist within scope of usage
 --
 -- reverse(string)
 --
@@ -7923,6 +7927,7 @@ SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS 
(tail agtype);
 ERROR:  could not find rte for abc
 LINE 1: SELECT * FROM cypher('list', $$ RETURN tail(abc) $$) AS (tai...
                                                     ^
+HINT:  variable abc does not exist within scope of usage
 SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail agtype);
 ERROR:  function ag_catalog.age_tail() does not exist
 LINE 1: SELECT * FROM cypher('list', $$ RETURN tail() $$) AS (tail a...
@@ -9011,9 +9016,70 @@ SELECT agtype_hash_cmp(agtype_in('[null, null, null, 
null, null]'));
       -505290721
 (1 row)
 
+--
+-- Issue 2263: AGE returns incorrect error message for EXISTS subquery outer 
variable reference
+--
+--       NOTE: There isn't really anything incorrect about the message. 
However,
+--             it could be more clear.
+--
+SELECT * FROM create_graph('issue_2263');
+NOTICE:  graph "issue_2263" has been created
+ create_graph 
+--------------
+ 
+(1 row)
+
+SELECT * FROM cypher('issue_2263', $$
+    CREATE a=()-[:T]->(), p=({k:exists{return a}})-[:T]->()
+    RETURN 1
+$$) AS (one agtype);
+ERROR:  could not find rte for a
+LINE 2:     CREATE a=()-[:T]->(), p=({k:exists{return a}})-[:T]->()
+                                                      ^
+HINT:  variable a does not exist within scope of usage
+SELECT * FROM cypher('issue_2263', $$
+    CREATE p0=(n0), (n1{k:EXISTS{WITH p0}})
+    RETURN 1
+$$) AS (one agtype);
+ERROR:  could not find rte for p0
+LINE 2:     CREATE p0=(n0), (n1{k:EXISTS{WITH p0}})
+                                              ^
+HINT:  variable p0 does not exist within scope of usage
+SELECT * FROM cypher('issue_2263', $$
+    CREATE ()-[r4 :T6]->(), ({k2:COUNT{WITH r4.k AS a3 UNWIND [] AS a4 WITH 
DISTINCT NULL AS a5}})
+    RETURN 1
+$$) AS (one agtype);
+ERROR:  could not find rte for r4
+LINE 2:     CREATE ()-[r4 :T6]->(), ({k2:COUNT{WITH r4.k AS a3 UNWIN...
+                                                    ^
+HINT:  variable r4 does not exist within scope of usage
+SELECT * FROM cypher('issue_2263', $$
+    CREATE (x), ({a1:EXISTS { RETURN COUNT(0) AS a2, keys(x) AS a4 }})
+$$) AS (out agtype);
+ERROR:  could not find rte for x
+LINE 2: ...TE (x), ({a1:EXISTS { RETURN COUNT(0) AS a2, keys(x) AS a4 }...
+                                                             ^
+HINT:  variable x does not exist within scope of usage
+SELECT * FROM cypher('issue_2263', $$
+    CREATE x = (), ({ a0:COUNT { MATCH () WHERE CASE WHEN true THEN (x IS 
NULL) END RETURN 0 } })
+$$) AS (out agtype);
+ERROR:  could not find rte for x
+LINE 2: ...({ a0:COUNT { MATCH () WHERE CASE WHEN true THEN (x IS NULL)...
+                                                             ^
+HINT:  variable x does not exist within scope of usage
 --
 -- Cleanup
 --
+SELECT * FROM drop_graph('issue_2263', true);
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to table issue_2263._ag_label_vertex
+drop cascades to table issue_2263._ag_label_edge
+NOTICE:  graph "issue_2263" has been dropped
+ drop_graph 
+------------
+ 
+(1 row)
+
 SELECT * FROM drop_graph('issue_1988', true);
 NOTICE:  drop cascades to 4 other objects
 DETAIL:  drop cascades to table issue_1988._ag_label_vertex
diff --git a/regress/expected/list_comprehension.out 
b/regress/expected/list_comprehension.out
index 07f77770..5a375642 100644
--- a/regress/expected/list_comprehension.out
+++ b/regress/expected/list_comprehension.out
@@ -569,10 +569,12 @@ SELECT * FROM cypher('list_comprehension', $$ RETURN [i 
IN range(0, 10, 2)],i $$
 ERROR:  could not find rte for i
 LINE 1: ..._comprehension', $$ RETURN [i IN range(0, 10, 2)],i $$) AS (...
                                                              ^
+HINT:  variable i does not exist within scope of usage
 SELECT * FROM cypher('list_comprehension', $$ RETURN [i IN range(0, 10, 2) 
WHERE i>5 | i^2], i $$) AS (result agtype, i agtype);
 ERROR:  could not find rte for i
 LINE 1: ...$$ RETURN [i IN range(0, 10, 2) WHERE i>5 | i^2], i $$) AS (...
                                                              ^
+HINT:  variable i does not exist within scope of usage
 -- Invalid list comprehension
 SELECT * FROM cypher('list_comprehension', $$ RETURN [1 IN range(0, 10, 2) 
WHERE 2>5] $$) AS (result agtype);
 ERROR:  Syntax error at or near IN
diff --git a/regress/expected/scan.out b/regress/expected/scan.out
index d8105a05..46d5676d 100644
--- a/regress/expected/scan.out
+++ b/regress/expected/scan.out
@@ -437,36 +437,42 @@ $$) AS t(id text);
 ERROR:  could not find rte for _$09A_z
 LINE 2: RETURN _$09A_z
                ^
+HINT:  variable _$09A_z does not exist within scope of usage
 SELECT * FROM cypher('scan', $$
 RETURN A
 $$) AS t(id text);
 ERROR:  could not find rte for A
 LINE 2: RETURN A
                ^
+HINT:  variable A does not exist within scope of usage
 SELECT * FROM cypher('scan', $$
 RETURN z
 $$) AS t(id text);
 ERROR:  could not find rte for z
 LINE 2: RETURN z
                ^
+HINT:  variable z does not exist within scope of usage
 SELECT * FROM cypher('scan', $$
 RETURN `$`
 $$) AS t(id text);
 ERROR:  could not find rte for $
 LINE 2: RETURN `$`
                ^
+HINT:  variable $ does not exist within scope of usage
 SELECT * FROM cypher('scan', $$
 RETURN `0`
 $$) AS t(id text);
 ERROR:  could not find rte for 0
 LINE 2: RETURN `0`
                ^
+HINT:  variable 0 does not exist within scope of usage
 SELECT * FROM cypher('scan', $$
 RETURN ````
 $$) AS t(id text);
 ERROR:  could not find rte for `
 LINE 2: RETURN ````
                ^
+HINT:  variable ` does not exist within scope of usage
 -- zero-length quoted identifier
 SELECT * FROM cypher('scan', $$
 RETURN ``
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 83f21856..466bace4 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -3634,9 +3634,36 @@ SELECT * FROM cypher('issue_1988', $$
 SELECT agtype_access_operator(agtype_in('[null, null]'));
 SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
 
+--
+-- Issue 2263: AGE returns incorrect error message for EXISTS subquery outer 
variable reference
+--
+--       NOTE: There isn't really anything incorrect about the message. 
However,
+--             it could be more clear.
+--
+SELECT * FROM create_graph('issue_2263');
+SELECT * FROM cypher('issue_2263', $$
+    CREATE a=()-[:T]->(), p=({k:exists{return a}})-[:T]->()
+    RETURN 1
+$$) AS (one agtype);
+SELECT * FROM cypher('issue_2263', $$
+    CREATE p0=(n0), (n1{k:EXISTS{WITH p0}})
+    RETURN 1
+$$) AS (one agtype);
+SELECT * FROM cypher('issue_2263', $$
+    CREATE ()-[r4 :T6]->(), ({k2:COUNT{WITH r4.k AS a3 UNWIND [] AS a4 WITH 
DISTINCT NULL AS a5}})
+    RETURN 1
+$$) AS (one agtype);
+SELECT * FROM cypher('issue_2263', $$
+    CREATE (x), ({a1:EXISTS { RETURN COUNT(0) AS a2, keys(x) AS a4 }})
+$$) AS (out agtype);
+SELECT * FROM cypher('issue_2263', $$
+    CREATE x = (), ({ a0:COUNT { MATCH () WHERE CASE WHEN true THEN (x IS 
NULL) END RETURN 0 } })
+$$) AS (out agtype);
+
 --
 -- Cleanup
 --
+SELECT * FROM drop_graph('issue_2263', true);
 SELECT * FROM drop_graph('issue_1988', true);
 SELECT * FROM drop_graph('issue_1953', true);
 SELECT * FROM drop_graph('expanded_map', true);
diff --git a/src/backend/parser/cypher_clause.c 
b/src/backend/parser/cypher_clause.c
index 971f8c3d..5c5024cf 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -6315,6 +6315,7 @@ transform_cypher_clause_as_subquery(cypher_parsestate 
*cpstate,
            pstate->p_expr_kind == EXPR_KIND_OTHER ||
            pstate->p_expr_kind == EXPR_KIND_WHERE ||
            pstate->p_expr_kind == EXPR_KIND_SELECT_TARGET ||
+           pstate->p_expr_kind == EXPR_KIND_INSERT_TARGET ||
            pstate->p_expr_kind == EXPR_KIND_FROM_SUBSELECT);
 
     /*
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index 993957c8..5f4de86b 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -423,9 +423,11 @@ static Node *transform_ColumnRef(cypher_parsestate 
*cpstate, ColumnRef *cref)
                 else
                 {
                     ereport(ERROR,
-                                (errcode(ERRCODE_UNDEFINED_COLUMN),
-                                 errmsg("could not find rte for %s", colname),
-                                 parser_errposition(pstate, cref->location)));
+                            (errcode(ERRCODE_UNDEFINED_COLUMN),
+                             errmsg("could not find rte for %s", colname),
+                             errhint("variable %s does not exist within scope 
of usage",
+                                     colname),
+                             parser_errposition(pstate, cref->location)));
                 }
 
                 if (node == NULL)

Reply via email to