Type of property graph

First seen: 2026-04-30 12:29:50+00:00 · Messages: 2 · Participants: 2

Latest Update

2026-05-06 · opus 4.7

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:

Leaving an unused pg_type row around is not merely cosmetic. It creates:

  1. Namespace pollution — the type name occupies the type namespace and can collide with user-created types.
  2. 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.
  3. Misleading semantics — tooling and users introspecting pg_type would 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 relamreltypepg_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:

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

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.