public inbox for [email protected]
help / color / mirror / Atom feedFrom: SATYANARAYANA NARLAPURAM <[email protected]>
To: PostgreSQL Hackers <[email protected]>
To: Ashutosh Bapat <[email protected]>
Subject: Bug: pg_get_viewdef() fails on GRAPH_TABLE views with lateral column references
Date: Sat, 18 Apr 2026 00:56:19 -0700
Message-ID: <CAHg+QDcLVa2iBnggkHxY4itZbXtDMfsYHEjnCUYe9hNbnxDi-w@mail.gmail.com> (raw)
Hi hackers,
pg_get_viewdef() fails with ERROR: bogus varlevelsup: 0 offset 0 for any
view containing a GRAPH_TABLE whose COLUMNS clause references an outer
(lateral)
table. This also breaks pg_dump and \d+ for any database containing such a
view.
Repro:
CREATE TABLE vtab (id int PRIMARY KEY, name text);
CREATE TABLE etab (eid int PRIMARY KEY,
src int REFERENCES vtab(id), dst int REFERENCES vtab(id));
CREATE PROPERTY GRAPH g1
VERTEX TABLES (vtab)
EDGE TABLES (etab KEY (eid)
SOURCE KEY (src) REFERENCES vtab(id)
DESTINATION KEY (dst) REFERENCES vtab(id));
CREATE TABLE outer_t (val int);
CREATE VIEW v AS
SELECT * FROM outer_t,
GRAPH_TABLE (g1 MATCH (a IS vtab)
COLUMNS (a.name AS src_name, outer_t.val AS oval));
pg_dump -d foo -p 5433
pg_dump: error: query failed: ERROR: bogus varlevelsup: 0 offset 0
pg_dump: detail: Query was: SELECT
pg_catalog.pg_get_viewdef('173849'::pg_catalog.oid) AS viewdef
Problem:
deparse_context context variable declared in the case RTE_GRAPH_TABLE
shadows the function's
deparse_context *context parameter. The zeroed struct has namespaces = NIL,
so when get_rule_expr()
reaches a Var node, get_variable() sees list_length(context->namespaces) ==
0 and raises the error. Property
references are fine because GraphPropertyRef deparsing never touches
namespaces.
Fix:
Remove the shadowing local variable and pass the outer context pointer to
get_rule_expr(). Attached a patch
with a fix, additionally added a test.
Thanks,
Satya
Attachments:
[application/octet-stream] 0001-Fix-pg_get_viewdef-crash-for-GRAPH_TABLE-views-with-.patch (4.9K, 3-0001-Fix-pg_get_viewdef-crash-for-GRAPH_TABLE-views-with-.patch)
download | inline diff:
From f9667899154e6a42e6e73d9f21393384a9ff1dc2 Mon Sep 17 00:00:00 2001
From: Ubuntu
<azureuser@pgclient.5sdvw5dac2hu3o3frfdg3sxydd.zx.internal.cloudapp.net>
Date: Sat, 18 Apr 2026 07:34:58 +0000
Subject: [PATCH] Fix pg_get_viewdef() crash for GRAPH_TABLE views with lateral
column refs
get_from_clause_item() in ruleutils.c declares a local 'deparse_context
context = {0}' inside the RTE_GRAPH_TABLE COLUMNS loop, which shadows the
function's 'deparse_context *context' parameter. The zeroed struct has
namespaces = NIL, so when get_rule_expr() encounters a Var node (from a
lateral column reference in COLUMNS), get_variable() finds list_length(0)
and errors with 'bogus varlevelsup: 0 offset 0'.
Fix by removing the shadowing local variable and passing the outer context
pointer through to get_rule_expr(), which is what every other RTE case in
this function already does.
This crash affects pg_get_viewdef(), pg_dump, and psql's \d+ for any view
containing a GRAPH_TABLE with lateral column references in its COLUMNS
clause.
---
src/backend/utils/adt/ruleutils.c | 5 +----
src/test/regress/expected/graph_table.out | 19 +++++++++++++++++++
src/test/regress/sql/graph_table.sql | 11 +++++++++++
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 090e8cc2..148eb5bb 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -13097,16 +13097,13 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
foreach(lc, rte->graph_table_columns)
{
TargetEntry *te = lfirst_node(TargetEntry, lc);
- deparse_context context = {0};
if (!first)
appendStringInfoString(buf, ", ");
else
first = false;
- context.buf = buf;
-
- get_rule_expr((Node *) te->expr, &context, false);
+ get_rule_expr((Node *) te->expr, context, false);
appendStringInfoString(buf, " AS ");
appendStringInfoString(buf, quote_identifier(te->resname));
}
diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out
index b579e3df..d7b767be 100644
--- a/src/test/regress/expected/graph_table.out
+++ b/src/test/regress/expected/graph_table.out
@@ -932,6 +932,25 @@ SELECT pg_get_viewdef('customers_us'::regclass);
ORDER BY customer_name, product_name;
(1 row)
+-- ruleutils reverse parsing with lateral column reference in COLUMNS
+CREATE TABLE lateral_t (val int);
+INSERT INTO lateral_t VALUES (1);
+CREATE VIEW gt_lateral_view AS
+ SELECT * FROM lateral_t,
+ GRAPH_TABLE (myshop MATCH (c IS customers)
+ COLUMNS (c.name AS cname, lateral_t.val AS lval));
+SELECT pg_get_viewdef('gt_lateral_view'::regclass);
+ pg_get_viewdef
+---------------------------------------------------------------------------------------------------
+ SELECT lateral_t.val, +
+ "graph_table".cname, +
+ "graph_table".lval +
+ FROM lateral_t, +
+ GRAPH_TABLE (myshop MATCH (c IS customers) COLUMNS (c.name AS cname, lateral_t.val AS lval));
+(1 row)
+
+DROP VIEW gt_lateral_view;
+DROP TABLE lateral_t;
-- test view/graph nesting
CREATE VIEW customers_view AS SELECT customer_id, 'redacted' || customer_id AS name_redacted, address FROM customers;
SELECT * FROM customers;
diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql
index 4ff98817..90e5ea2e 100644
--- a/src/test/regress/sql/graph_table.sql
+++ b/src/test/regress/sql/graph_table.sql
@@ -528,6 +528,17 @@ SELECT * FROM GRAPH_TABLE (g4 MATCH (s WHERE s.id = 3)-[e]-(d) COLUMNS (s.val, e
CREATE VIEW customers_us AS SELECT * FROM GRAPH_TABLE (myshop MATCH (c IS customers WHERE c.address = 'US')-[IS customer_orders | customer_wishlists ]->(l IS orders | wishlists)-[ IS list_items]->(p IS products) COLUMNS (c.name AS customer_name, p.name AS product_name)) ORDER BY customer_name, product_name;
SELECT pg_get_viewdef('customers_us'::regclass);
+-- ruleutils reverse parsing with lateral column reference in COLUMNS
+CREATE TABLE lateral_t (val int);
+INSERT INTO lateral_t VALUES (1);
+CREATE VIEW gt_lateral_view AS
+ SELECT * FROM lateral_t,
+ GRAPH_TABLE (myshop MATCH (c IS customers)
+ COLUMNS (c.name AS cname, lateral_t.val AS lval));
+SELECT pg_get_viewdef('gt_lateral_view'::regclass);
+DROP VIEW gt_lateral_view;
+DROP TABLE lateral_t;
+
-- test view/graph nesting
CREATE VIEW customers_view AS SELECT customer_id, 'redacted' || customer_id AS name_redacted, address FROM customers;
--
2.43.0
view thread (4+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: Bug: pg_get_viewdef() fails on GRAPH_TABLE views with lateral column references
In-Reply-To: <CAHg+QDcLVa2iBnggkHxY4itZbXtDMfsYHEjnCUYe9hNbnxDi-w@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox