Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wFro2-005e7J-1Q for pgsql-hackers@arkaria.postgresql.org; Thu, 23 Apr 2026 11:01:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wFro1-001RoV-2K for pgsql-hackers@arkaria.postgresql.org; Thu, 23 Apr 2026 11:01:13 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wFro1-001RoN-0e for pgsql-hackers@lists.postgresql.org; Thu, 23 Apr 2026 11:01:13 +0000 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wFrnv-00000002P7n-006F for pgsql-hackers@lists.postgresql.org; Thu, 23 Apr 2026 11:01:12 +0000 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-48a563e4ef7so30332125e9.0 for ; Thu, 23 Apr 2026 04:01:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776942064; x=1777546864; darn=lists.postgresql.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=sEBnRx7cG8teD99pnxvVPCEphC0xJlIkJBYZHWRO6OU=; b=VNGFZbLuaPjXn1aIOIQ1A18npOWhMLmqKNdwKkXu8AMnjO4+xKNQKS3P623fD6t89s flnLLmITElMOTJ7t8x0MfpYPF6QJpxkSnPFZUi+l2FhHOdyMGVonJQ47libg3HW8DnDE vLw1FVwilBSYthVfA3in/X8KSprEdivXWZveXBZ8WQo0FGGHwKfCSw063wStETRcyOE/ Oq8LoDvraQrWiCXOaArDoDsPhdCTpRP1SoYllnS8tueOg6+msqIEZk1ZRsx5uq1duOvW VeDDUw3JbDjDNkvZhWOYE8PWqE9MA7dyTKgQ9uwKAvhpL0piZv7xHJhV0QmOAUivOlvA Gy3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776942064; x=1777546864; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sEBnRx7cG8teD99pnxvVPCEphC0xJlIkJBYZHWRO6OU=; b=J9v3qqw1WUovgLMEUxJD0WHxoVH3RThHgUkaVZRhYB+jUR+LqrxuAJT8wNkU9UdlAq Ma9rZ+1nnjQAlRwB5AGwoP7LB8/z2Hu36/m3OPQ4BEZ17urPADR9XTmFD93hrQTQST5v waNR9e8S1hUPjbBhizljFRU3ntlQ/Wl0jIzf4Pgoalls9xX8xuZCTzY65YWMFQ5fEEED QnpPGoMpaA+IbVnMNKiGTveIvIxaQSUbKYEdnnJ2Vl8kfNS5pJLhM4oz/nrBotuLI3wr xklvxp68TjCobzyGCQwrEJK8/qLcQd775ezFjyWEcBeoQsxLUlXKM21qZirErUZw8dLB 2Mhw== X-Forwarded-Encrypted: i=1; AFNElJ/LAs13NPAaRpWROssnUtRrXbevjxexO8xzs3pnS+55QQSREsEZ3yJ36vrwKxYzZkDDAoy3OOYcFvUubutt@lists.postgresql.org X-Gm-Message-State: AOJu0YysG0tP7+wcnfQpUi51NdCAubpiObPITYA/fCK3qsHL783xBNim 5maNOZuzUshoy2eBTU++Vor/cEr5gi6X6RwbuDDS4yeY0XFpVvcHSmJ3 X-Gm-Gg: AeBDieusJCYygPZ4MiRTRpJqaWZRmEEoi0W18/23j8CIoQE82J3GfZQ/W+JC9Et+rqw ETTuHhnV3e2pMjHG94P65lBbQ9acQzZfJf7GstX2A0hYX8lDdRc9GJZ+zO9dH3oJIrYEtfjbI2Z J27Z3Q4wKskWTJnxilC7dMGbQ5n5Xh/dWIvr78xdt9DhJ03PzUu2spRTQhx92s6LoN+LZA3zUIk /cEbnoxpu/lkWAlubCeR7W1HUU+tAixhIudGjnvrk58M0TY1aaftMZZKGdYf+rzzSBvrc2OXFdj /zKLAaqdwVJTVjBLiJ3r3plwW9dpXmObgFZdoJjGfz4+kT5dzCW9fRBBpXJuxMLnlq75YyP2N63 Z7DGtrt5aydT0zBXB+gGDAxD59TvKQXJRtKV5Xt4pLczmr5ygfhwkliekauU6fDXcQwvWb+yi5H IkYP6PbgJYNZlFkwsBkY3Mvvh87FHEiKJsFC1dPYVFTcZwNk8WSbQxX2COiL7ivhd+ahxl8RHrp jONgYGFVpIHztzmeRHXlg== X-Received: by 2002:a05:600c:2d91:b0:48a:5301:bb5c with SMTP id 5b1f17b1804b1-48a5301bc69mr113002825e9.16.1776942064259; Thu, 23 Apr 2026 04:01:04 -0700 (PDT) Received: from bdtpg (ec2-15-237-197-144.eu-west-3.compute.amazonaws.com. [15.237.197.144]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488ffc558f2sm379298115e9.1.2026.04.23.04.01.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Apr 2026 04:01:03 -0700 (PDT) Date: Thu, 23 Apr 2026 11:01:02 +0000 From: Bertrand Drouvot To: Ashutosh Bapat Cc: Michael Paquier , pgsql-hackers@lists.postgresql.org, Peter Eisentraut Subject: Re: Fix DROP PROPERTY GRAPH "unsupported object class" error Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="gtUR827Uq8d5gVsQ" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --gtUR827Uq8d5gVsQ Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi, On Thu, Apr 23, 2026 at 12:57:37PM +0530, Ashutosh Bapat wrote: > On Thu, Apr 23, 2026 at 12:09 PM Michael Paquier wrote: > > > > On Wed, Apr 22, 2026 at 04:19:26PM +0000, Bertrand Drouvot wrote: > > > Indeed, 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". > > > > Hmm. Couldn't these code paths be reached as well with the object > > functions like pg_describe_object(), pg_get_object_address(), > > pg_identify_object_as_address() or pg_identify_object()? Object > > descriptions usually stick within object_address.sql. The new objects > > you would want to stick should be covered as well in this test suite, > > and the file already has some property graphs in it. > > +1. See emails around [1] for some discussion about existing property > graph object definitions. Yeah that makes sense to also add some tests here, done in the attached. > > > The bug only manifests when an event trigger is active, because that is what > > > calls these functions. > > > That covers everything you want to test and its minimal change to the > test. But I see that the event triggers for all objects are tested in > event_triggers.sql. So I think the new test should be added to that > file. A simpler test has been done in event_trigger.sql instead. > > > I think that's worth an open item and I'll add one for this issue. > > > > This should be an open item, I guess, yes. Could you add one? One has already been created (I think you need to be logged in to see the updates). > Element label, label property are not user visible objects per say, so > I am not sure whether the code changes are in the right direction. But > it's also true that we shouldn't get an error in the presence of an > event trigger. We need to fix that. Agreed. Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com --gtUR827Uq8d5gVsQ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v2-0001-Fix-DROP-PROPERTY-GRAPH-unsupported-object-class-.patch" From 029179007d5cde0bcd1cca04cc1698cce39fd366 Mon Sep 17 00:00:00 2001 From: Bertrand Drouvot Date: Thu, 23 Apr 2026 09:27:39 +0000 Subject: [PATCH v2] Fix DROP PROPERTY GRAPH "unsupported object class" error getObjectTypeDescription() and getObjectIdentityParts() are missing switch cases for PropgraphElementLabelRelationId and PropgraphLabelPropertyRelationId, causing them to hit the default case and error out with "unsupported object class". During DROP PROPERTY GRAPH, this manifests when an event trigger is active, because pg_event_trigger_ddl_commands() calls these functions. The same code paths are also reachable via pg_identify_object() and pg_identify_object_as_address(). This commit adds the missing cases. Test coverage is added in object_address.sql for these two catalog types via the zero-OID test that exercises pg_identify_object() and pg_identify_object_as_address(). A test in event_trigger.sql verifies that DROP PROPERTY GRAPH works correctly when an event trigger is active. Author: Bertrand Drouvot Reviewed-by: Michael Paquier Reviewed-by: Ashutosh Bapat Discussion: https://postgr.es/m/aej1DkLwhyZWmtxJ@bdtpg --- src/backend/catalog/objectaddress.c | 93 ++++++++++++++++++++ src/test/regress/expected/event_trigger.out | 17 ++++ src/test/regress/expected/object_address.out | 4 + src/test/regress/sql/event_trigger.sql | 13 +++ src/test/regress/sql/object_address.sql | 2 + 5 files changed, 129 insertions(+) 62.4% src/backend/catalog/ 25.6% src/test/regress/expected/ 11.8% 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/event_trigger.out b/src/test/regress/expected/event_trigger.out index 065f586310f..ed8d5df397e 100644 --- a/src/test/regress/expected/event_trigger.out +++ b/src/test/regress/expected/event_trigger.out @@ -173,6 +173,23 @@ NOTICE: test_event_trigger: ddl_command_end CREATE USER MAPPING alter default privileges for role regress_evt_user revoke delete on tables from regress_evt_user; NOTICE: test_event_trigger: ddl_command_end ALTER DEFAULT PRIVILEGES +-- DROP PROPERTY GRAPH should work with event trigger in place +CREATE TABLE t1x (a int PRIMARY KEY, b text); +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_end CREATE TABLE +CREATE TABLE t2x (i int PRIMARY KEY, j text); +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_end CREATE TABLE +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1x KEY (a) LABEL l1 PROPERTIES (b AS p1), + t2x KEY (i) LABEL l2 PROPERTIES (j AS p1) +); +NOTICE: test_event_trigger: ddl_command_end CREATE PROPERTY GRAPH +DROP PROPERTY GRAPH gx; +NOTICE: test_event_trigger: ddl_command_end DROP PROPERTY GRAPH +DROP TABLE t1x, t2x; +NOTICE: test_event_trigger: ddl_command_end DROP TABLE -- alter owner to non-superuser should fail alter event trigger regress_event_trigger owner to regress_evt_user; ERROR: permission denied to change owner of event trigger "regress_event_trigger" diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index 97227d67a54..729c3537f25 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -593,7 +593,9 @@ WITH objects (classid, objid, objsubid) AS (VALUES ('pg_parameter_acl'::regclass, 0, 0), -- no parameter ACL ('pg_policy'::regclass, 0, 0), -- no policy ('pg_propgraph_element'::regclass, 0, 0), -- no property graph element + ('pg_propgraph_element_label'::regclass, 0, 0), -- no property graph element label ('pg_propgraph_label'::regclass, 0, 0), -- no property graph label + ('pg_propgraph_label_property'::regclass, 0, 0), -- no property graph label property ('pg_propgraph_property'::regclass, 0, 0), -- no property graph property ('pg_publication'::regclass, 0, 0), -- no publication ('pg_publication_namespace'::regclass, 0, 0), -- no publication namespace @@ -653,6 +655,8 @@ ORDER BY objects.classid, objects.objid, objects.objsubid; ("(""parameter ACL"",,,)")|("(""parameter ACL"",,)")|NULL ("(""property graph element"",,,)")|("(""property graph element"",,)")|NULL ("(""property graph label"",,,)")|("(""property graph label"",,)")|NULL +("(""property graph element label"",,,)")|("(""property graph element label"",,)")|NULL ("(""property graph property"",,,)")|("(""property graph property"",,)")|NULL +("(""property graph label property"",,,)")|("(""property graph label property"",,)")|NULL -- restore normal output mode \a\t diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql index 32e9bb58c5e..271f443378b 100644 --- a/src/test/regress/sql/event_trigger.sql +++ b/src/test/regress/sql/event_trigger.sql @@ -143,6 +143,19 @@ create user mapping for regress_evt_user server useless_server; alter default privileges for role regress_evt_user revoke delete on tables from regress_evt_user; +-- DROP PROPERTY GRAPH should work with event trigger in place +CREATE TABLE t1x (a int PRIMARY KEY, b text); +CREATE TABLE t2x (i int PRIMARY KEY, j text); + +CREATE PROPERTY GRAPH gx + VERTEX TABLES ( + t1x KEY (a) LABEL l1 PROPERTIES (b AS p1), + t2x KEY (i) LABEL l2 PROPERTIES (j AS p1) +); + +DROP PROPERTY GRAPH gx; +DROP TABLE t1x, t2x; + -- alter owner to non-superuser should fail alter event trigger regress_event_trigger owner to regress_evt_user; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index 1bbe9457c1c..620dacf1045 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -282,7 +282,9 @@ WITH objects (classid, objid, objsubid) AS (VALUES ('pg_parameter_acl'::regclass, 0, 0), -- no parameter ACL ('pg_policy'::regclass, 0, 0), -- no policy ('pg_propgraph_element'::regclass, 0, 0), -- no property graph element + ('pg_propgraph_element_label'::regclass, 0, 0), -- no property graph element label ('pg_propgraph_label'::regclass, 0, 0), -- no property graph label + ('pg_propgraph_label_property'::regclass, 0, 0), -- no property graph label property ('pg_propgraph_property'::regclass, 0, 0), -- no property graph property ('pg_publication'::regclass, 0, 0), -- no publication ('pg_publication_namespace'::regclass, 0, 0), -- no publication namespace -- 2.34.1 --gtUR827Uq8d5gVsQ--