Skip to content

Releases: Evokoa/pgGraph

v1.1.0: pgGraph Caller-Scoped RLS And Safe Replacement

Choose a tag to compare

@evokoa-admin evokoa-admin released this 16 Aug 07:19
v1.1.0

pgGraph v1.1.0 makes PostgreSQL source-table RLS authoritative for graph topology,
hardens projection replacement against cancellation, reduces query-start
catalog work, and adds relationship-typed shortest paths. It supports
PostgreSQL 14 through 18 and preserves the stable 1.0 SQL result shapes.

Security Changes

  • graph.traverse(), graph.connected_components(), and
    graph.component_stats() now execute as SECURITY INVOKER. Hydration and
    later source-table visibility probes see the outer application role.
  • Selected/named-graph catalog access remains behind pinned, caller-authorizing
    SECURITY DEFINER mediators. No Rust user-ID switching is used.
  • Runtime status rows are filtered to readable graphs. Selected-graph artifact
    and build-resource telemetry requires graph admin; cluster generation and
    backend resource telemetry requires graph-schema administration.
  • Raw build and maintenance job tables no longer grant PUBLIC reads. Their
    status APIs use pinned caller-authorizing mediators, and heartbeat mediators
    no longer accept caller-supplied generations or watermarks.
  • Status counts remain physical projection totals. They are not
    source-table-RLS-filtered query results.
  • Every topology-producing surface enforces caller visibility before topology
    becomes observable. Hidden seeds and targets behave as nonexistent; hidden
    intermediates and relationship rows do
    not affect reachability, paths, costs, components, statistics, aggregation,
    GQL/Cypher matching, or mapped-write target selection.
  • graph.rls_mode = 'enforce' is the default. The superuser-only
    legacy_bypass value is a temporary compatibility escape hatch.
    graph.allow_rls_tables remains accepted as a deprecated no-op.

Reliability And Query Startup

  • Build, vacuum, maintenance rebuild, compaction, repair, and durable sync
    ingestion publish only a fully validated generation. Cancellation before
    publication retains the previous generation and reconciles or removes only
    the recorded unpublished candidate. Persisted low-memory replacement first
    proves that the serving generation is reloadable.

  • The playground fully qualifies Docker Hub base images for Podman, reuses an
    already-satisfied virtual environment without requiring sfw, resolves
    Python shims before venv creation, deduplicates Panama nodes, scopes
    statement_timeout, caches graph initialization, and pins its data-frame
    stack.

  • Query initialization now returns one owned state containing selected-graph
    metadata, registered tables and relationships, filter columns, catalog
    fingerprint and drift status, sync mode, and applicable source relation
    OIDs.

  • Pending-sync and high-watermark checks consume that state through
    caller/graph-bound, cancellation-safe mediators. Automatic pending-sync
    replay also reuses it for log reads, durable ingestion, legacy replay, and
    fingerprint installation instead of loading the registration catalog again.
    Per-statement ACL, schema-drift, freshness, and sync checks remain enabled.

Paths And Compatibility

  • New overloads restrict unweighted and weighted shortest paths by
    edge_types text[]. Existing four-, five-, and six-argument calls retain
    their meaning, including legacy calls with an untyped NULL in the
    max_depth position.
  • The 1.0.0 -> 1.1.0 extension update preserves extension catalogs, source
    rows, function ownership, explicit grants, existing signatures, and result
    shapes. Existing v6 artifacts load without a blanket rebuild.
  • An RLS-active relationship mapping whose artifact lacks a usable durable
    source identity fails closed with SQLSTATE 55000, diagnostic PG023, and a
    rebuild hint. A successful graph.build() repairs that targeted compatibility
    condition.
  • In-place downgrade is not supported. Rollback restores the pre-upgrade
    PostgreSQL backup with the matching 1.0.0 package; installing a 1.0 shared
    library over 1.1 catalogs or artifacts is unsafe and unsupported. After a
    logical restore, reset and re-register the source relations and rebuild the
    derived projection because relation OIDs are database-local.

Performance

  • Query startup reuses one selected-graph/catalog state throughout freshness,
    tenant, filter, hydration, and sync decisions. The fixed-work query-start
    benchmark reduced median traversal setup latency by 21.5% versus the 1.0
    baseline.
  • On the no-RLS path, visibility construction returns before source-row scans
    or graph-sized bitmap allocation. The unrestricted visibility benchmark measured a 1.5%
    median and 3.6% p95 change versus the query-start baseline, inside the 5%/10%
    release budget.
  • Relationship-type filtering added no measurable median regression in the
    recorded fixed-work shortest-path benchmark. These measurements are
    environment-specific evidence, not universal latency guarantees.

Operational Notes

  • A mapped artifact is copied into a private anonymous mapping in each backend.
    Its physical pages are not shared across backends through the OS page cache;
    plan resident memory as artifact size multiplied by concurrent loaded
    backends plus query and maintenance workspace.
  • See Versioning And Compatibility
    for the exact update, rebuild, and backup-restore rollback procedure.

