PostgreSQL extensions
Need similar-document search, a background queue, or location queries? PostgreSQL extensions let those capabilities live beside your application data. Rent lets you declare them in RSL and use their types and operations from Rust.
For example, pgvector adds an embedding to a post and lets you find nearby posts:
datasource db {
provider = "postgresql"
}
extension vector {
name = "vector"
}
model Post {
id BigInt @id
title String
embedding pgvector.Vector? @db.Vector(1536)
}After generating the client and applying the migration, the query looks like an ordinary post query:
let posts = client
.post()
.order_by_embedding_cosine(&query_vector)?
.limit(10)
.all()
.await?;The pgvector guide shows dependencies, vector creation, and deployment requirements.
Choose a capability
- Application infrastructure: pgmq queues, pg_cron schedules, and pg_net HTTP
- Search and discovery: pgvector, ParadeDB pg_search, and pg_trgm
- Location and time: PostGIS and TimescaleDB
- Data modeling and integrity: citext, uuid-ossp, pg_jsonschema, and pg_partman
- Security and auditing: pgcrypto and pgAudit
Each guide explains what the extension does, when to use it, its Rent API, and what the database server needs.
Register a pack when using its API
A pack makes an extension's types and operations available to Rent. For direct pack APIs, register it during application setup and keep the returned handle:
use rent_ext_pgvector::PgVector;
let mut extensions = rent::extension::ExtensionRegistry::default();
let pgvector = extensions.register_pack::<PgVector>()?;That handle gives access to the extension's functions, types, operators, indexes, migrations, and higher-level clients. Pack manifests describe PostgreSQL compatibility, installation schemas, privileges, preload libraries, dependencies, provider enablement, and supported upgrade paths.
Operational extensions such as pgmq provide async clients bound to a database.
Query-oriented extensions provide typed expressions that compose with Rent's
query expressions and generated filters.
Share an application transaction
Pass the generated client to a registered pack to use its connection context. Inside a transaction closure,
pass tx so application writes and extension calls commit or roll back together:
use rent_ext_pgmq::{Pgmq, PgmqClientExt};
let pgmq = extensions.register_pack::<Pgmq>()?;
client
.transaction_app(async |tx| -> anyhow::Result<()> {
let post = tx
.create_post()
.title("A new post")
.body("Hello!")
.published(false)
.author_id(author_id)
.save()
.await?;
pgmq
.client(&tx.system())
.queue("post_events")
.send(serde_json::json!({ "post_id": post.id }))
.await?;
Ok(())
})
.await?;Create the queue during application setup. A registered pack can also bind directly to a DatabasePool
for independent operations. Binding to a transaction client preserves its connection and session settings.
Using that client after commit or rollback returns a closed-transaction error. Database row-level security
still applies. Arbitrary extension SQL does not infer Rent entity policies or the tenant guard, so a generated
client must be a system handle (tx.system() keeps the transaction) or calls return
DriverError::RawSqlRequiresSystem. Check application authorization before issuing administrative calls or
enqueueing privileged work.
Scalar and row-set results
The shared extension client decodes native SQL values. query_i32, query_i64, query_string, query_bytes,
query_f32, query_f64, and query_bool return None for no row or SQL NULL and reject multiple rows.
Use query_scalar_result::<T> when you need to distinguish ScalarResult::NoRow, ScalarResult::Null,
and ScalarResult::Value(value). query_required::<T> requires one non-NULL value. Type mismatches are errors,
not automatic coercions. SQL NULL and the JSON value null remain distinct in typed JSON scalar results.
Use query_json for row sets and execute for operations whose result is intentionally ignored.
Prepare the database server
Before planning an extension migration, verify the destination server and hosting policy:
rent extension check --provider self-hostedAfter installation or upgrade, inspect the versions and database objects that are actually present:
rent extension statusBoth commands support --format json for deployment automation. See the check and status command guides for full output and provider options.
