# v0.32.0 — Citus: Stable Naming & Per-Source Frontier Foundation

> **Full technical details:** [v0.32.0.md-full.md](v0.32.0.md-full.md)

**Status: Planned** | **Scope: Medium**

> The first of two releases that bring world-class Citus support to
> pg_trickle. v0.32.0 lays the additive foundation — stable object naming,
> Citus detection helpers, and per-source frontier correctness — with zero
> behaviour change on single-node deployments.

---

## What is this?

pg_trickle currently names every internal object (change buffers, trigger
functions, index names, WAL slot names, frontier keys) after the PostgreSQL
OID of the source table. An OID is a local, database-specific integer that
is different on every node in a Citus cluster and changes after a
`pg_dump` / restore cycle. This works fine for single-node PostgreSQL but
is the root cause of every Citus incompatibility.

v0.32.0 replaces OID-keyed names with a **stable hash** derived from the
schema-qualified table name — identical on every node, survives restores,
and survives OID reassignment after a major upgrade. At the same time it
ships a new `src/citus.rs` module with Citus detection helpers that allow
the extension to make intelligent decisions about source placement in v0.35.0.

---

## Stable naming

Instead of `changes_12345`, `pg_trickle_cdc_fn_12345`, and
`slot_pgtrickle_12345`, objects are now named using a short hex string
derived from `stable_hash("myschema.my_table")`:

```
changes_a3f7b2c1
pg_trickle_cdc_fn_a3f7b2c1
slot_pgtrickle_a3f7b2c1
```

This name is computed once at `create_stream_table()` time, stored in the
catalog, and used for all subsequent object creation. Existing installations
are upgraded automatically — the SQL migration script renames all existing
objects in a single transaction with no downtime.

The change is invisible to end users: no SQL API changes, no configuration
changes, no behaviour changes on a single-node deployment.

---

## Citus detection

A new internal module learns to ask "is Citus loaded on this database?" and
"how is this table distributed?". The answers — local, reference, or
distributed — are stored alongside the stable name in the catalog and drive
the CDC and apply strategies in v0.35.0.

---

## Per-source frontier correctness

pg_trickle tracks a *frontier* for each source table — the point up to which
changes have been consumed and applied. Today the frontier is keyed by the
table OID, creating an implicit assumption that all sources share a single
WAL namespace. v0.32.0 rekeys the frontier by stable name and audits all
code paths that compare or merge frontier values across sources, removing
the assumption of a single node's WAL.

This fixes a latent correctness issue for any multi-source stream table
where the two sources have wildly different write rates, and it is a
prerequisite for tracking per-worker WAL positions in v0.35.0.

---

## Who benefits?

- **All users** — stable naming survives `pg_dump` / restore, major
  upgrades, and OID reassignment. The frontier fix improves correctness for
  multi-source stream tables.
- **Citus users** — v0.32.0 is the prerequisite for v0.35.0. Without stable
  naming, per-worker slots cannot be named consistently across the cluster.

---

## Scope

v0.32.0 is a medium-sized release. The naming refactor touches many files
(`src/cdc.rs`, `src/wal_decoder.rs`, `src/dvm/diff.rs`,
`src/refresh/codegen.rs`) but is purely additive: old behaviour is
preserved in full, and the SQL migration handles existing installations
automatically.

---

*Previous: [v0.31.0 — Performance & Scheduler Intelligence](v0.31.0.md)*
*Next: [v0.33.0 — Reactive Subscriptions & Zero-Downtime Operations](v0.33.0.md)*