v1.0.0: pgGraph Production Release

Choose a tag to compare

@evokoa-admin evokoa-admin released this 25 Jul 01:43
v1.0.0

v1.0.0 is pgGraph's first production release and supports PostgreSQL 14
through 18. PostgreSQL tables remain the source of truth, and pgGraph's graph
indexes and projections can be validated and rebuilt from them.

Supported Surface

  • The exact SQL function, configuration, diagnostic, and bounded GQL read/write
    profiles are generated and drift-checked. Full ISO GQL, full openCypher, and a
    public SQL/PGQ GRAPH_TABLE surface are not claimed.
  • Named graphs, PostgreSQL-backed mapped writes, durable synchronization,
    resource-governed traversal and analytics, persisted generation recovery,
    maintenance jobs, and operator diagnostics are supported within the public
    limits documentation.
  • Standard PostgreSQL SQLSTATEs are paired with stable PGxxx diagnostics in
    DETAIL. Applications migrating from alpha builds must update any code that
    depended on the earlier nonstandard SQLSTATE mapping.

Alpha Migration And Rebuild

The supported transition from v0.1.8 is source-preserving, not an in-place
catalog or binary upgrade. Back up the database, record graph registrations,
disable writers and schedulers, remove the alpha extension, install 1.0.0,
reapply registration, and rebuild from the PostgreSQL source tables. Before
using DROP EXTENSION graph CASCADE, inventory application objects that depend
on extension functions or types; CASCADE removes those dependents as well as
extension-generated sync objects.

Alpha .pggraph files, projection manifests, and segments are not loaded as a
1.0 compatibility promise. Rebuild them with the 1.0 engine. The 1.0 base
artifact format is v6 and mutable projection metadata is checksummed and
generation-addressed.

Rollback

Do not install an alpha binary over 1.0 catalogs or artifacts. Before cutover,
retain a logical backup plus the matching alpha package and registration
inventory. Rollback restores that backup into a clean database using the alpha
package; source rows are authoritative, and derived graph state is rebuilt.

Security, Resources, And Deprecations

  • Extension and generated trigger security-definer boundaries use a pinned
    pg_catalog, pg_temp search path, preserve caller-role ACL/RLS checks, and
    reject unsafe catalog/source lock combinations before publication.
  • Build, load, query, hydration, synchronization, compaction, and supported
    analytics enforce documented memory, work, row, disk, file, and elapsed-time
    limits. Rejected work does not replace the last validated generation.
  • The alpha graph.oom_action and graph.allow_unsafe_oom_actions settings are
    accepted as read-only compatibility aliases throughout 1.x. They do not
    authorize unsafe allocation behavior and should be removed from new
    configurations.

Benchmark data: ICIJ Offshore Leaks snapshot (2026-07-29)

Choose a tag to compare

ICIJ Offshore Leaks benchmark dataset

This dataset is redistributed solely as a stable, reproducible input for
pgGraph benchmarks and playground examples. This is not a pgGraph software
release.

Source and provenance

  • Publisher: International Consortium of Investigative Journalists (ICIJ)
  • Database: ICIJ Offshore Leaks Database
  • Original download:
    https://offshoreleaks-data.icij.org/offshoreleaks/csv/full-oldb.LATEST.zip
  • Upstream generation marker: GENERATED_ON_20260729.txt
  • Mirrored filename: icij-offshore-leaks-2026-07-29.zip
  • SHA-256:
    34475194b6a8c2d683fddc55cca02f88f08f0a538521fb13a324975221624380
  • Modifications: None. The archive bytes are unchanged; only the filename was
    changed to identify the fixed snapshot.

Attribution and licenses

Data source and attribution: International Consortium of Investigative
Journalists, ICIJ Offshore Leaks Database.

The database is made available under the Open Data Commons Open Database
License 1.0:

https://opendatacommons.org/licenses/odbl/1-0/

The database contents are made available under Creative Commons
Attribution-ShareAlike 3.0 Unported:

https://creativecommons.org/licenses/by-sa/3.0/

The accompanying LICENSE-ODbL-1.0.txt and LICENSE-CC-BY-SA-3.0.txt files
contain the complete license texts.

The pgGraph Apache-2.0 license does not replace or modify the licenses
applicable to this dataset. No endorsement by ICIJ is implied.

Important data disclaimer

A person or entity appearing in the database should not be assumed to have
committed illegal or improper conduct. Names may refer to different people or
entities, identities should be independently verified, and some records may no
longer be current.

See ICIJ's complete disclaimer:

https://offshoreleaks.icij.org/pages/disclaimer

v0.1.8: Named Graphs And Production Release Hardening

Choose a tag to compare

@evokoa-admin evokoa-admin released this 29 Jun 06:51
v0.1.8

v0.1.8: Named Graphs And Production Release Hardening

v0.1.8 adds named graph administration, graph-scoped catalogs, hosted
maintenance jobs, relationship creation, and stricter query-surface boundaries.
pgGraph can now keep multiple registered graph definitions in the same
extension schema, apply graph-specific grants and quotas, scope builds and sync
replay to the selected graph, and expose enough runtime state for operators to
load, unload, inspect, and maintain those graphs without falling back to raw
catalog writes.

