From 8e3373ec7682b881c5b12c0ebf6f68ba860ebb45 Mon Sep 17 00:00:00 2001 From: satyanarayana narlapuram Date: Mon, 20 Apr 2026 18:07:40 +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. Reported-by: Satyanarayana Narlapuram --- src/backend/commands/propgraphcmds.c | 30 +++++++++++++++++++ .../expected/create_property_graph.out | 6 ++++ .../regress/sql/create_property_graph.sql | 4 +++ 3 files changed, 40 insertions(+) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index 45d2ff1b..16ef611b 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1522,6 +1522,36 @@ 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++; + 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