| From: | Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> |
|---|---|
| To: | Andres Freund <andres(at)anarazel(dot)de>, Peter Eisentraut <peter(at)eisentraut(dot)org> |
| Cc: | pgsql-hackers(at)postgresql(dot)org |
| Subject: | Re: PGQ catalog representation and pg_dump support |
| Date: | 2026-09-01 11:50:16 |
| Message-ID: | CAExHW5vO4PPWWT3netjDw5d3nWSFRm3HRWP+iTA9WDpQ_BVxJg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Tue, Sep 1, 2026 at 12:31 PM Ashutosh Bapat
<ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > > - External cascades leave orphan graph metadata
> > >
> > > ALTER PROPERTY GRAPH explicitly removes unused labels/properties, but generic
> > > dependency deletion bypasses that cleanup:
> > >
> > > CREATE TABLE v (id int PRIMARY KEY);
> > > CREATE PROPERTY GRAPH g
> > > VERTEX TABLES (v LABEL l PROPERTIES (id AS p));
> > > DROP TABLE v CASCADE;
> > >
> > > g retains global label l and integer property p. Adding a new text property named p then incorrectly
> > > reports a type mismatch.
> > >
> > >
> > > SELECT count(*) AS elements
> > > FROM pg_propgraph_element
> > > WHERE pgepgid = 'g'::regclass;
> > >
> > > SELECT count(*) AS labels
> > > FROM pg_propgraph_label
> > > WHERE pglpgid = 'g'::regclass;
> > >
> > > SELECT count(*) AS properties
> > > FROM pg_propgraph_property
> > > WHERE pgppgid = 'g'::regclass;
> > >
> > > CREATE TABLE v2 (id text PRIMARY KEY);
> > >
> > > ALTER PROPERTY GRAPH g
> > > ADD VERTEX TABLES (
> > > v2 LABEL l PROPERTIES (id AS p)
> > > );
> > >
> > > ERROR: 42601: property "p" data type mismatch: integer vs. text
> > > DETAIL: In a property graph, a property of the same name has to have the same data type in each label.
> > >
> >
> > Thanks for reporting it. I did not find any existing code which deals
> > with delete-when-reference-drops-to-zero behaviour. Ideally, we should
> > invent a new kind of dependency that will delete the dependent objects
> > when the number of references to the object drops to zero. But it's
> > possibly too late for that kind of change for PG 19 and the semantics
> > of such a dependency need to be carefully thought through to be
> > applicable beyond property graphs. We can rework this in a future
> > release and introduce such a dependency cleanup mechanism. For now, I
> > am adding a special handling in performDeletion() and
> > performMultipleDeletions() to collect and delete all the orphaned
> > property graph objects. To make it easy to convert it entirely driven
> > by dependency mechanism later, the code in the patch makes use of
> > pg_depend to find the orphaned property graph objects instead of using
> > the property graph catalog as much as possible.
> >
> > To avoid code duplication, AlterPropGraph() also uses the same
> > routines to delete orphaned property graph objects. Current
> > AlterPropGraph() cleans up all the orphaned property graph objects
> > once per command but it examines every object irrespective of whether
> > its parent object was deleted or not. With this change we examine only
> > objects downstream to the objects that are being deleted but it means
> > we might be doing it multiple times for the same object. Given that
> > ALTER PROPERTY GRAPH can drop only one parent object at a time, the
> > probability of that leading to multiple deletions cascading to a
> > single orphaned object is low. So, I think it's a net win.
> >
> > This fix is in 0002 patch which is WIP. I will be working more on it
> > tomorrow. Early comments are welcome.
> >
> > - Similarly, query plan caching is not handled correctly after a CASCADE style
> > dropping.
> >
> > AlterPropGraph() calls CacheInvalidateRelcacheByRelid(), but that's not
> > invoked when done via performDeletion() -> DropObjectById().
> >
>
> I extended the earlier fix to drop the orphaned property and label
> entries also to invalidate the caches.
>
> Attached patchset has
> 0001 - a minor code refactoring to help 0004
> 0002 - a minor test case comment clarifying intention of the test case
> 0003 - pg_dump dependency transfer fix
> 0004 - fixes dropping orphaned property and label entries and also
> invalidate caches because of cascaded drops.
>
> >
> > - Views depend only on global pg_propgraph_label and pg_propgraph_property rows
> > not the specific label/property association.
>
>
> CREATE TABLE v1 (id integer PRIMARY KEY, n integer);
> CREATE TABLE v2 (id integer PRIMARY KEY, n integer);
>
> CREATE PROPERTY GRAPH g
> VERTEX TABLES (
> v1 LABEL l1 PROPERTIES (n AS p) LABEL keep NO PROPERTIES,
> v2 LABEL l2 PROPERTIES (n AS p)
> );
>
> CREATE VIEW gv AS
> SELECT *
> FROM GRAPH_TABLE (
> g MATCH (x IS l1)
> COLUMNS (x.p)
> );
>
> ALTER PROPERTY GRAPH g
> ALTER VERTEX TABLE v1
> ALTER LABEL l1 DROP PROPERTIES (p);
>
> SELECT to_regclass('gv') AS view_still_exists;
> SELECT * FROM gv;
>
> results in:
>
> ERROR: 42704: property "p" for element variable "x" not found
This behaviour is governed by section 11.26, syntax rule 8.a. It says
If ALTER LABEL action immediately contains DROP PROPERTY then:
a. If RESTRICT is specified, then SPG (the property graph specified in
the ALTER PROPERTY GRAPH statement) shall not be referenced in any of
the following: the list here includes, views, functions, constraints,
value expressions in other property graph etc.
b. Note 164 says "If CASCADE is specified, then any such dependent
object will be dropped by the execution of the revoke statement
specified in the general rules of this subclause." I did not find any
revoke statement in section 11.26. Something to fix , but there's a
revoke statement in DROP PROPERTY GRAPH section.
Interpreting a and b together, in the above case dropping the property
should not be allowed in RESTRICT mode. In CASCADE mode however, the
view should be dropped. That's consistent with the other DROP CASCADE
behaviours. However, consider the case below:
CREATE FUNCTION shared_f() RETURNS int LANGUAGE SQL RETURN 1;
ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t1 ADD LABEL shared_l
PROPERTIES (shared_f() AS shared_p);
ALTER PROPERTY GRAPH g4 ALTER VERTEX TABLE t2 ADD LABEL shared_l
PROPERTIES (i AS shared_p);
DROP FUNCTION shared_f() CASCADE;
DROP FUNCTION would lead to dropping the property shared_p in label
shared_l of element t1. But the shared_p in label shared_l of element
t2 remains unaffected, but now the two labels are inconsistent with
each other. The section 11.26 does not specify directly the outcome of
this situation. Should DROP FUNCTION be rejected because property
graph consistency rules fail even if CASCADE is specified? That looks
inconsistent with how CASCADE mode is applied in other cases. Can you
please clarify?
--
Best Wishes,
Ashutosh Bapat
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Nazir Bilal Yavuz | 2026-09-01 11:50:56 | Re: aio: Async fsyncs for crash recovery and checkpointer |
| Previous Message | David Geier | 2026-09-01 11:05:23 | Re: Reduce build times of pg_trgm GIN indexes |