This release also expands the mutable GQL write surface with registered
relationship creation and row hydration, while keeping PostgreSQL source tables
authoritative for graph mutations. Capability checks for openCypher and
SQL/PGQ are now explicit, so unsupported syntax is rejected with clearer
compatibility guidance instead of drifting into partial behavior.

The final release candidate hardens restricted-role SQL behavior, refreshes the
Rust and pgrx release toolchain, and documents the full release handoff from
gate evidence through signed tags and package publishing.

Highlights

  • Added a durable named-graph catalog with graph creation, selection,
    description, residency, grants, quotas, and metadata inspection APIs.
  • Scoped node registrations, relationship registrations, filter columns, build
    jobs, maintenance jobs, sync policies, and sync replay by graph identity.
  • Added runtime graph loading and unloading controls so operators can manage
    selected graphs and inspect active runtime state.
  • Added graph grants and quota policy enforcement for visibility, build,
    sync, mutation, and administration paths.
  • Added hosted sync-policy jobs, hosted due-job runners, and an internal due
    job worker so scheduled maintenance can run through graph-scoped job state.
  • Added graph-aware discovery and direct identity lookups for registered
    labels and relationships.
  • Added GQL CREATE support for registered relationships, including source-row
    inserts, transaction-local visibility, and hydrated relationship rows in
    query results.
  • Added graph-scoped projection and sync behavior so replay, dirty-range
    ingest, copy-on-write compaction, and runtime selection ignore unrelated
    graph state.
  • Added explicit openCypher and SQL/PGQ capability boundaries with clearer
    unsupported-feature reporting and compatibility corpus coverage.
  • Hardened named-graph catalog access so internal graph catalogs are mediated
    through SQL APIs and caller-role visibility checks.
  • Hardened restricted-role graph access so selected-graph metadata, sync status,
    and runtime state can be resolved through controlled definer boundaries while
    preserving caller-role graph grants and PostgreSQL source-table ACL/RLS
    checks.
  • Refreshed the release toolchain to Rust 1.96 and pgrx 0.19.1, with matching
    Docker, Nix, Cargo, installation, and PGXN source-build documentation.
  • Added a contributor release-gate checklist that records required gates,
    environment prerequisites, opt-in gates, evidence capture, signed tagging,
    package validation, and prepare/publish ordering.

Named Graph Administration

Named graphs move pgGraph beyond one implicit default graph. Operators can
create graph definitions, select the active graph for a role, list graph
metadata, configure residency, grant graph-level capabilities, and set build or
storage quotas. Registration APIs now attach tables, relationships, filter
columns, sync policies, and build state to a graph ID, while existing default
graph behavior remains available for simple installs.

The graph-scoped catalog layer also changes runtime behavior. Build operations,
auto-discovery, traversal, GQL queries, sync replay, projection ingest, and
maintenance jobs now resolve the caller's selected graph and reject access when
the role lacks the required graph privilege. Runtime status APIs report graph
identity and residency state so loaded graph engines are no longer treated as a
single global slot.

Hosted Maintenance And Sync

v0.1.8 adds graph-scoped job tables and scheduler entry points for hosted
maintenance. Sync policies can create due jobs, due-job runners can claim and
execute graph work, and Docker installs continue to schedule
graph.run_scheduled_maintenance() through pg_cron. The same job model can
be used by external schedulers in non-Docker deployments.

Build jobs and maintenance jobs now include graph identity, advisory-lock
coverage was updated for graph-scoped work, and sync replay ignores source
changes that belong to other registered graphs. Projection maintenance paths
also preserve graph scope when ingesting dirty ranges or compacting
copy-on-write state.

GQL And Compatibility

The GQL mutable write path can now create registered relationships. Relationship
creation resolves mapped endpoint rows, inserts through PostgreSQL DML, exposes
transaction-local changes to subsequent graph reads, and returns hydrated
relationship records. Direct identity lookups support the new row hydration
paths without making graph artifacts a second source of truth.

The release also makes compatibility boundaries more explicit. The openCypher
preview accepts only the subset that maps cleanly to pgGraph's GQL IR, and the
SQL/PGQ adapter documents supported typed-hook behavior separately from
PostgreSQL's future SQL parser integration. Unsupported features now fail with
clearer errors and capability metadata.

Compatibility

The named-graph catalog adds new extension-owned tables and changes the shape
of several internal administration paths. Existing single-graph installs should
continue to use the default graph, but development databases created from older
alpha catalog layouts should be recreated before testing this release.

Source tables remain the source of truth. Graph artifacts, projection segments,
sync state, and runtime engines are still derived from PostgreSQL tables and
graph registration metadata.

v0.1.8 raises the source-build baseline to Rust 1.96 and pgrx 0.19.1.
PostgreSQL 14 through 18 remain the supported PostgreSQL majors, with
PostgreSQL 17 as the default release-gate target.

