From 3425fb0945f06593d792004a9ea80dc171cb8e8a Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Wed, 18 Mar 2026 19:27:38 +0530
Subject: [PATCH v20260320 1/2] Cross variable references in graph pattern
 causes segfault

When converting the WHERE clause in an element pattern,
generate_query_for_graph_path() calls replace_property_refs() to replace
the property references in it.  Only the current graph element pattern
is passed as the context for replacement. If there are references to
variables from other element patterns, it causes a segmentation fault
(an assertion failure in an Assert enabled build) since it does not find
path_element object corresponding to those variables. Fix the issue by
passing all the path elements in the graph pattern as context for
replacement.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reported by: Man Zeng <zengman@halodbtech.com>
Investigated by: Henson Choi <assam258@gmail.com>
Reviewed by: Junwang Zhao <zhjwpku@gmail.com>
---
 src/backend/rewrite/rewriteGraphTable.c   |  2 +-
 src/test/regress/expected/graph_table.out | 14 ++++++++++++++
 src/test/regress/sql/graph_table.sql      |  4 ++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c
index 06f2f3442d8..d3f382573fd 100644
--- a/src/backend/rewrite/rewriteGraphTable.c
+++ b/src/backend/rewrite/rewriteGraphTable.c
@@ -519,7 +519,7 @@ generate_query_for_graph_path(RangeTblEntry *rte, List *graph_path)
 		{
 			Node	   *tr;
 
-			tr = replace_property_refs(rte->relid, pf->whereClause, list_make1(pe));
+			tr = replace_property_refs(rte->relid, pf->whereClause, graph_path);
 
 			qual_exprs = lappend(qual_exprs, tr);
 		}
diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out
index 27c81ec6e42..eeaf1b85121 100644
--- a/src/test/regress/expected/graph_table.out
+++ b/src/test/regress/expected/graph_table.out
@@ -395,6 +395,20 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (v1 IS vl2)-(v2) COLUMNS (v1.vname AS v1name
  v22    | v32
 (3 rows)
 
+-- cross variable references
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b WHERE a.vprop1 = 10]->(c) COLUMNS (a.vname AS aname, a.vprop1 AS ap1, b.ename AS bname, b.eprop1 AS bp1, c.vname AS cname, c.vprop1 AS cp1)) ORDER BY aname, bname, cname;
+ aname | ap1 | bname |  bp1  | cname | cp1  
+-------+-----+-------+-------+-------+------
+ v11   |  10 | e121  | 10001 | v22   | 1020
+ v11   |  10 | e131  | 10003 | v33   | 2030
+ v11   |  10 | e132  | 10004 | v31   | 2010
+(3 rows)
+
+-- forward variable reference, not supported
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a WHERE b.eprop1 = 10001)-[b]->(c) COLUMNS (a.vname AS aname, a.vprop1 AS ap1, b.ename AS bname, b.eprop1 AS bp1, c.vname AS cname, c.vprop1 AS cp1)) ORDER BY aname, bname, cname;
+ERROR:  missing FROM-clause entry for table "b"
+LINE 1: SELECT * FROM GRAPH_TABLE (g1 MATCH (a WHERE b.eprop1 = 1000...
+                                                     ^
 -- Errors
 -- vl1 is not associated with property vprop2
 SELECT src, src_vprop2, conn, dest FROM GRAPH_TABLE (g1 MATCH (a IS vl1)-[b IS el1]->(c IS vl2 | vl3) COLUMNS (a.vname AS src, a.vprop2 AS src_vprop2, b.ename AS conn, c.vname AS dest));
diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql
index 6d2b08b997b..c3a35b69e92 100644
--- a/src/test/regress/sql/graph_table.sql
+++ b/src/test/regress/sql/graph_table.sql
@@ -274,6 +274,10 @@ SELECT src, conn, dest, lprop1, vprop2, vprop1 FROM GRAPH_TABLE (g1 MATCH (a IS
 -- edges directed in both ways - to and from v2
 SELECT * FROM GRAPH_TABLE (g1 MATCH (v1 IS vl2)-[conn]-(v2) COLUMNS (v1.vname AS v1name, conn.ename AS cname, v2.vname AS v2name));
 SELECT * FROM GRAPH_TABLE (g1 MATCH (v1 IS vl2)-(v2) COLUMNS (v1.vname AS v1name, v2.vname AS v2name));
+-- cross variable references
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a)-[b WHERE a.vprop1 = 10]->(c) COLUMNS (a.vname AS aname, a.vprop1 AS ap1, b.ename AS bname, b.eprop1 AS bp1, c.vname AS cname, c.vprop1 AS cp1)) ORDER BY aname, bname, cname;
+-- forward variable reference, not supported
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a WHERE b.eprop1 = 10001)-[b]->(c) COLUMNS (a.vname AS aname, a.vprop1 AS ap1, b.ename AS bname, b.eprop1 AS bp1, c.vname AS cname, c.vprop1 AS cp1)) ORDER BY aname, bname, cname;
 
 -- Errors
 -- vl1 is not associated with property vprop2

base-commit: e7975f1c06b585dcda645c6047e6f37cdfacce84
-- 
2.34.1

