public inbox for [email protected]
help / color / mirror / Atom feedFrom: Bertrand Drouvot <[email protected]>
Subject: [PATCH v1] Fix DROP PROPERTY GRAPH "unsupported object class" error
Date: Wed, 22 Apr 2026 15:01:12 +0000
getObjectTypeDescription() and getObjectIdentityParts() are missing switch cases
for PropgraphElementLabelRelationId and PropgraphLabelPropertyRelationId, causing
DROP PROPERTY GRAPH to hit the default case and error out with
"unsupported object class".
The bug only manifests when an event trigger is active, because that is what
calls these functions.
This commit adds the missing cases so that DROP PROPERTY GRAPH, DROP PROPERTY GRAPH
IF EXISTS, and DROP SCHEMA CASCADE on schemas containing property graphs all work
correctly when event triggers are present.
It also adds test cases that create an event trigger and then exercise DROP PROPERTY
GRAPH and DROP SCHEMA CASCADE with property graphs.
Author: Bertrand Drouvot <[email protected]>
---
src/backend/catalog/objectaddress.c | 93 +++++++++++++++++++
.../expected/create_property_graph.out | 36 +++++++
.../regress/sql/create_property_graph.sql | 36 +++++++
3 files changed, 165 insertions(+)
54.5% src/backend/catalog/
24.2% src/test/regress/expected/
21.1% src/test/regress/sql/
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index c1862809577..e2d6d8f71f6 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -4901,10 +4901,18 @@ getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
appendStringInfoString(&buffer, "policy");
break;
+ case PropgraphElementLabelRelationId:
+ appendStringInfoString(&buffer, "property graph element label");
+ break;
+
case PropgraphElementRelationId:
appendStringInfoString(&buffer, "property graph element");
break;
+ case PropgraphLabelPropertyRelationId:
+ appendStringInfoString(&buffer, "property graph label property");
+ break;
+
case PropgraphLabelRelationId:
appendStringInfoString(&buffer, "property graph label");
break;
@@ -6161,6 +6169,49 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
}
+ case PropgraphElementLabelRelationId:
+ {
+ Relation ellabelDesc;
+ ScanKeyData skey[1];
+ SysScanDesc ellabelscan;
+ HeapTuple tup;
+ Form_pg_propgraph_element_label pgelform;
+ ObjectAddress oa;
+
+ ellabelDesc = table_open(PropgraphElementLabelRelationId, AccessShareLock);
+ ScanKeyInit(&skey[0],
+ Anum_pg_propgraph_element_label_oid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+ ellabelscan = systable_beginscan(ellabelDesc,
+ PropgraphElementLabelObjectIndexId,
+ true, NULL, 1, skey);
+
+ tup = systable_getnext(ellabelscan);
+ if (!HeapTupleIsValid(tup))
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for element label %u",
+ object->objectId);
+
+ systable_endscan(ellabelscan);
+ table_close(ellabelDesc, AccessShareLock);
+ break;
+ }
+
+ pgelform = (Form_pg_propgraph_element_label) GETSTRUCT(tup);
+
+ ObjectAddressSet(oa, PropgraphElementRelationId, pgelform->pgelelid);
+
+ appendStringInfoString(&buffer, getObjectIdentityParts(&oa, objname,
+ objargs, false));
+
+ systable_endscan(ellabelscan);
+ table_close(ellabelDesc, AccessShareLock);
+ break;
+ }
+
case PropgraphElementRelationId:
{
HeapTuple tup;
@@ -6184,6 +6235,48 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
}
+ case PropgraphLabelPropertyRelationId:
+ {
+ Relation lblpropDesc;
+ ScanKeyData skey[1];
+ SysScanDesc lblpropscan;
+ HeapTuple tup;
+ Form_pg_propgraph_label_property plpform;
+ ObjectAddress oa;
+
+ lblpropDesc = table_open(PropgraphLabelPropertyRelationId,
+ AccessShareLock);
+ ScanKeyInit(&skey[0],
+ Anum_pg_propgraph_label_property_oid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+ lblpropscan = systable_beginscan(lblpropDesc, PropgraphLabelPropertyObjectIndexId,
+ true, NULL, 1, skey);
+
+ tup = systable_getnext(lblpropscan);
+ if (!HeapTupleIsValid(tup))
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for label property %u",
+ object->objectId);
+
+ systable_endscan(lblpropscan);
+ table_close(lblpropDesc, AccessShareLock);
+ break;
+ }
+
+ plpform = (Form_pg_propgraph_label_property) GETSTRUCT(tup);
+
+ ObjectAddressSet(oa, PropgraphElementLabelRelationId, plpform->plpellabelid);
+ appendStringInfoString(&buffer, getObjectIdentityParts(&oa, objname,
+ objargs, false));
+
+ systable_endscan(lblpropscan);
+ table_close(lblpropDesc, AccessShareLock);
+ break;
+ }
+
case PropgraphLabelRelationId:
{
HeapTuple tup;
diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out
index bc9a596ec89..942a1294b15 100644
--- a/src/test/regress/expected/create_property_graph.out
+++ b/src/test/regress/expected/create_property_graph.out
@@ -922,5 +922,41 @@ ALTER PROPERTY GRAPH IF EXISTS g1 SET SCHEMA create_property_graph_tests_2;
NOTICE: relation "g1" does not exist, skipping
DROP PROPERTY GRAPH IF EXISTS g1;
NOTICE: property graph "g1" does not exist, skipping
+-- Test DROP PROPERTY GRAPH with dependency resolution
+RESET search_path;
+CREATE FUNCTION dpg_evt_func() RETURNS event_trigger
+LANGUAGE plpgsql AS $$
+BEGIN END;
+$$;
+CREATE EVENT TRIGGER dpg_evt ON ddl_command_end EXECUTE FUNCTION dpg_evt_func();
+CREATE TABLE dpg_t1 (id int PRIMARY KEY, val text);
+CREATE TABLE dpg_t2 (id int PRIMARY KEY, src int, dst int);
+CREATE PROPERTY GRAPH dpg_test
+ VERTEX TABLES (dpg_t1 KEY (id) LABEL person PROPERTIES (val AS name))
+ EDGE TABLES (dpg_t2 KEY (id)
+ SOURCE KEY (src) REFERENCES dpg_t1 (id)
+ DESTINATION KEY (dst) REFERENCES dpg_t1 (id)
+ LABEL knows);
+DROP PROPERTY GRAPH dpg_test;
+-- table survives graph drop
+SELECT COUNT(*) FROM dpg_t1;
+ count
+-------
+ 0
+(1 row)
+
+DROP TABLE dpg_t1, dpg_t2;
+-- Test DROP SCHEMA CASCADE with property graphs inside
+CREATE SCHEMA dpg_schema;
+SET search_path = dpg_schema;
+CREATE TABLE t (id int PRIMARY KEY);
+CREATE PROPERTY GRAPH g VERTEX TABLES (t KEY (id));
+RESET search_path;
+DROP SCHEMA dpg_schema CASCADE;
+NOTICE: drop cascades to 2 other objects
+DETAIL: drop cascades to table dpg_schema.t
+drop cascades to property graph dpg_schema.g
+DROP EVENT TRIGGER dpg_evt;
+DROP FUNCTION dpg_evt_func;
DROP ROLE regress_graph_user1, regress_graph_user2;
-- leave remaining objects behind for pg_upgrade/pg_dump tests
diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql
index 241f93df302..857098dadc8 100644
--- a/src/test/regress/sql/create_property_graph.sql
+++ b/src/test/regress/sql/create_property_graph.sql
@@ -360,6 +360,42 @@ ALTER PROPERTY GRAPH g1 ADD VERTEX TABLES (t1 KEY (a)); -- error
ALTER PROPERTY GRAPH IF EXISTS g1 SET SCHEMA create_property_graph_tests_2;
DROP PROPERTY GRAPH IF EXISTS g1;
+
+-- Test DROP PROPERTY GRAPH with dependency resolution
+
+RESET search_path;
+CREATE FUNCTION dpg_evt_func() RETURNS event_trigger
+LANGUAGE plpgsql AS $$
+BEGIN END;
+$$;
+
+CREATE EVENT TRIGGER dpg_evt ON ddl_command_end EXECUTE FUNCTION dpg_evt_func();
+
+CREATE TABLE dpg_t1 (id int PRIMARY KEY, val text);
+CREATE TABLE dpg_t2 (id int PRIMARY KEY, src int, dst int);
+CREATE PROPERTY GRAPH dpg_test
+ VERTEX TABLES (dpg_t1 KEY (id) LABEL person PROPERTIES (val AS name))
+ EDGE TABLES (dpg_t2 KEY (id)
+ SOURCE KEY (src) REFERENCES dpg_t1 (id)
+ DESTINATION KEY (dst) REFERENCES dpg_t1 (id)
+ LABEL knows);
+DROP PROPERTY GRAPH dpg_test;
+
+-- table survives graph drop
+SELECT COUNT(*) FROM dpg_t1;
+DROP TABLE dpg_t1, dpg_t2;
+
+-- Test DROP SCHEMA CASCADE with property graphs inside
+CREATE SCHEMA dpg_schema;
+SET search_path = dpg_schema;
+CREATE TABLE t (id int PRIMARY KEY);
+CREATE PROPERTY GRAPH g VERTEX TABLES (t KEY (id));
+RESET search_path;
+DROP SCHEMA dpg_schema CASCADE;
+
+DROP EVENT TRIGGER dpg_evt;
+DROP FUNCTION dpg_evt_func;
+
DROP ROLE regress_graph_user1, regress_graph_user2;
-- leave remaining objects behind for pg_upgrade/pg_dump tests
--
2.34.1
--s/7v445LwpBnK/Gl--
view thread (1532+ 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]
Subject: Re: [PATCH v1] Fix DROP PROPERTY GRAPH "unsupported object class" error
In-Reply-To: <no-message-id-472009@localhost>
* 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