Skip to Content
🚀 Introducing Polygres: Managed cloud for Postgres graph databases. Learn more at polygres.com →
User GuideSupported Features

Supported Features

This page summarizes the pgGraph 1.2 release surface and its explicit limits.

PostgreSQL source tables remain authoritative for every release. Graph writes use PostgreSQL DML before projection synchronization, and graph reads remain subject to the documented SQL, security, freshness, and resource contracts.

Stable 1.2 Features

AreaSupported behavior
PostgreSQL versionsPostgreSQL 14 through 18
RegistrationManual and discovered table, relationship, filter-column, and named-graph registration
SearchSource-table search with contains, exact, prefix, and token modes
TraversalBounded BFS and DFS with direction, relationship type, table, tenant, indexed filters, hydration, pagination, and resource limits
PathsUnweighted and weighted shortest paths across all registered relationship types, with optional relationship-type restriction through backward-compatible overloads
Open-vocabulary relationship typesA checked logical EdgeTypeId(u32) removes the historical 254-label graph ceiling under explicit limits of 1,000,000 distinct types, 1,024 UTF-8 bytes per label, and 256 MiB of label payload. Rebuilt bases and mutable segments use adaptive v7 one-, two-, or four-byte type storage and remain v6 read compatible. Trigger-backed committed graph.apply_sync() interns valid unseen labels and atomically publishes their cumulative dictionary. Mapped GQL relationship CREATE exposes unseen dynamic labels immediately inside the transaction, including savepoint rollback, exact filtering, and returned type spelling. Explicit GQL/Cypher dynamic types bind by endpoint mapping without scanning the source vocabulary; ambiguous mappings fail closed and absent types return no match. Eligible single-hop equality predicates on a registered relationship label column lower to the compact type filter. See the relationship type limits.
GQL and CypherThe documented GQL-compatible read/write subset and Cypher compatibility entry point
AnalyticsConnected components, path counting, and server-side aggregation
SynchronizationManual rebuild, trigger-log synchronization, maintenance, vacuum, and transaction-local overlays
PersistenceVersioned, validated graph artifacts with generation manifests and lazy backend loading
SecurityTable ACL enforcement, caller-scoped source-table RLS for topology, authorized operational telemetry, and PostgreSQL authority
PlaygroundDocker-backed Streamlit SQL playground with the Panama dataset fixture

Feature Maturity Details