Release Validation

The production release candidate completed the full PostgreSQL 17 release gate,
including docs drift, dependency freshness remediation, formatting, clippy,
Rust docs and doctests, unit tests, pgrx SQL tests, cargo-deny, fuzz compile,
projection seed corpora, package validation, fresh install smoke,
SQL metadata audit, SQLSTATE/ACL boundary tests, backup/restore,
lock-regression gates, concurrency stress, synthetic release fixture,
Docker/playground validation, pgbench sync stress, GQL write lifecycle gates,
named-graph heavy gates, cross-backend durable projection checks, projection
recovery, transaction-delta lifecycle, and write predicate re-check races.

The playground release gate now treats nondeterministic demo sample hashes as
row-count assertions while retaining stable checksums for deterministic results.
This keeps the gate focused on product regressions instead of component-id or
sample-order drift across fresh builds.

v0.1.7: Durable Projection Operations

Choose a tag to compare

@evokoa-admin evokoa-admin released this 08 Jun 18:32

v0.1.7: Durable Projection Operations

v0.1.7 adds the durable projection operation layer for mutable graphs. pgGraph
can now publish committed source-table changes into durable projection
segments, read those segments alongside the base CSR graph, compact accumulated
segment state, repair dirty base chunks, garbage-collect obsolete generations,
and surface operator diagnostics through SQL functions.

This release also stabilizes how GQL returns relationship values for
bidirectional edges. Bidirectional edges can still be traversed from either
endpoint, but relationship records now keep the source and target endpoint
order registered in the graph schema. That makes edge records consistent for
applications that render graph edges or inspect _start, _end, path values,
or relationships(path).

Highlights

  • Added manifest-backed layered reads that merge the base CSR graph, durable
    projection segments, replacement base chunks, committed overlay rows, and
    transaction-local deltas into one traversal view.
  • Routed traversal, shortest path, weighted shortest path, connected
    components, and GQL relationship expansion through the layered projection
    runtime when a graph is built with durable projection state.
  • Published committed mutable-overlay changes as durable segments, so fresh
    backends can observe committed graph writes without requiring a full
    graph.build() rebuild.
  • Added durable segment compaction, including preservation of weighted
    relationship state and rewrite support for dirty base chunks.
  • Added generation heartbeats and generation-aware garbage collection so
    obsolete projection files are removed only after retained valid generations
    and active backends no longer protect them.
  • Added projection recovery and repair support, including targeted base-chunk
    repair and rollback-safe full rebuild restoration.
  • Added operator-facing diagnostics through graph.projection_status(),
    graph.projection_gc(), graph.projection_repair(), and
    graph.active_generation_count(), with additional durable-projection
    recommendations exposed through graph.sync_health().
  • Preserved registered source and target endpoints in GQL relationship values
    even when a bidirectional edge is matched through its reverse traversal path.
  • Updated release automation and verification for native multi-platform Docker
    builds, package prepare/publish separation, projection fuzz seed corpora,
    crash recovery gates, Docker smoke checks, and release benchmark contracts.

Durable Projection Behavior

Durable projections let pgGraph keep PostgreSQL source tables authoritative
while avoiding a full graph rebuild for every committed mutable change. When
durable projection mode is active, committed sync rows can be ingested into
projection segment files. Readers then combine those segment files with the
base graph and any transaction-local overlay state at query time.

The layered runtime is used across the graph surfaces that need topology reads:

  • traversal APIs
  • unweighted shortest path
  • weighted shortest path
  • connected components
  • GQL relationship expansion
  • query-time catch-up for mutable graph writes

Projection maintenance is now represented as explicit operations. Segment
ingestion records committed changes, compaction bounds segment fanout, dirty
base chunk rewrite repairs source-node ranges, recovery validates and restores
projection generations, and GC removes obsolete files only after retention and
active-generation checks pass.

New SQL Operations And Diagnostics

v0.1.7 adds and documents durable projection administration entry points:

  • graph.projection_status() reports manifest, segment, chunk, heartbeat,
    validation, operation timestamp, and recommendation diagnostics.
  • graph.projection_gc() runs generation-aware cleanup for obsolete projection
    files.
  • graph.projection_repair() validates projection state and repairs targeted
    chunk damage or restores a valid full rebuild when needed.
  • graph.active_generation_count() exposes how many active projection
    generations are protected by backend heartbeats.
  • graph.sync_health() includes metadata-only durable projection
    recommendations without changing the core source-table sync model.

The release also adds graph.projection_retention_generations so operators can
control how many valid projection generations are retained before GC can remove
obsolete files.

GQL Relationship Behavior

Before v0.1.7, a bidirectional edge matched through its reverse traversal
path could be returned with endpoints ordered according to the path pattern.
For example, if a relationship was registered from account_a to account_b,
a reverse traversal from account_b back to account_a could expose the
relationship value as though its start and end were reversed.

