From 2046f489f06685131b4908292f806e1c44f6e1d7 Mon Sep 17 00:00:00 2001 From: satyanarayana narlapuram Date: Tue, 21 Apr 2026 07:52:56 +0000 Subject: [PATCH] Prevent dropping the last label from a property graph element ALTER PROPERTY GRAPH ... DROP LABEL allowed removing the last label from an element, leaving it with zero labels. This causes pg_get_propgraphdef() to crash. Add a check in AlterPropGraph() that counts the element's labels before deletion and errors out if only one remains. The label count loop breaks early once it finds more than one label, avoiding a full scan of the element_label catalog. Update the ALTER PROPERTY GRAPH documentation to mention the restriction. Reported-by: Satyanarayana Narlapuram --- doc/src/sgml/ref/alter_property_graph.sgml | 2 ++ src/backend/commands/propgraphcmds.c | 34 +++++++++++++++++++ .../expected/create_property_graph.out | 6 ++++ .../regress/sql/create_property_graph.sql | 4 +++ 4 files changed, 46 insertions(+) diff --git a/doc/src/sgml/ref/alter_property_graph.sgml b/doc/src/sgml/ref/alter_property_graph.sgml index 19352c06..8bcca0ec 100644 --- a/doc/src/sgml/ref/alter_property_graph.sgml +++ b/doc/src/sgml/ref/alter_property_graph.sgml @@ -100,6 +100,8 @@ ALTER PROPERTY GRAPH [ IF EXISTS ] name This form removes a label from an existing vertex or edge table. + The last label on an element table cannot be dropped; every element + table must have at least one label. diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 45d2ff1b..b1c5e8ae 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1522,6 +1522,40 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) get_rel_name(pgrelid), stmt->element_alias, stmt->drop_label), parser_errposition(pstate, -1)); + /* + * Prevent dropping the last label from an element. Every element + * must have at least one label. + */ + { + Relation elrel; + SysScanDesc elscan; + ScanKeyData elkey[1]; + int nlabels = 0; + + elrel = table_open(PropgraphElementLabelRelationId, AccessShareLock); + ScanKeyInit(&elkey[0], + Anum_pg_propgraph_element_label_pgelelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(peoid)); + elscan = systable_beginscan(elrel, PropgraphElementLabelElementLabelIndexId, + true, NULL, 1, elkey); + while (HeapTupleIsValid(systable_getnext(elscan))) + { + nlabels++; + if (nlabels > 1) + break; + } + systable_endscan(elscan); + table_close(elrel, AccessShareLock); + + if (nlabels <= 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot drop the last label from element \"%s\"", + stmt->element_alias), + errhint("Every element must have at least one label."))); + } + ObjectAddressSet(obj, PropgraphElementLabelRelationId, ellabeloid); performDeletion(&obj, stmt->drop_behavior, 0); diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index bc9a596e..740f886c 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -57,6 +57,12 @@ ALTER PROPERTY GRAPH g3 ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3x; -- error ERROR: property graph "g3" element "t3" has no label "t3l3x" ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3; +-- Test that the last label on an element cannot be dropped +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l2; +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l1; -- error: last label +ERROR: cannot drop the last label from element "t3" +HINT: Every element must have at least one label. +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 ADD LABEL t3l2 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2); -- fail ERROR: cannot drop vertex t2 of property graph g3 because other objects depend on it DETAIL: edge e1 of property graph g3 depends on vertex t2 of property graph g3 diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 241f93df..4cf77159 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -52,6 +52,10 @@ ALTER PROPERTY GRAPH g3 ADD LABEL t3l3 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3x; -- error ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l3; +-- Test that the last label on an element cannot be dropped +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l2; +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 DROP LABEL t3l1; -- error: last label +ALTER PROPERTY GRAPH g3 ALTER VERTEX TABLE t3 ADD LABEL t3l2 PROPERTIES ALL COLUMNS; ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2); -- fail ALTER PROPERTY GRAPH g3 DROP VERTEX TABLES (t2) CASCADE; ALTER PROPERTY GRAPH g3 DROP EDGE TABLES (e2); -- 2.43.0