On Fri, Jun 5, 2026 at 7:59 PM zengman <[email protected]> wrote: > > Hi all, > > I noticed that ALTER PROPERTY GRAPH ... DROP LABEL doesn't clean up > orphaned pg_propgraph_property entries. The cleanup condition in > RemoveRelations() only checks for drop_properties, > drop_vertex_tables, and drop_edge_tables, but not drop_label. > > Before fix: > > ```sql > postgres@zxm-VMware-Virtual-Platform:~/code/postgres$ psql > psql (19beta1) > Type "help" for help. > > postgres=# CREATE TABLE v4 (a int PRIMARY KEY, b int, c int); > CREATE TABLE > postgres=# CREATE PROPERTY GRAPH g5 > VERTEX TABLES ( > v4 LABEL l1 PROPERTIES (a, b, c) > LABEL l2 PROPERTIES (a) > ); > CREATE PROPERTY GRAPH > postgres=# ALTER PROPERTY GRAPH g5 ALTER VERTEX TABLE v4 DROP LABEL l1; > ALTER PROPERTY GRAPH > postgres=# SELECT pgpname FROM pg_propgraph_property > WHERE pgppgid = 'g5'::regclass ORDER BY pgpname; > pgpname > --------- > a > b > c > (3 rows) > ``` > > After fix: > ```sql > postgres@zxm-VMware-Virtual-Platform:~/code/postgres$ psql > psql (19beta1) > Type "help" for help. > > postgres=# CREATE TABLE v4 (a int PRIMARY KEY, b int, c int); > CREATE TABLE > postgres=# CREATE PROPERTY GRAPH g5 > VERTEX TABLES ( > v4 LABEL l1 PROPERTIES (a, b, c) > LABEL l2 PROPERTIES (a) > ); > CREATE PROPERTY GRAPH > postgres=# ALTER PROPERTY GRAPH g5 ALTER VERTEX TABLE v4 DROP LABEL l1; > ALTER PROPERTY GRAPH > postgres=# SELECT pgpname FROM pg_propgraph_property > WHERE pgppgid = 'g5'::regclass ORDER BY pgpname; > pgpname > --------- > a > (1 row) > ``` > > ```sql > CREATE TABLE v4 (a int PRIMARY KEY, b int, c int); > CREATE PROPERTY GRAPH g5 > VERTEX TABLES ( > v4 LABEL l1 PROPERTIES (a, b, c) > LABEL l2 PROPERTIES (a) > ); > ALTER PROPERTY GRAPH g5 ALTER VERTEX TABLE v4 DROP LABEL l1; > SELECT pgpname FROM pg_propgraph_property > WHERE pgppgid = 'g5'::regclass ORDER BY pgpname; > ```
Thanks for the report and the patch. The fix is on the right track. I changed a few things as follows a. we usually add operands to the same operator at the end, not at the beginning. b. create_property_graph.sql, which tests all property graph DDLs, is the right place to add these tests. graph_table.sql tests graph query. I have used an existing property graph in create_property_graph.sql in the test. It removes a label from the property graph which has two properties associated with it, one that gets orphaned and one that doesn't. We can verify that the orphaned property gets dropped from the property graph but not the other one by information schema query outputs later. So didn't add any separate verification step after the DDL. Attached patch with those changes. -- Best Wishes, Ashutosh Bapat
From 94f2c313519d56ba3c6ea2bf298d2852628dd060 Mon Sep 17 00:00:00 2001 From: Ashutosh Bapat <[email protected]> Date: Wed, 10 Jun 2026 22:08:49 +0530 Subject: [PATCH v20260611 10/10] Properties orphaned by dropping a label AlterPropGraph() cleans up properties that are orphaned by dropping an element or properties associated with an element. But it doesn't clean up properties that are orphaned by dropping a label. Fix this missing case. Author: Ashutosh Bapat <[email protected]> Author: zengman <[email protected]>. Reported by: zengman <[email protected]> --- src/backend/commands/propgraphcmds.c | 3 ++- .../expected/create_property_graph.out | 23 +++++++++---------- .../regress/sql/create_property_graph.sql | 5 ++++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index fc998b3e244..1041be05189 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -1673,7 +1673,8 @@ AlterPropGraph(ParseState *pstate, const AlterPropGraphStmt *stmt) } /* Remove any orphaned pg_propgraph_property entries */ - if (stmt->drop_properties || stmt->drop_vertex_tables || stmt->drop_edge_tables) + if (stmt->drop_properties || stmt->drop_vertex_tables || + stmt->drop_edge_tables || stmt->drop_label) { foreach_oid(propoid, get_graph_property_ids(pgrelid)) { diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 1e733f9b572..60afeeac175 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -90,6 +90,11 @@ ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error ERROR: property graph "g4" element "t2" label "t2" has no property "yy" +-- Dropping a label should drop only orphaned properties. zz is orphaned because +-- it is only associated with the dropped label t3l2, while x is not orphaned +-- because it remains associated with t3l1. We will verify this in the +-- information schema queries outputs below. +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 DROP LABEL t3l2; CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); CREATE TABLE t13 ( @@ -447,7 +452,6 @@ SELECT * FROM information_schema.pg_element_table_labels ORDER BY property_graph regression | create_property_graph_tests | g4 | t1 | t1 regression | create_property_graph_tests | g4 | t2 | t2 regression | create_property_graph_tests | g4 | t3 | t3l1 - regression | create_property_graph_tests | g4 | t3 | t3l2 regression | create_property_graph_tests | g5 | t11 | t11 regression | create_property_graph_tests | g5 | t12 | t12 regression | create_property_graph_tests | g5 | t13 | t13 @@ -459,7 +463,7 @@ SELECT * FROM information_schema.pg_element_table_labels ORDER BY property_graph regression | create_property_graph_tests | gt | e | e regression | create_property_graph_tests | gt | v1 | v1 regression | create_property_graph_tests | gt | v2 | v2 -(26 rows) +(25 rows) SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_graph_name, element_table_alias, property_name; property_graph_catalog | property_graph_schema | property_graph_name | element_table_alias | property_name | property_expression @@ -493,7 +497,6 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | g4 | t2 | kk | (k * 2) regression | create_property_graph_tests | g4 | t3 | x | x regression | create_property_graph_tests | g4 | t3 | yy | y - regression | create_property_graph_tests | g4 | t3 | zz | z regression | create_property_graph_tests | g5 | t11 | a | a regression | create_property_graph_tests | g5 | t12 | b | b regression | create_property_graph_tests | g5 | t13 | c | c @@ -518,7 +521,7 @@ SELECT * FROM information_schema.pg_element_table_properties ORDER BY property_g regression | create_property_graph_tests | gt | v1 | b | b regression | create_property_graph_tests | gt | v2 | m | m regression | create_property_graph_tests | gt | v2 | n | n -(54 rows) +(53 rows) SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_name, label_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name | property_name @@ -558,8 +561,6 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | g4 | t2 | kk regression | create_property_graph_tests | g4 | t3l1 | x regression | create_property_graph_tests | g4 | t3l1 | yy - regression | create_property_graph_tests | g4 | t3l2 | x - regression | create_property_graph_tests | g4 | t3l2 | zz regression | create_property_graph_tests | g5 | t11 | a regression | create_property_graph_tests | g5 | t12 | b regression | create_property_graph_tests | g5 | t13 | c @@ -584,7 +585,7 @@ SELECT * FROM information_schema.pg_label_properties ORDER BY property_graph_nam regression | create_property_graph_tests | gt | v1 | b regression | create_property_graph_tests | gt | v2 | m regression | create_property_graph_tests | gt | v2 | n -(61 rows) +(59 rows) SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_name; property_graph_catalog | property_graph_schema | property_graph_name | label_name @@ -603,7 +604,6 @@ SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_n regression | create_property_graph_tests | g4 | t1 regression | create_property_graph_tests | g4 | t2 regression | create_property_graph_tests | g4 | t3l1 - regression | create_property_graph_tests | g4 | t3l2 regression | create_property_graph_tests | g5 | t11 regression | create_property_graph_tests | g5 | t12 regression | create_property_graph_tests | g5 | t13 @@ -615,7 +615,7 @@ SELECT * FROM information_schema.pg_labels ORDER BY property_graph_name, label_n regression | create_property_graph_tests | gt | e regression | create_property_graph_tests | gt | v1 regression | create_property_graph_tests | gt | v2 -(26 rows) +(25 rows) SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_name, property_name; property_graph_catalog | property_graph_schema | property_graph_name | property_name | data_type | character_maximum_length | character_octet_length | character_set_catalog | character_set_schema | character_set_name | collation_catalog | collation_schema | collation_name | numeric_precision | numeric_precision_radix | numeric_scale | datetime_precision | interval_type | interval_precision | user_defined_type_catalog | user_defined_type_schema | user_defined_type_name | scope_catalog | scope_schema | scope_name | maximum_cardinality | dtd_identifier @@ -641,7 +641,6 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | g4 | t | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | t regression | create_property_graph_tests | g4 | x | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | x regression | create_property_graph_tests | g4 | yy | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | yy - regression | create_property_graph_tests | g4 | zz | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | zz regression | create_property_graph_tests | g5 | a | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | a regression | create_property_graph_tests | g5 | b | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | b regression | create_property_graph_tests | g5 | c | integer | | | | | | regression | | | | | | | | | regression | pg_catalog | int4 | | | | | c @@ -659,7 +658,7 @@ SELECT * FROM information_schema.pg_property_data_types ORDER BY property_graph_ regression | create_property_graph_tests | gt | k2 | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | k2 regression | create_property_graph_tests | gt | m | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | m regression | create_property_graph_tests | gt | n | text | | | | | | regression | | | | | | | | | regression | pg_catalog | text | | | | | n -(39 rows) +(38 rows) SELECT * FROM information_schema.pg_property_graph_privileges WHERE grantee LIKE 'regress%' ORDER BY property_graph_name, grantor, grantee, privilege_type; grantor | grantee | property_graph_catalog | property_graph_schema | property_graph_name | privilege_type | is_grantable @@ -809,7 +808,7 @@ CREATE PROPERTY GRAPH create_property_graph_tests.g4 VERTEX TABLES ( t1 KEY (a) NO PROPERTIES, t2 KEY (i) PROPERTIES ((i + j) AS i_j, (k * 2) AS kk), - t3 KEY (x) LABEL t3l1 PROPERTIES (x, y AS yy) LABEL t3l2 PROPERTIES (x, z AS zz) + t3 KEY (x) LABEL t3l1 PROPERTIES (x, y AS yy) ) EDGE TABLES ( e1 KEY (a, i) SOURCE KEY (a) REFERENCES t1 (a) DESTINATION KEY (i) REFERENCES t2 (i) PROPERTIES (a, i, t), diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 0c3aa81e9ca..e7826548808 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -80,6 +80,11 @@ CREATE PROPERTY GRAPH g4 ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 ADD PROPERTIES (k * 2 AS kk); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (k); ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ALTER LABEL t2 DROP PROPERTIES (yy); -- error +-- Dropping a label should drop only orphaned properties. zz is orphaned because +-- it is only associated with the dropped label t3l2, while x is not orphaned +-- because it remains associated with t3l1. We will verify this in the +-- information schema queries outputs below. +ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t3 DROP LABEL t3l2; CREATE TABLE t11 (a int PRIMARY KEY); CREATE TABLE t12 (b int PRIMARY KEY); -- 2.34.1
