rent
Learn by example

23. PostgreSQL superpowers

Request extensions beside application models in the central RSL schema:

extension pgmq {
  name = "pgmq"
}

extension vector {
  name    = "vector"
  version = "0.8.1"
  schema  = "extensions"
}

rent migrate diff includes those requests in the desired catalog. Runtime use then begins with explicit typed registration. The returned token gates every extension-owned function, type, operator, index, migration contribution, and high-level client.

let mut extensions = ExtensionRegistry::default();
let pgmq = extensions.register_pack::<Pgmq>()?;
let events = pgmq.client(&pool).queue("events");
let id = events
    .send(json!({"kind": "post.published"}))
    .await?;

Field-aware packs compose directly with generated field expressions and generated queries:

let nearest = vector.nearest_cosine(
    post::embedding(),
    &query_embedding,
);

let posts = client
    .post()
    .order_by_expression(nearest)
    .limit(10)
    .all()
    .await?;

The compile-checked gallery owns crates/rent/examples/extensions/schema.rsl, while each dedicated application has a smaller schema containing only its extension request. Continue through the PostgreSQL extensions section. Each page has an executable example target; the Docker provider matrix executes supported packs against stock PostgreSQL, Supabase, TimescaleDB, and ParadeDB images.

Start with the durable queue application: it reuses the User/Post/Comment client, publishes a post and event atomically, and processes retries with an idempotent worker. The same application runs through the required live nextest matrix. Set DATABASE_URL before running this example directly; its database effects are temporary tables and a uniquely named queue that it cleans up.