Catalog System Architecture in pgrust: A Three-Layer Rust Implementation of PostgreSQL System Tables

The pgrust catalog system replicates PostgreSQL's internal system tables through a modular three-layer architecture that combines compile-time generated Rust structs, MVCC-consistent snapshot management, and seam-based APIs for extension integration.

The catalog system architecture in pgrust serves as the backbone for type resolution, function dispatch, and schema metadata management in this Rust-based PostgreSQL implementation. Developed in the malisper/pgrust repository, the system translates PostgreSQL's C header definitions into idiomatic Rust while preserving full compatibility with upstream OID conventions and system table layouts.

Catalog Definition Layer: Static System Table Representations

At the foundation of the architecture lies the catalog definition layer, which declares Rust equivalents of PostgreSQL's system catalogs including pg_type, pg_proc, and pg_class. These definitions mirror the C structs and constants found in PostgreSQL's catalog/pg_*.h header files, providing type-safe access to built-in OIDs and catalog schemas.

Core Catalog Files

The primary definitions reside in the types_core crate under the _support directory:

These files are generated from PostgreSQL header files, ensuring that OIDs and catalog layouts remain synchronized with upstream PostgreSQL versions.

Syscache and Snapshot Seams: Dynamic Catalog Access

The second layer provides runtime catalog visibility through snapshot management and seam interfaces. Unlike the static definitions, this layer handles MVCC-consistent views of the catalog during query execution, managing cache invalidation and snapshot lifecycles.

MVCC Snapshot Management

The snapshot manager, implemented in crates/backend/utils/time/snapmgr_seams/src/lib.rs, provides functions for obtaining catalog snapshots:

  • get_catalog_snapshot() – Returns an MVCC-consistent view of the catalog for the current transaction
  • invalidate_catalog_snapshot() – Clears cached snapshots after schema modifications

Catalog-Driven Utility Seams

Additional seam modules provide catalog-aware functionality throughout the backend:

These seams abstract whether the catalog data resides in memory caches, on-disk structures, or temporary snapshot buffers, presenting a uniform API to upper layers.

Execution and Extension Integration

The third layer enables extension integration and runtime catalog consumption. Extensions like pgcrypto and pg_trgm use the seam APIs to register custom catalog objects while leveraging the same infrastructure as built-in types.

Extension Registration Points

Extension modules demonstrate practical catalog usage:

Working with the Catalog System

Working with the catalog system involves combining static OID constants with dynamic snapshot acquisition. The following example demonstrates resolving type and function OIDs with proper snapshot management:

use pgrust::types_core::catalog::{pg_type, pg_proc};
use pgrust::backend::utils::time::snapmgr_seams::{get_catalog_snapshot, invalidate_catalog_snapshot};

fn resolve_catalog_objects() -> Result<(), Box<dyn std::error::Error>> {
    // Obtain a fresh catalog snapshot (MVCC-consistent)
    let snap = get_catalog_snapshot(0)?; // 0 = InvalidRelationId = whole-catalog view

    // Resolve a built-in type OID using static constants
    let int_oid = pg_type::INT4_OID;
    println!("OID for int4 = {}", int_oid);

    // Resolve a function OID (e.g., length(text))
    let len_oid = pg_proc::PG_PROC_OID.get("length")?;
    println!("OID for length(text) = {}", len_oid);

    // After schema changes, invalidate the snapshot so the next call sees the new catalog
    invalidate_catalog_snapshot();

    Ok(())
}

This pattern ensures that catalog lookups respect transaction isolation levels while providing the performance benefits of syscache lookups.

Summary

  • Three-layer architecture separates static definitions (mirror PostgreSQL headers), dynamic snapshots (MVCC consistency), and consumption APIs (seam interfaces)
  • Type-safe catalog definitions in crates/_support/types/types_core/src/catalog/ prevent OID mismatches through compile-time generated Rust code
  • Snapshot management via snapmgr_seams provides MVCC-consistent catalog views without exposing underlying storage implementation details
  • Extension integration allows contrib modules like pgcrypto to register catalog objects using the same APIs as core system components
  • Seam-based design abstracts catalog storage, enabling optimizations like in-memory syscaching without changing consumer code

Frequently Asked Questions

How does pgrust maintain compatibility with PostgreSQL's catalog OID assignments?

pgrust generates Rust catalog definitions directly from PostgreSQL's catalog/pg_*.h header files, ensuring that built-in type OIDs (like INT4_OID in pg_type.rs) and function OIDs match the upstream C constants exactly. This compile-time generation prevents drift between the Rust implementation and PostgreSQL's system catalogs.

What is the difference between catalog definitions and snapshot seams in pgrust?

Catalog definitions (in types_core) provide compile-time constants and struct layouts for system tables, while snapshot seams (in snapmgr_seams) provide runtime MVCC-consistent views of these catalogs during query execution. The definitions are static metadata; the seams manage dynamic visibility and cache invalidation.

Where are extension-specific catalog objects registered in pgrust?

Extension modules register catalog objects in their respective src/lib.rs files within the crates/contrib/ directory. For example, crates/contrib/pgcrypto/src/lib.rs inserts cryptographic function entries into the pg_proc catalog through the seam API, while pg_trgm registers GiST opclass information in trgm_gist.rs.

How does the catalog snapshot system handle schema changes during transactions?

The snapshot manager in crates/backend/utils/time/snapmgr_seams/src/lib.rs tracks catalog modifications and provides invalidate_catalog_snapshot() to clear stale caches. When DDL statements modify system tables, calling this function ensures subsequent catalog lookups see the updated schema while maintaining MVCC consistency for existing snapshots.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →