From 4cd6a54ef711cccd1f7d7bfb6e32d3ae1aa85411 Mon Sep 17 00:00:00 2001 From: Ewan Young Date: Mon, 31 Aug 2026 22:53:03 +0800 Subject: [PATCH] Coerce GRAPH_TABLE pattern WHERE clauses to boolean transformGraphElementPattern() and transformGraphPattern() ran their WHERE clauses through transformExpr() without ever applying coerce_to_boolean(), so a WHERE clause of any type was accepted and its bare datum was used as the qual. For example, MATCH (c IS customers WHERE c.name) is accepted and EXPLAIN shows "Filter: name"; the never-null text pointer is always taken as true, so the condition silently degenerates to roughly "name IS NOT NULL" instead of raising the usual "argument of WHERE must be type boolean" error. Wrong results, no diagnostic. Route both sites through transformWhereClause(), like every other WHERE clause, and add regression tests for the element-level and pattern-level cases. --- src/backend/parser/parse_graphtable.c | 7 +++++-- src/test/regress/expected/graph_table.out | 4 ++++ src/test/regress/sql/graph_table.sql | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/backend/parser/parse_graphtable.c b/src/backend/parser/parse_graphtable.c index 73fbfb541f7..b44f7ccd0a7 100644 --- a/src/backend/parser/parse_graphtable.c +++ b/src/backend/parser/parse_graphtable.c @@ -22,6 +22,7 @@ #include "catalog/pg_propgraph_property.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "parser/parse_clause.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" #include "parser/parse_graphtable.h" @@ -251,7 +252,8 @@ transformGraphElementPattern(ParseState *pstate, GraphElementPattern *gep) gep->labelexpr = transformLabelExpr(gpstate, gep->labelexpr); - gep->whereClause = transformExpr(pstate, gep->whereClause, EXPR_KIND_WHERE); + gep->whereClause = transformWhereClause(pstate, gep->whereClause, + EXPR_KIND_WHERE, "WHERE"); /* * Assign collations here for the reason mentioned in the prologue of @@ -387,7 +389,8 @@ transformGraphPattern(ParseState *pstate, GraphPattern *graph_pattern) transformPathPatternList(pstate, graph_pattern->path_pattern_list)); graph_pattern->path_pattern_list = path_pattern_list; - graph_pattern->whereClause = transformExpr(pstate, graph_pattern->whereClause, EXPR_KIND_WHERE); + graph_pattern->whereClause = transformWhereClause(pstate, graph_pattern->whereClause, + EXPR_KIND_WHERE, "WHERE"); assign_expr_collations(pstate, graph_pattern->whereClause); return (Node *) graph_pattern; diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index 2e862a82ba0..dd051aa4d1c 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -101,6 +101,10 @@ LINE 1: SELECT * FROM GRAPH_TABLE (myshop MATCH COLUMNS (1 AS col)); ^ SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)->{1,2}(o IS orders) COLUMNS (c.name AS customer_name)); -- error ERROR: element pattern quantifier is not supported +SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.name) COLUMNS (c.name AS customer_name)); -- error, WHERE must yield boolean +ERROR: argument of WHERE must be type boolean, not type character varying +SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers) WHERE c.customer_id COLUMNS (c.name AS customer_name)); -- error, WHERE must yield boolean +ERROR: argument of WHERE must be type boolean, not type integer SELECT * FROM GRAPH_TABLE (myshop MATCH ((c IS customers)->(o IS orders)) COLUMNS (c.name)); ERROR: unsupported element pattern kind: "nested path pattern" LINE 1: SELECT * FROM GRAPH_TABLE (myshop MATCH ((c IS customers)->(... diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 21e70015f6e..67ea6d2f0d2 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -92,6 +92,8 @@ SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.addr SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers), (o IS orders) COLUMNS (c.name AS customer_name)); -- error SELECT * FROM GRAPH_TABLE (myshop MATCH COLUMNS (1 AS col)); -- error, empty match clause SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)->{1,2}(o IS orders) COLUMNS (c.name AS customer_name)); -- error +SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.name) COLUMNS (c.name AS customer_name)); -- error, WHERE must yield boolean +SELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers) WHERE c.customer_id COLUMNS (c.name AS customer_name)); -- error, WHERE must yield boolean SELECT * FROM GRAPH_TABLE (myshop MATCH ((c IS customers)->(o IS orders)) COLUMNS (c.name)); -- a property graph can be referenced only from within GRAPH_TABLE clause. -- 2.47.3