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. 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. (Alternatively, we could make a separate switch case for RTE_GRAPH_TABLE.)

What do you think?

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.

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.
From 7eef5e5557adeee1da3770f306d8ff03c9aa463f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Wed, 18 Feb 2026 12:52:18 +0100
Subject: [PATCH] Sort out RELKIND_PROPGRAPH / table_open

---
 src/backend/access/table/table.c          |  3 +-
 src/backend/parser/parse_clause.c         | 37 ++++++++++++++++++-----
 src/backend/parser/parse_relation.c       | 27 -----------------
 src/backend/rewrite/rewriteHandler.c      |  4 +--
 src/test/regress/expected/graph_table.out |  4 +++
 5 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c
index fe330ae862a..1799a8762db 100644
--- a/src/backend/access/table/table.c
+++ b/src/backend/access/table/table.c
@@ -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..8828ee56475 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,34 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc 
*rtf)
                                                                                
  tf, rtf->alias, is_lateral, true);
 }
 
+/*
+ * Similar to parseOpenTable() 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 parserOpenPropGraph(), the relkind check is done inside
+        * table_openrv*.  Here, we do it manually, 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 +946,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),
-- 
2.53.0

Reply via email to