CapabilityStatusIntended contract
Playground portability and stability fixesImplemented in 1.1Docker and Podman setup, deterministic Panama data, Python-shim handling, policy-compliant reuse of pre-provisioned virtual environments, cached initialization, scoped statement timeouts, and stable data-frame rendering
Cancellation-safe graph replacementImplemented in 1.1Build, vacuum, foreground/background maintenance, projection compaction/repair, and durable sync ingestion publish only validated generations under one per-graph writer lock. Cancellation before publication retains the previous generation and removes only the recorded unpublished candidate; interruption after publication reconciles the backend to the new generation. Low-memory eviction is rejected unless the serving base, projection files, and relationship-identity sidecar pass recovery validation.
Caller-preserving query boundaryImplemented in 1.1Topology query entry points run as SECURITY INVOKER, so direct calls execute hydration and source-table SQL as the application role. A caller-authored SECURITY DEFINER wrapper deliberately changes PostgreSQL’s effective current_user to its owner, as direct SQL in that wrapper does. Narrow pgGraph catalog mediators pin search_path, capture the outer role for graph authorization, and do not switch Rust user IDs.
Caller-scoped topology RLSImplemented in 1.1Every topology-producing surface intersects projected nodes and relationship identities with caller-visible source rows before admission. This includes direct traversal and path APIs, workflows, components and statistics, aggregation and path estimates, GQL node/identity scans, optional and multi-pattern matches, wildcard paths, Cypher lowering, and the projected MATCH phase of mapped GQL writes. PostgreSQL DML remains the final write authority.
Bounded direct-identity RLS probesImplemented after 1.1get_node and true depth-zero traversal resolve requested caller-visible source identities through typed, indexable PostgreSQL predicates for stable built-in key types. Every RLS-active mapping with a GUC-dependent, array, domain, or custom identity type fails closed because the 1.1 text identity does not retain enough information for safe matching under changed session settings. No-RLS and authorized legacy-bypass source-existence checks remain compatible. Whole-graph queries retain eager visibility until their own resumable executors land. Recursive policy-driven graph visibility resolution fails closed with diagnostic PG024.
Resumable targeted traversal RLSImplemented after 1.1Positive-depth BFS and DFS through traverse, multi-seed traversal and traverse_search, BFS-only get_neighbors, expand, find_related, and neighborhood, plus unweighted and weighted shortest_path, materialize bounded adjacency candidates before PostgreSQL policy probes. Traversal and unweighted paths cover clean CSR, committed in-memory edge_buffer overlays, bounded transaction-local edge overlays, and segment-backed durable projections. Weighted Dijkstra covers clean CSR and durable segments, preserves strict heap/tie and target-pop semantics, and retains the established PG018 error for pending weighted overlays. Dynamic relationship labels in rebuilt bases, committed durable deltas, and transaction-local mapped writes remain policy-governed. Projection borrows are released before set-based node and relationship probes, then candidates are admitted in original algorithm order. Workflow roots and find_related count passes share one statement-local resolver. No-RLS/BYPASS traversal and path execution retains its no-probe fast paths; identity-bounded one-hop GQL/Cypher uses the bounded executor and rechecks only matched PostgreSQL source rows. Transaction-local node/filter changes and other derived workflows retain the eager oracle until their remaining P4 cursors land.
Targeted GQL/Cypher RLSImplemented after 1.1Scalar-identity node scans, fixed one-hop Out/In matches, optional matches, and identity-bounded mapped SET matches use bounded caller-policy probes. Cypher uses the same physical selector. Multi-pattern joins, wildcard and variable-length paths, undirected expansion, whole-source scans, and other write shapes retain the eager oracle. PostgreSQL DML, locks, triggers, ACLs, RLS, and write-side rechecks remain authoritative. Resolver metrics report the bounded policy-probe work; defense-in-depth hydration can perform additional source SQL when hydration is requested.
Operational telemetry authorizationImplemented in 1.1Selected/named-graph status requires read authorization, artifact and build-resource status requires selected-graph admin authorization, cluster/resource telemetry requires graph-schema administration, and runtime rows are filtered to caller-readable graphs. These are physical totals, not RLS-row-filtered query results.
Query-start catalog deduplicationImplemented in 1.1Each topology query initialization composes one owned state from the selected graph and one registered-catalog read. Fingerprints, schema drift, tenant scope, and applicable sync relations derive from that state; caller/graph-bound sync mediators and automatic replay reuse it without weakening freshness, ACL, or sync checks.
Relationship-typed shortest pathsImplemented in 1.1Backward-compatible shortest-path overloads accept a required edge_types text[]; the unweighted array is the seventh argument so legacy calls, including an untyped fifth-argument NULL, remain unambiguous
Bounded relationship-type inventory and filtersImplemented in 1.2graph.status() exposes a 64-entry committed preview, while graph.edge_types() pages the complete effective dictionary in stable ID order. Relationship-type filter arrays are capped at 4,096 entries and 4 MiB before filter allocation. Retained exact-commit evidence covers 65 Criterion cases, eight PostgreSQL query cases, and Linux resource scaling at 1, 4, and 8 backends.
Relationship-table auto-discoveryImplemented in 1.2Schema-wide and targeted discovery register a binary composite-key junction with two distinct single-column foreign keys to single-column primary keys as one relationship edge. A surrogate-key table with that endpoint shape and a conventional text/varchar dynamic type column (relationship_name, relationship_type, edge_type, or rel_type) is inferred as one dynamic edge mapping. Composite FKs and alternate unique-key references are never guessed into endpoints; three-or-more-endpoint tables retain ordinary table/FK discovery for explicit review.
Registration-clearing resetImplemented in 1.2graph.reset() remains a projection-only reset that preserves selected-graph mappings. graph.reset(true) also clears the selected graph’s registered tables, edges, and filter columns without changing PostgreSQL source tables or other named graphs, including when stale relation OIDs would otherwise produce PG000.
1.1-to-1.2 package upgradeImplemented in 1.2ALTER EXTENSION graph UPDATE TO '1.2.0' adds graph.edge_types() and graph.reset(boolean) without replacing existing function objects or changing their owners and explicit grants. Existing v6 artifacts remain readable; new builds use adaptive v7 type storage. Rollback is backup restoration with the matching 1.1 package, never a 1.1 binary installed over 1.2 catalogs or v7 artifacts.
Registration troubleshootingExpanded in 1.2Documentation identifies missing ::regclass casts for table arguments and gives a scoped graph.reset(true) recovery sequence when stale relation OIDs produce PG000.

Current RLS Boundary

The 1.2 topology, GQL, Cypher, workflow, component, and analytics APIs evaluate applicable node and relationship policies in the effective PostgreSQL execution context, then exclude hidden identities before reachability, limits, paths, costs, component unions, statistics, or aggregate inputs are computed. Hidden seeds and targets behave as nonexistent, a hidden intermediate blocks visible nodes behind it, shortest-path selection chooses the best caller-visible route, and component and aggregate counts describe only caller-visible topology. graph.allow_rls_tables is now a deprecated no-op; builds accept RLS-enabled source tables by default.

The same rule applies before GQL/Cypher rows, optional null-extension, row caps, or write targets are selected. PostgreSQL then rechecks ACLs, RLS, constraints, and triggers when mapped graph writes execute against their source tables.

Not Targeted for 1.2

The following remain post-1.2 roadmap work:

  • bounded set-based graph mutation batches;
  • PostgreSQL 19 and SQL/PGQ integration;
  • a new topology trait hierarchy or cross-statement RLS cache; and
  • broader GQL syntax outside the documented profile.

See the Roadmap for future direction, the SQL Profile and GQL Profile for exact syntax, and Known Issues for current limitations.

Last updated on