Starting in v0.1.7, traversal direction and relationship identity are kept
separate:

  • Path matching still honors bidirectional traversal.
  • Relationship values preserve the registered schema direction.
  • Path values preserve the matched node order for the path, while embedded
    relationship records preserve the registered relationship direction.
  • relationships(path) returns relationship records with stable endpoint
    orientation, even when a relationship was traversed in reverse.

The fix is applied through edge storage, persisted graph artifacts, projection
segments, transaction overlays, compaction, dirty chunk rewrite, and GQL
materialization so schema-direction relationship values stay stable across the
new durable projection paths.

Release And Packaging

The release process was hardened alongside the projection work:

  • Package publishing now separates prepare and publish modes.
  • Docker release builds run natively per platform and then merge per-platform
    digests into the prepared multi-arch tags.
  • Docker extension verification waits briefly before failing and prints
    container logs on failure.
  • GHCR image naming is normalized to lowercase.
  • The local release gate now uses the same pg17 development feature set as
    the maintained pgrx evidence command.
  • Projection manifest and segment fuzz seed corpora can be run outside a live
    PostgreSQL backend through the release-gate script.
  • Documentation now includes the Homebrew install path and expanded durable
    projection operation notes.

Compatibility

Queries that only check reachability, filter by labels or properties, or return
node values should behave the same as before. Queries that inspect relationship
endpoint fields, compare path relationship values, or render directed edge
arrows from relationships(path) may observe changed output for reverse
matches on bidirectional relationships. The new output is the registered schema
direction, not the reverse path-pattern direction.

The persisted artifact formats changed for this release. Graph artifacts now
use graph format v3, and projection segments now use segment format v2, so the
schema-direction metadata can be loaded safely. Existing source tables and graph
registrations do not need to be rewritten.

Upgrade Note

`.pggraph` artifacts written before `v0.1.7` must be regenerated with `SELECT graph.build();` after upgrading. These files are derived artifacts, not the source of truth; PostgreSQL source tables remain authoritative.

Regenerating the derived artifact is the intended upgrade path:

SELECT graph.build();

Validation

The PostgreSQL 17 release gate passed for this release, including fmt, clippy,
documentation checks, unit tests, pgrx SQL tests, package validation, install
smoke, metadata audit, SQLSTATE/ACL boundary tests, backup/restore,
advisory-lock regression coverage, concurrency stress, projection recovery,
cross-backend durable projection checks, projection fuzz seed corpora,
playground query validation, pgbench sync stress, Docker smoke, RSS
measurement, and disposable crash recovery checks.

The release also added benchmark and contract coverage for layered BFS, GQL
relationship expansion, weighted paths, ingest publication, compaction, GC, and
repair, and was checked against the public package metadata and documentation
references for the v0.1.7 tag.

v0.1.6: Release Readiness Hardening

Choose a tag to compare

@evokoa-admin evokoa-admin released this 07 Jun 04:00

v0.1.6: Release Readiness Hardening

v0.1.6 is a release-readiness hardening update for the GQL mutable projection
stack. It clears the final pg17 release gate after the dependency refresh,
clippy cleanup, transaction-delta rollback fixes, and persisted metadata
serialization migration.

Highlights

  • Moved persisted .pggraph metadata sections from bincode 1.3.3 to
    bincode 2.0.1 with serde support.
  • Kept the .pggraph artifact format at version 2 and made metadata decoding
    reject trailing bytes instead of accepting partially consumed payloads.
  • Skipped the published bincode 3.0.0 crate in dependency freshness checks
    because that release contains a top-level compile error.
  • Fixed dirty transaction overlays so pending trigger sync rows are not applied
    into backend-local base projection state while transaction-local deltas are
    still uncommitted.
  • Tightened the build-lock regression fixture so the concurrent slow-build path
    uses manual sync mode and does not trip trigger-sync behavior unrelated to
    the advisory-lock check.
  • Cleared clippy blockers in GQL wildcard expansion, join binding, path-variable
    binding, and SQL admin single-row handling without broad lint suppressions.
  • Documented the deferred nixpkgs and rust-overlay lock refresh as a
    Nix-environment follow-up rather than a release blocker.

Upgrade Note

`.pggraph` artifacts written before `v0.1.6` must be regenerated with `SELECT graph.build();` after upgrading. These files are derived artifacts, not the source of truth; PostgreSQL source tables remain authoritative.

This release intentionally chooses regeneration over compatibility shims for
old bincode metadata payloads. Future artifact tooling should move variable
metadata sections toward a pgGraph-owned binary encoding so artifact
compatibility is no longer tied to serializer crate behavior.

Validation

The full post-bincode pg17 release gate passed:

PG_VERSION_FEATURE=pg17 ./tests/heavy/run_release_gate.sh

That gate includes fmt, clippy, docs, unit tests, pgrx SQL tests, cargo-deny,
fuzz binary checks, package validation, fresh install smoke, metadata audit,
SQLSTATE/ACL boundary tests, backup/restore, advisory-lock regressions,
concurrency, synthetic smoke, rebuilt playground fixtures, pgbench sync stress,
and GQL transaction lifecycle and race scripts.

