On Wed, Feb 18, 2026 at 8:58 PM Peter Eisentraut <[email protected]> wrote:
>
> On 13.01.26 17:14, Ashutosh Bapat wrote:
> > On Tue, Jan 13, 2026 at 3:53 PM Peter Eisentraut <[email protected]> 
> > wrote:
> >>
> >> I have a small fixup patch for your 20260102 patches, attached.
> >>
> >> - needs additional #include because of recent changes elsewhere
> >> - copyright year updates
> >> - various typos
> >> - some style changes related to palloc APIs
> >
> > All changes look good.
> >
> > Looks like you have reviewed patches 0002-onwards. I removed 0004
> > which was erroneously removing the | handling from ecpg lexer as you
> > pointed out earlier. Squashed all other patches along with your small
> > fixup patch. Attached is the resultant single patch.
>
> I have studied a bit the changes in parse_relation.c with the additional
> relkind checks.  That didn't look clean to me.  I have attached here a
> patch that does it differently, by *not* accepting RELKIND_PROPGRAPH in
> table_open().  Instead, we write our own alternative to
> parserOpenTable() to use in the parser.  This ends up even giving some
> better error messages.

This looks good to me.

I wondered whether to create propgraph_open() and
validate_relation_kind() for propgraph in a separate file propgraph.c
on the lines of sequence.c. But we will still need something like
parserOpenPropGraph() to handle callback. So doesn't seem to have an
advantage of sequence_open which is not called from parser. Also
parserOpenPropGraph()'s placement seems to be ok since there is only
one caller in parse_clause.c. This looks better than the earlier
changes in parse_relation.c

> The only other change is that in
> AcquireRewriteLocks() we need to use relation_open() instead of
> table_open(), but that seems harmless and even intellectually better,
> because at that point we don't care about giving anyone a user-facing
> error message about wrong relkinds, we just want to lock the ones we
> have.

+1.

> (Alternatively, we could make a separate switch case for
> RTE_GRAPH_TABLE.)
>
> What do you think?

LGTM.

I am actually wondering whether the comment in parserOpenPropGraph()
is required. In case we want to keep it, the attached patch has a typo
fix. It also has some more improvements.

>
> Also, see this patch:
>
> https://www.postgresql.org/message-id/6d3fef19-a420-4e11-8235-8ea534bf2080%40eisentraut.org
>
> If this is accepted, it would make the change in the patch here even
> smaller.

+1. I think we should commit this, rebase SQL/PGQ patches and then
apply this change.

>
> And then there is this patch:
>
> https://www.postgresql.org/message-id/4bcd65fb-2497-484c-bb41-83cb435eb64d%40eisentraut.org
>
> which also grew out of this analysis.

Reviewed both the patches.

-- 
Best Wishes,
Ashutosh Bapat
diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c
index fe330ae862a..7479254ce21 100644
--- a/src/backend/access/table/table.c
+++ b/src/backend/access/table/table.c
@@ -131,7 +131,7 @@ table_close(Relation relation, LOCKMODE lockmode)
 /* ----------------
  *		validate_relation_kind - check the relation's kind
  *
- *		Make sure relkind is not index or composite type
+ *		Make sure relkind is not an index, a composite type or a property graph.
  * ----------------
  */
 static inline void
@@ -139,7 +139,8 @@ validate_relation_kind(Relation r)
 {
 	if (r->rd_rel->relkind == RELKIND_INDEX ||
 		r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX ||
-		r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
+		r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE ||
+		r->rd_rel->relkind == RELKIND_PROPGRAPH)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("cannot open relation \"%s\"",
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index dea5315bed1..25588acc4d7 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*.
+	 * Since we don't have anything like propgraph_open, we do it here.
+	 */
+	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 cd360917653..87ca5e000fb 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1512,20 +1512,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;
@@ -1609,19 +1595,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 2520cefae9d..01cc9691d4e 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),

Reply via email to