v2-0001-Fix-assertion-failure-in-LATERAL-GRAPH_TABLE-with-multi-label-pattern.patch
application/octet-stream
Filename: v2-0001-Fix-assertion-failure-in-LATERAL-GRAPH_TABLE-with-multi-label-pattern.patch
Type: application/octet-stream
Part: 0
From ad6c9007ba5d092ee530b3a6e964b05c7ff2c7e7 Mon Sep 17 00:00:00 2001 From: Ayush Tiwari <ayushtiwari.slg01@gmail.com> Date: Tue, 19 May 2026 00:00:00 +0000 Subject: [PATCH v2] Fix assertion failure in LATERAL GRAPH_TABLE with multi-label pattern rewriteGraphTable() rewrites GRAPH_TABLE into a subquery RTE. During that rewrite, replace_property_refs_mutator() bumps Vars that already refer outside the GRAPH_TABLE expression by one query level, which is sufficient for patterns that produce a single path query. For patterns that produce multiple path queries, however, generate_setop_from_pathqueries() additionally inserts each path query as a subquery RTE of the UNION ALL query. Lateral Vars inside those path queries were not adjusted for that extra query level. As a result, such Vars could be interpreted as references to the rewritten GRAPH_TABLE RTE itself, causing create_lateral_join_info() to see a lateral self-reference and trip its assertion. Increment only Vars that already refer outside each path query before adding it to the setop range table. Local Vars belonging to the path query remain unchanged. Add regression coverage for a multi-label GRAPH_TABLE pattern with lateral references in both WHERE and COLUMNS. Author: Satya Narlapuram <satyanarlapuram@gmail.com> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://www.postgresql.org/message-id/CAHg+QDfnLzsgjaQ_CiKSpP4JH3MKOiwoawEcCzXa9uYr45yiWw@mail.gmail.com --- src/backend/rewrite/rewriteGraphTable.c | 7 +++++++ src/test/regress/expected/graph_table.out | 13 +++++++++++++ src/test/regress/sql/graph_table.sql | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/src/backend/rewrite/rewriteGraphTable.c b/src/backend/rewrite/rewriteGraphTable.c index 33d4e866d74..a62ef926a5c 100644 --- a/src/backend/rewrite/rewriteGraphTable.c +++ b/src/backend/rewrite/rewriteGraphTable.c @@ -714,6 +714,13 @@ generate_setop_from_pathqueries(List *pathqueries, List **rtable, List **targetl lquery = linitial_node(Query, pathqueries); + /* + * Each path query is being inserted as a subquery RTE of the setop + * query, so any Vars that already refer outside the path query must be + * adjusted for the additional query level. + */ + IncrementVarSublevelsUp((Node *) lquery, 1, 1); + pni = addRangeTableEntryForSubquery(make_parsestate(NULL), lquery, NULL, false, false); *rtable = lappend(*rtable, pni->p_rte); diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out index cc6d80afd82..d783cb94dff 100644 --- a/src/test/regress/expected/graph_table.out +++ b/src/test/regress/expected/graph_table.out @@ -254,6 +254,19 @@ SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers WHERE x1.ad 2 | customer1 | 1 | 1 (2 rows) +-- lateral reference with multi-label pattern (UNION ALL rewrite) +SELECT x1.a, g.* FROM x1, + GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.customer_id = x1.a)-[IS customer_orders | customer_wishlists]->(l IS lists)-[IS list_items]->(p IS products) + COLUMNS (x1.a AS outer_id, c.name AS customer_name, p.name AS product_name, l.list_type)) g + ORDER BY 1, 3, 4, 5; + a | outer_id | customer_name | product_name | list_type +---+----------+---------------+--------------+----------- + 1 | 1 | customer1 | product1 | order + 1 | 1 | customer1 | product2 | order + 2 | 2 | customer2 | product1 | order + 2 | 2 | customer2 | product1 | wishlist +(4 rows) + -- non-local property references are not allowed, even if a lateral column -- reference is available SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers)-[IS customer_orders]->(o IS orders WHERE o.order_id = x1.a) COLUMNS (x1.name AS customer_name, x1.customer_id AS cid, o.order_id)) g; -- error diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql index 0e381ec72bc..f7e403f03f0 100644 --- a/src/test/regress/sql/graph_table.sql +++ b/src/test/regress/sql/graph_table.sql @@ -158,6 +158,11 @@ CREATE TABLE x1 (a int, address text); INSERT INTO x1 VALUES (1, 'one'), (2, 'two'); SELECT * FROM x1, GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US' AND c.customer_id = x1.a)-[IS customer_orders]->(o IS orders) COLUMNS (c.name AS customer_name, c.customer_id AS cid)); SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers WHERE x1.address = 'US')-[IS customer_orders]->(o IS orders) COLUMNS (x1.name AS customer_name, x1.customer_id AS cid, o.order_id)) g; +-- lateral reference with multi-label pattern (UNION ALL rewrite) +SELECT x1.a, g.* FROM x1, + GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.customer_id = x1.a)-[IS customer_orders | customer_wishlists]->(l IS lists)-[IS list_items]->(p IS products) + COLUMNS (x1.a AS outer_id, c.name AS customer_name, p.name AS product_name, l.list_type)) g + ORDER BY 1, 3, 4, 5; -- non-local property references are not allowed, even if a lateral column -- reference is available SELECT x1.a, g.* FROM x1, GRAPH_TABLE (myshop MATCH (x1 IS customers)-[IS customer_orders]->(o IS orders WHERE o.order_id = x1.a) COLUMNS (x1.name AS customer_name, x1.customer_id AS cid, o.order_id)) g; -- error