v0.1.5: GQL Mutable Projection Stabilization

Choose a tag to compare

@evokoa-admin evokoa-admin released this 01 Jun 16:45

v0.1.5: GQL Mutable Projection Stabilization

v0.1.5 introduces pgGraph's GQL surface and the mutable projection path that
lets mapped GQL writes update PostgreSQL source rows while keeping the in-memory
graph view transactionally consistent. This release turns GQL from an internal
planning target into a documented SQL entry point, adds node and relationship
mutability through the overlay engine, and keeps the v0.1.4 installation and
SQL function surface compatible.

Highlights

  • Added graph.gql() as the primary standards-oriented graph query surface for
    pgGraph, with graph.gql_explain() for stable plan inspection.
  • Added mutable GQL support for mapped source tables, including CREATE,
    MERGE, SET, REMOVE, relationship DELETE, and DETACH DELETE paths
    backed by PostgreSQL row changes and transaction-local projection deltas.
  • Preserved PostgreSQL as the source of truth for mutable graph data: GQL writes
    honor table mappings, ACL/RLS checks, tenant scope, rollback behavior, and
    overlay limits.
  • Added transaction lifecycle coverage for GQL create, set/remove, delete, and
    merge race paths in the release gate.
  • Made trigger sync the default sync mode, so a normal graph.build() installs
    source-table sync triggers and topology reads catch up to pending rows by
    default unless operators opt into graph.sync_mode = 'manual'.
  • Upgrade note: deployments that relied on implicit manual refresh should set
    graph.sync_mode = 'manual' before running graph.build(). When trigger
    mode is active, graph.build() emits a warning that sync triggers were
    installed on registered source tables.
  • Fixed mapped dynamic-label edge deletes so rows with NULL or blank
    label_column values fall back to the registered relationship label.
  • Preserved transaction-local nodes for non-tenanted tables even when a session
    tenant scope is active, while still hiding unscoped writes for tenanted tables.
  • Fixed optional aggregate semantics so collect, count(expr), sum, avg,
    min, and max ignore JSON null values while count(*) still counts
    every input row.
  • Cancelled net-neutral transaction edge deltas before overlay-cap accounting,
    avoiding false overlay-limit failures for insert/delete pairs that leave no
    pending edge.
  • Normalized GQL path function names case-insensitively for nodes(path),
    relationships(path), and length(path).
  • Returned typed GQL errors for value-projection invariants instead of relying
    on internal panics.
  • Decoupled variable-length path cardinality from whether the query returns a
    path value, and preserved explicit *1..1 path-distinct matches.
  • Stabilized graph.gql_explain() output around registered table labels and
    fixed catalog reads of regclass fields so explain fixtures no longer drift
    with table OIDs.
  • Updated the playground release gate to rebuild the Docker image and recreate
    the playground container during the full release gate, preventing stale
    extension binaries from passing or failing the fixture suite.

Testing

  • Added regression coverage for dynamic-label delete fallback values,
    non-tenanted transaction-local node visibility under tenant scope, explicit
    single-hop variable-length path cardinality, catalog-backed explain labels,
    and playground release-gate freshness.
  • Spawned a second-opinion Rust review subagent for the GQL/projection changes;
    all findings from that pass were fixed.

Validation

The full pg17 release gate passed, including fmt, clippy, docs, unit tests,
pgrx SQL tests, cargo-deny, fuzz binary checks, package validation, fresh
install smoke, metadata audit, SQLSTATE/ACL boundary tests, backup/restore,
advisory-lock regressions, concurrency, synthetic smoke, rebuilt playground
fixtures, pgbench sync stress, and GQL transaction lifecycle scripts:

PG_VERSION_FEATURE=pg17 ./tests/heavy/run_release_gate.sh

v0.1.4: PGXN Distribution

Choose a tag to compare

@evokoa-admin evokoa-admin released this 30 May 15:04

v0.1.4: PGXN Distribution

v0.1.4 adds PGXN distribution metadata and a top-level Makefile for
source-based installation via PGXN. Existing v0.1.3 users should not
need to change their SQL or application code.

Highlights

  • Added PGXN META.json distribution metadata at the repository root.
  • Added a PGXN-compatible top-level Makefile that delegates to cargo pgrx.
  • Added PGXN and manual source installation documentation to README.md,
    README_zh.md, and the user guide.
  • Documented PG_CONFIG targeting and missing PostgreSQL header
    troubleshooting for source installs.
  • Prepared pgGraph for source-based PGXN release.

Validation

Run the PGXN metadata validation (cargo install pgxn_meta --locked):

pgxn_meta

Run the PGXN-style build flow:

make
make installcheck

v0.1.3: Structured Filters And Architecture Clarity

Choose a tag to compare

@damienhehe damienhehe released this 28 May 01:43

v0.1.3: Structured Filters And Architecture Clarity

v0.1.3 adds structured traversal filter helpers, removes the legacy raw-filter
parser, refactors internal filter and sync state, tightens engine encapsulation,
and documents pgGraph's architecture tradeoffs. It keeps the v0.1.2 SQL
contract and adds no breaking changes.

