Core Problem
PostgreSQL's SQL/PGQ (Property Graph Queries) feature, under development by Peter Eisentraut, introduces a new schema object: the property graph. A property graph is a catalog-level construct that describes a graph view over existing tables (vertex tables and edge tables) — it is not itself a data-bearing relation. It has no tuple layout, produces no result rows of its own type, and cannot be referenced the way a table or composite type can be.
Despite this, the initial implementation registered a pg_type row for every CREATE PROPERTY GRAPH object. This mirrors the long-standing PostgreSQL convention in which every relation recorded in pg_class (tables, views, materialized views, composite types, sequences, foreign tables, indexes with some nuance) also gets a companion row in pg_type representing its rowtype. That companion type is what allows constructs like SELECT t FROM t, composite-column usage, %ROWTYPE references in PL/pgSQL, and function return types referring to the relation.
For a property graph, none of that is meaningful:
- A property graph has no rows; the
MATCHclause projects columns from underlying vertex/edge tables, not from the graph object itself. - There is no coherent rowtype to associate — different label/property combinations yield different output shapes.
- No SQL feature (CAST, function signature, composite access,
record_in/record_out, etc.) is defined against a property graph's "type".
Leaving an unused pg_type row around is not merely cosmetic. It creates:
- Namespace pollution — the type name occupies the type namespace and can collide with user-created types.
- Catalog maintenance burden — every type-related operation (dependency tracking, ALTER ... RENAME, owner/ACL changes, drop cascades) must special-case or at least traverse this dead entry.
- Misleading semantics — tooling and users introspecting
pg_typewould see an entry that cannot be used in any type context.
Ashutosh's Proposal
Ashutosh Bapat observes the precedent: not every pg_class entry needs a companion pg_type row. The clearest examples are toast indexes and, more generally, objects for which a rowtype is nonsensical. He proposes aligning property graphs with that minority — skip the TypeCreate/GenerateTypeDependencies call path during CREATE PROPERTY GRAPH, and correspondingly skip the type cleanup on DROP.
His empirical validation is minimal but meaningful: make check passes unchanged. This confirms that no existing regression test exercises the property-graph type — which is itself evidence that the type entry serves no purpose. If any code path (planner, rewriter, parse analysis of PGQ) depended on looking up relam→reltype→pg_type for a property graph, the test suite would have caught it.
Design Decision and Its Implications
The committed change is small but has catalog-compatibility consequences, which is why Peter bumped catversion. Specifically:
- On-disk catalog shape changes. Existing clusters (even development clusters) that had created property graphs under the old code would have orphan
pg_typeentries; new initdb is required. pg_class.reltypebecomesInvalidOid(0) for property graphs, joining toast indexes and a few other edge cases. Code that unconditionally dereferencesreltypewhen iteratingpg_classmust tolerate zero — this is already standard practice in PostgreSQL, so the risk is low.- Dependency graph simplification. Dropping a property graph no longer needs to cascade through the rowtype dependency; the property-graph
pg_classentry is the single authoritative object.
The decision reflects a broader PostgreSQL principle: catalog entries should be created only when they carry semantic weight. Peter's quick agreement ("Agreed, committed") suggests this was an oversight in the original PGQ patch series — the CREATE PROPERTY GRAPH code path likely copied boilerplate from DefineRelation/view creation without reconsidering whether the rowtype was needed.
Why It Matters Architecturally
SQL/PGQ is still maturing in PostgreSQL. Getting the catalog representation right before the feature stabilizes and ships in a release is important: once external tools, extensions, and pg_dump logic assume a rowtype exists for property graphs, removing it becomes a compatibility break. Fixing it in the pre-release window is cheap; fixing it later is expensive. The catversion bump is the only externally visible cost, and during active development that cost is negligible.
The change also sets a precedent for future non-relational schema objects (e.g., if PostgreSQL grows additional SQL-standard schema object kinds that aren't rowtype-bearing). The rule becomes: if the object isn't queryable as a rowset in its own right, don't synthesize a rowtype.
Participant Weight
- Peter Eisentraut is the committer driving the SQL/PGQ feature in PostgreSQL and a core committer with deep experience in catalog design and SQL standards conformance. His same-day acceptance and commit indicate the issue is uncontroversial.
- Ashutosh Bapat is a long-time PostgreSQL contributor (major work on partitioning, postgres_fdw, parallelism) whose catalog-level observations carry weight. He framed the proposal correctly in terms of existing
pg_class/pg_typeconventions rather than as an ad hoc fix.
The brevity of the thread — two messages, four days apart, no objections — is itself a signal that this is a clean correction, not a contested design call.