From b21ed425500c8bd492ed7acd615715c9d32ae3a7 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Wed, 1 Jul 2026 21:34:48 +0530
Subject: [PATCH v20260703 11/13] Fix GRANT ... TABLE on a property graph

A property graph only supports the SELECT privileges. Privileges can be
granted using either GRANT ... PROPERTY GRAPH or GRANT ... TABLE.  When
the GRANT ... TABLE form is used, ignore any privileges other than SELECT
and emit a warning, as we already do for sequences.

While here, add the missing RELKIND_PROPGRAPH cases in pg_class_aclmask_ext()
and in the object-type switch in ExecGrant_Relation() so that the default ACL
and the objtype passed to restrict_and_check_grant() are correct.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/20260630023308.c7.noahmisch@microsoft.com
---
 src/backend/catalog/aclchk.c                  | 31 ++++++++++++++++++-
 .../expected/create_property_graph.out        |  2 ++
 .../regress/sql/create_property_graph.sql     |  1 +
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 140cd1302f5..54b59892c43 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -1784,7 +1784,7 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
 }
 
 /*
- *	This processes both sequences and non-sequences.
+ * This processes all pg_class entries including sequences and property graphs.
  */
 static void
 ExecGrant_Relation(InternalGrant *istmt)
@@ -1891,6 +1891,29 @@ ExecGrant_Relation(InternalGrant *istmt)
 					this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
 				}
 			}
+			else if (pg_class_tuple->relkind == RELKIND_PROPGRAPH)
+			{
+				/*
+				 * Per the SQL standard, property graphs share the namespace
+				 * with tables, so GRANT ... ON TABLE also works on a property
+				 * graph. A property graph only supports SELECT, so mask off
+				 * any other requested privileges and emit a warning, as we do
+				 * for sequences.
+				 */
+				if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_PROPGRAPH))
+				{
+					/*
+					 * Mention the object name because the user needs to know
+					 * which operations succeeded.  This is required because
+					 * WARNING allows the command to continue.
+					 */
+					ereport(WARNING,
+							(errcode(ERRCODE_INVALID_GRANT_OPERATION),
+							 errmsg("property graph \"%s\" only supports SELECT privileges",
+									NameStr(pg_class_tuple->relname))));
+					this_privileges &= (AclMode) ACL_ALL_RIGHTS_PROPGRAPH;
+				}
+			}
 			else
 			{
 				if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
@@ -1996,6 +2019,9 @@ ExecGrant_Relation(InternalGrant *istmt)
 				case RELKIND_SEQUENCE:
 					objtype = OBJECT_SEQUENCE;
 					break;
+				case RELKIND_PROPGRAPH:
+					objtype = OBJECT_PROPGRAPH;
+					break;
 				default:
 					objtype = OBJECT_TABLE;
 					break;
@@ -3389,6 +3415,9 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
 			case RELKIND_SEQUENCE:
 				acl = acldefault(OBJECT_SEQUENCE, ownerId);
 				break;
+			case RELKIND_PROPGRAPH:
+				acl = acldefault(OBJECT_PROPGRAPH, ownerId);
+				break;
 			default:
 				acl = acldefault(OBJECT_TABLE, ownerId);
 				break;
diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out
index e9f91f77ee9..713966e8a9e 100644
--- a/src/test/regress/expected/create_property_graph.out
+++ b/src/test/regress/expected/create_property_graph.out
@@ -251,6 +251,8 @@ SET ROLE regress_graph_user1;
 GRANT SELECT ON PROPERTY GRAPH g1 TO regress_graph_user2;
 GRANT UPDATE ON PROPERTY GRAPH g1 TO regress_graph_user2;  -- fail
 ERROR:  invalid privilege type UPDATE for property graph
+GRANT UPDATE ON TABLE g1 TO regress_graph_user2;  -- warning
+WARNING:  property graph "g1" only supports SELECT privileges
 RESET ROLE;
 -- collation
 CREATE TABLE tc1 (a int, b text);
diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql
index 08341e13a50..5325d22206e 100644
--- a/src/test/regress/sql/create_property_graph.sql
+++ b/src/test/regress/sql/create_property_graph.sql
@@ -197,6 +197,7 @@ ALTER PROPERTY GRAPH g1 OWNER TO regress_graph_user1;
 SET ROLE regress_graph_user1;
 GRANT SELECT ON PROPERTY GRAPH g1 TO regress_graph_user2;
 GRANT UPDATE ON PROPERTY GRAPH g1 TO regress_graph_user2;  -- fail
+GRANT UPDATE ON TABLE g1 TO regress_graph_user2;  -- warning
 RESET ROLE;
 
 -- collation
-- 
2.34.1