Highlights

  • Added six structured traversal filter helpers for membership, text, and null
    predicates: graph.in(), graph.not_in(), graph.contains_text(),
    graph.prefix_text(), graph.is_null(), and graph.is_not_null().
  • Removed the legacy raw-filter parser from all paths including development,
    tests, and fuzzing; structured JSONB filters are now the only supported
    traversal filter boundary.
  • Refactored FilterOp into a FilterOp { column_idx, condition } struct with
    a separate FilterCondition enum so column targets and predicate conditions
    are represented independently.
  • Encapsulated sync row replay behind a typed SyncRowOperation helper so node
    insert, update, delete, and truncate are resolved once and applied in order.
  • Routed mmap-backed node mutations through engine helpers that materialize
    borrowed arrays before in-place mutation.
  • Narrowed all Engine store, sync, resolution, mmap, and status fields from
    pub to pub(crate), establishing the engine as a crate-internal boundary.
  • Added a new architecture tradeoffs documentation page covering pgGraph's
    design philosophy, read-only mmap positioning, and SQL/PGQ relationship.

New Features

  • graph.in(column, values) — membership filter accepting a JSONB array of
    values. Typed pushdown covers u32, i64, bool, text token, and UUID
    columns.
  • graph.not_in(column, values) — negative membership filter with the same
    typed pushdown coverage.
  • graph.contains_text(column, value) — substring filter for dictionary-encoded
    text columns. Pushed down against the text dictionary at traversal time.
  • graph.prefix_text(column, value) — prefix filter for dictionary-encoded text
    columns.
  • graph.is_null(column) — explicit NULL check filter. Also works through the
    existing eq operator with a NULL value, but provides clearer intent.
  • graph.is_not_null(column) — explicit NOT NULL check filter.

All six helpers produce the same structured JSONB format consumed by
graph.traverse(filter := ...), graph.all(), and graph.any().

Internal Changes

  • Filter pushdown refactor: FilterOp is now a struct holding column_idx
    and a FilterCondition enum. All existing pushdown variants (Eq, Neq,
    Gt, Between, EqI64, EqBool, EqToken, EqUuid, IsNull, etc.)
    moved into FilterCondition, with new membership (In, NotIn, InI64,
    NotInI64, InBool, NotInBool, InToken, NotInToken, InUuid,
    NotInUuid) and text (ContainsToken, PrefixToken) variants added.
  • Hydration filter operators: HydrationFilterOperator gained In,
    NotIn, Contains, Prefix, IsNull, and IsNotNull variants for
    source-row recheck of filters that cannot be pushed down.
  • Structured filter validation: validate_structured_operator_shape() now
    runs unconditionally for all filters, not only for columns with a resolved
    column type. Added validation for contains/prefix (must be text),
    in/not_in (must be array), and is_null/is_not_null (must be null or
    true).
  • Legacy raw-filter removal: Deleted the parse_condition fuzz target
    and its Cargo.toml entry. Removed the development-only raw-filter parser
    and associated unit tests from filter_index.rs.
  • Sync row replay: Introduced SyncRowOperation enum with Insert,
    Update, Delete, and Truncate variants. Each sync log entry is parsed
    into a typed operation before the engine applies ordered node mutations, edge
    overlays, tenant updates, and filter index refreshes.
  • Engine encapsulation: All Engine fields (node_store, edge_store,
    reverse_edge_store, filter_index, edge_type_registry, built,
    sync_status, resolution_store, resolution_delta, edge_buffer,
    is_read_only, read_only_reason, applied_sync_id, needs_vacuum,
    needs_rebuild, schema_state, table_membership, tenant_membership,
    tenanted_table_oids, etc.) changed from pub to pub(crate). Helper
    structs ResolutionStore, MmapResolutionState, and EdgeMutation fields
    also narrowed to pub(crate).
  • Resolution index tests: Added resolve() coverage for ResolutionIndexBuilder
    and len() coverage for ResolutionDeltaIndex.
  • Test helper fix: Restored ensure_current_graph visibility for
    pg_test so pgrx SQL integration tests continue to compile after the
    facade module refactor.

Documentation

  • Added docs/contributor_guide/architecture-tradeoffs.mdx documenting pgGraph's
    design philosophy, mmap tradeoffs, and SQL/PGQ positioning. Linked from the
    docs overview, contributor guide, and quick-links navigation.
  • Clarified mmap as read-only derived artifact mapping across build-and-persistence,
    limitations-and-fit, roadmap, memory-model, and index docs. Added
    callouts explaining that .pggraph files are not PostgreSQL buffer-pool
    replacements.
  • Updated querying.mdx with structured filter examples using graph.in(),
    graph.is_not_null(), and related helpers. Added search index guidance for
    case-insensitive and trigram queries.
  • Updated schema-registration.mdx with auto-discovery text property boundaries,
    manual registration examples, and filter-column registration guidance.
  • Updated api-reference.mdx with the new filter helper function entries.
  • Updated configuration.mdx with GUC enum compatibility policy for typed
    string settings with aliases.
  • Updated quickstart.mdx with quickstart mode documentation.
  • Updated known-issues.mdx: added 13 closed items under P1/P2/P3 and removed
    all previously tracked P2 rows (auto-discovery text, structured filter
    operators, legacy raw filters, case-insensitive search, GUC enum behavior)
    now that structured filters cover text, membership, range, null, and prefix
    semantics. Consolidated P3 internals to a single remaining pgrx test layout
    item.
  • Updated roadmap.mdx to reflect cleared P2 and P3 backlogs and added SQL/PGQ
    comparison note under benchmark plans for PostgreSQL 19.
  • Updated README.md and README_zh.md with version 0.1.3 badges and
    refreshed project descriptions.

