From 60583ec50616f0abd132aa6cd4f0054fc5939c62 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Wed, 25 Feb 2026 11:35:28 +0530
Subject: [PATCH v20260225 2/2] Sort out RELKIND_PROPGRAPH / table_open

Author: Peter Eisentraut
---
 src/backend/parser/parse_clause.c         | 36 ++++++++++++++++++-----
 src/backend/parser/parse_relation.c       | 27 -----------------
 src/backend/rewrite/rewriteHandler.c      |  4 +--
 src/test/regress/expected/graph_table.out |  4 +++
 4 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 4a76cab7b09..ee063f6c409 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -17,6 +17,7 @@
 
 #include "access/htup_details.h"
 #include "access/nbtree.h"
+#include "access/relation.h"
 #include "access/table.h"
 #include "access/tsmapi.h"
 #include "catalog/catalog.h"
@@ -901,6 +902,33 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
 										  tf, rtf->alias, is_lateral, true);
 }
 
+/*
+ * Similar to parserOpenTable() but for property graphs.
+ */
+static Relation
+parserOpenPropGraph(ParseState *pstate, const RangeVar *relation, int lockmode)
+{
+	Relation	rel;
+	ParseCallbackState pcbstate;
+
+	setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
+
+	rel = relation_openrv(relation, lockmode);
+
+	/*
+	 * In parserOpenTable(), the relkind check is done inside table_openrv*.
+	 * We do it here since we don't have anything like propgraph_open.
+	 */
+	if (rel->rd_rel->relkind != RELKIND_PROPGRAPH)
+		ereport(ERROR,
+				errcode(ERRCODE_WRONG_OBJECT_TYPE),
+				errmsg("\"%s\" is not a property graph",
+					   RelationGetRelationName(rel)));
+
+	cancel_parser_errposition_callback(&pcbstate);
+	return rel;
+}
+
 /*
  * transformRangeGraphTable -- transform a GRAPH_TABLE clause
  */
@@ -917,13 +945,7 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt)
 	int			resno = 0;
 	bool		saved_hasSublinks;
 
-	rel = parserOpenTable(pstate, rgt->graph_name, AccessShareLock);
-	if (rel->rd_rel->relkind != RELKIND_PROPGRAPH)
-		ereport(ERROR,
-				errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				errmsg("\"%s\" is not a property graph",
-					   RelationGetRelationName(rel)),
-				parser_errposition(pstate, rgt->graph_name->location));
+	rel = parserOpenPropGraph(pstate, rgt->graph_name, AccessShareLock);
 
 	graphid = RelationGetRelid(rel);
 
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 465ae088df5..4b03f34b8e1 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1508,20 +1508,6 @@ addRangeTableEntry(ParseState *pstate,
 	 * to a rel in a statement, we must open the rel with the proper lockmode.
 	 */
 	rel = parserOpenTable(pstate, relation, lockmode);
-
-	/*
-	 * validate_relation_kind() already catches indexes and composite types,
-	 * but we use table_openrv_extended() elsewhere for open a property graph
-	 * reference, which is not allowed here. Use similar error message as
-	 * validate_relation_kind().
-	 */
-	if (rel->rd_rel->relkind == RELKIND_PROPGRAPH)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot open relation \"%s\"",
-						RelationGetRelationName(rel)),
-				 errdetail_relkind_not_supported(rel->rd_rel->relkind)));
-
 	rte->relid = RelationGetRelid(rel);
 	rte->inh = inh;
 	rte->relkind = rel->rd_rel->relkind;
@@ -1601,19 +1587,6 @@ addRangeTableEntryForRelation(ParseState *pstate,
 		   lockmode == RowExclusiveLock);
 	Assert(CheckRelationLockedByMe(rel, lockmode, true));
 
-	/*
-	 * validate_relation_kind() already catches indexes and composite types,
-	 * but we use table_openrv_extended() elsewhere for open a property graph
-	 * reference, which is not allowed here. Use similar error message as
-	 * validate_relation_kind().
-	 */
-	if (rel->rd_rel->relkind == RELKIND_PROPGRAPH)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot open relation \"%s\"",
-						RelationGetRelationName(rel)),
-				 errdetail_relkind_not_supported(rel->rd_rel->relkind)));
-
 	rte->rtekind = RTE_RELATION;
 	rte->alias = alias;
 	rte->relid = RelationGetRelid(rel);
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 75b999d7e65..05def9d2593 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -197,7 +197,7 @@ AcquireRewriteLocks(Query *parsetree,
 				else
 					lockmode = rte->rellockmode;
 
-				rel = table_open(rte->relid, lockmode);
+				rel = relation_open(rte->relid, lockmode);
 
 				/*
 				 * While we have the relation open, update the RTE's relkind,
@@ -205,7 +205,7 @@ AcquireRewriteLocks(Query *parsetree,
 				 */
 				rte->relkind = rel->rd_rel->relkind;
 
-				table_close(rel, NoLock);
+				relation_close(rel, NoLock);
 				break;
 
 			case RTE_JOIN:
diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out
index f90dc29535f..547a6b50916 100644
--- a/src/test/regress/expected/graph_table.out
+++ b/src/test/regress/expected/graph_table.out
@@ -100,12 +100,16 @@ ERROR:  element pattern quantifier not supported yet
 -- a property graph can be referenced only from within GRAPH_TABLE clause.
 SELECT * FROM myshop; -- error
 ERROR:  cannot open relation "myshop"
+LINE 1: SELECT * FROM myshop;
+                      ^
 DETAIL:  This operation is not supported for property graphs.
 COPY myshop TO stdout; -- error
 ERROR:  cannot open relation "myshop"
 DETAIL:  This operation is not supported for property graphs.
 INSERT INTO myshop VALUES (1); -- error
 ERROR:  cannot open relation "myshop"
+LINE 1: INSERT INTO myshop VALUES (1);
+                    ^
 DETAIL:  This operation is not supported for property graphs.
 INSERT INTO products VALUES
     (1, 'product1', 10),
-- 
2.34.1

