From ce448a1b559b5a3b68a78e226277451ef76cb095 Mon Sep 17 00:00:00 2001 From: Satya Narlapuram Date: Sat, 25 Apr 2026 16:43:33 +0000 Subject: [PATCH] Improve error message for graph variable references in subqueries within GRAPH_TABLE When a subquery inside GRAPH_TABLE COLUMNS or MATCH WHERE references a graph pattern variable, the error was a confusing "missing FROM-clause entry for table". Fix by walking the parentParseState chain in transformGraphTablePropertyRef() to detect the graph variable and report a clear "cannot be used in a subquery" error instead. --- src/backend/parser/parse_graphtable.c | 28 +++++++++++++++++++++++ src/test/regress/expected/graph_table.out | 15 ++++++++++++ src/test/regress/sql/graph_table.sql | 11 +++++++++ 3 files changed, 54 insertions(+) diff --git a/src/backend/parser/parse_graphtable.c b/src/backend/parser/parse_graphtable.c index 73fbfb54..5e5da5bc 100644 --- a/src/backend/parser/parse_graphtable.c +++ b/src/backend/parser/parse_graphtable.c @@ -81,7 +81,35 @@ transformGraphTablePropertyRef(ParseState *pstate, ColumnRef *cref) GraphTableParseState *gpstate = pstate->p_graph_table_pstate; if (!gpstate) + { + /* + * No GRAPH_TABLE context in this ParseState; may be inside a + * subquery whose sub-ParseState doesn't inherit p_graph_table_pstate. + * Walk up the parent chain to detect graph variable references and + * report a clear error instead of "missing FROM-clause entry". + */ + if (list_length(cref->fields) == 2) + { + Node *field1 = linitial(cref->fields); + + if (!IsA(field1, A_Star)) + { + for (ParseState *ps = pstate->parentParseState; + ps != NULL; + ps = ps->parentParseState) + { + if (ps->p_graph_table_pstate && + list_member(ps->p_graph_table_pstate->variables, field1)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("graph pattern variable reference \"%s\" cannot be used in a subquery", + strVal(field1)), + parser_errposition(pstate, cref->location))); + } + } + } return NULL; + } if (list_length(cref->fields) == 2) { diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index a2d7cdf3..d3c20610 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -1032,6 +1032,21 @@ SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE src.vprop1 > ERROR: subqueries within GRAPH_TABLE reference are not supported SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE out_degree(src.vname) > (SELECT max(out_degree(nname)) FROM GRAPH_TABLE (g1 MATCH (node) COLUMNS (node.vname AS nname))) COLUMNS(src.vname AS sname, dest.vname AS dname)); ERROR: subqueries within GRAPH_TABLE reference are not supported +-- subquery referencing graph variable in COLUMNS (should report clear error) +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) + COLUMNS (src.vname AS sname, + (SELECT count(*) FROM v1 WHERE vprop1 = src.vprop1) AS cnt)) gt; +ERROR: graph pattern variable reference "src" cannot be used in a subquery +LINE 3: ... (SELECT count(*) FROM v1 WHERE vprop1 = src.vprop1... + ^ +-- EXISTS subquery referencing graph variable in MATCH WHERE +SELECT * FROM GRAPH_TABLE (g1 + MATCH (src IS vl1 WHERE EXISTS ( + SELECT 1 FROM v1 WHERE vprop1 = src.vprop1)) + COLUMNS (src.vname AS sname)) gt; +ERROR: graph pattern variable reference "src" cannot be used in a subquery +LINE 3: SELECT 1 FROM v1 WHERE vprop1 = src.vprop1)) + ^ -- GRAPH_TABLE subquery in HAVING clause SELECT src.vname, count(*) FROM v1 AS src diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index b054dbdf..2521c4ca 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -590,6 +590,17 @@ SELECT * FROM customers co WHERE co.customer_id = (SELECT customer_id FROM GRAPH SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE src.vprop1 > (SELECT max(v1.vprop1) FROM v1) COLUMNS(src.vname AS sname, dest.vname AS dname)); SELECT sname, dname FROM GRAPH_TABLE (g1 MATCH (src)->(dest) WHERE out_degree(src.vname) > (SELECT max(out_degree(nname)) FROM GRAPH_TABLE (g1 MATCH (node) COLUMNS (node.vname AS nname))) COLUMNS(src.vname AS sname, dest.vname AS dname)); +-- subquery referencing graph variable in COLUMNS (should report clear error) +SELECT * FROM GRAPH_TABLE (g1 MATCH (src IS vl1) + COLUMNS (src.vname AS sname, + (SELECT count(*) FROM v1 WHERE vprop1 = src.vprop1) AS cnt)) gt; + +-- EXISTS subquery referencing graph variable in MATCH WHERE +SELECT * FROM GRAPH_TABLE (g1 + MATCH (src IS vl1 WHERE EXISTS ( + SELECT 1 FROM v1 WHERE vprop1 = src.vprop1)) + COLUMNS (src.vname AS sname)) gt; + -- GRAPH_TABLE subquery in HAVING clause SELECT src.vname, count(*) FROM v1 AS src -- 2.43.0