Validation

Focused validation for this branch included local documentation reference checks
(scripts/check_doc_references.py), targeted Rust unit tests
(cargo test --features pg17), clippy gate
(cargo clippy --features pg17 --lib -- -D warnings), and pgrx pg_test compile
checks (cargo test --features pg17,pg_test --lib --no-run).

Run the full release gate before publishing binary packages for v0.1.3:

PG_VERSION_FEATURE=pg17 ./tests/heavy/run_release_gate.sh

Commit Coverage

This release covers 14 commits on the alpha-hardening-critical-paths
branch, from f88d9cb (fix: restore pg facade test helpers) through f3c5cd0
(build: bump version to 0.1.3).

v0.1.2 Release

Choose a tag to compare

@evokoa-admin evokoa-admin released this 25 May 13:52

v0.1.2: Release Prep Hardening

This release captures the higher-priority alpha hardening work completed after
v0.1.1, updates public version markers, and records the current release-gate
evidence for the pg17 target.

Fixes

  • Development-only background job test runners now mark failed build and
    maintenance jobs with the same durable failure helpers used by real background
    workers. This keeps advisory-lock regression gates aligned with worker
    behavior and verifies that failed job rows do not remain stuck in running.
  • Source-row search recheck work now prepares Rust match state once per query
    and table display labels once per source-table statement.
  • Aggregation hydration now rekeys all-path hydration rows by table and reuses
    borrowed parent-path rows instead of cloning every candidate row into lookup
    maps.
  • Traversal result metadata stays dense for normal high-coverage traversals and
    switches to sparse parent/depth maps only for low-visit-budget traversals on
    large graphs.

Performance Notes

  • Source search warmed benchmark improved from 0.14s before the hardening pass
    to 0.08s after the recheck refactor.
  • Aggregation hydration improved from 8.33s before the hardening pass to 6.32s
    after the hydration lookup refactor.
  • Dense-path traversal internals improved from 0.37s before the hardening pass
    to 0.11s after the traversal metadata refactor.
  • Sparse traversal metadata is used only for low-visit-budget traversals on
    large graphs; normal and high-coverage traversals stay dense to avoid slowing
    path reconstruction.

Release Gates

The pg17 heavy release gate passed through fmt, clippy, docs, unit tests, pgrx
SQL tests, cargo-deny, fuzz check, package validation, fresh install smoke,
metadata audit, SQLSTATE/ACL boundary tests, backup/restore, lock regressions,
concurrency, synthetic release smoke, and pgbench sync stress:

PG_VERSION_FEATURE=pg17 DB_PREFIX=pggraph_release_prep3 RUN_PLAYGROUND=0 ./tests/heavy/run_release_gate.sh

The synthetic smoke portion produced nodes=50000, edges=150889,
build_ms=1775, query_ms=43, and wrote
/opt/homebrew/var/postgresql@17/graph/main.pggraph.

The pgbench sync stress portion passed with zero failed transactions. Observed
evidence: 3045 transactions, 0.000% failures, average latency 3.739 ms,
101.508310 TPS, sync_log_rows=3045, rows_applied=3045, apply_ms=27,
query_ms=10, and search_rows=0.

After Docker was made available, the Docker-backed playground gate passed and
validated all 26 Streamlit playground query examples against the prepared
Panama dataset:

PGGRAPH_PLAYGROUND_YES=1 PG_VERSION_FEATURE=pg17 ./tests/heavy/playground_release_gate.sh

The sandbox Panama benchmark gate also passed:

./sandbox/run_benchmarks.sh panama --yes

Observed sandbox evidence: 2016523 source nodes, 5802586 graph edges,
load_seconds=63.204512249998515, build_seconds=60.01402675001009,
build_time_ms=35384.969724, memory_used_mb=185.5018720626831, and
memory_limit_mb=2048. Hot median query timings were 29.064 ms for status,
83.2705 ms for entity search, 107.39 ms for depth-2 traversal, 3.1295 ms
for shortest path, 147.9435 ms for component stats, and 572.17 ms for
largest component.

The focused background job advisory-lock regression gate was rerun after the
development test-runner fix and passed:

PG_VERSION_FEATURE=pg17 DBNAME=pggraph_release_prep_background_lock ./tests/heavy/background_job_lock_regression.sh