project home
rqb
Postgres-only Rust query builder on top of sqlx. rqb validates typed query shapes, renders parameterized SQL, and stays out of ORM territory.
rqb Rust/Postgres Query Builder rqb
NAME
rqb - typed Postgres query construction and sqlx execution helpers
SYNOPSIS
Rust owns query shape. User values become Postgres bind parameters.
JSON search can filter and sort only fields exposed by metadata.
What It Is
rqb is a library for service code that wants to build Postgres queries in Rust without introducing an ORM model. It models tables, fields, expressions, writes, CTEs, joins, locks, and JSON search boundaries. It validates the shape before SQL rendering and executes through sqlx Postgres executors.
Use it when
- the application owns SQL shape but wants Rust composition;
- you need joins, CTEs, writes, locks, and raw escape hatches;
- client JSON should filter and sort only approved fields;
- you want sqlx execution and row decoding, not a second DB layer.
Do not use it for
- generic SQL across several database engines;
- database migrations or schema diffing;
- entity graphs, identity maps, or lazy loading;
- letting HTTP clients construct arbitrary SQL.
60-Second Example
Start with schema metadata, build a query, and inspect the generated SQL shape without exposing values.
use rqb::prelude::*;
use uuid::Uuid;
rqb::schema! {
table public.app_users {
id: uuid = Uuid,
email: text = String,
status: text = String,
}
}
let query = select(app_users::table())
.columns((app_users::ID, app_users::EMAIL))
.filter(app_users::STATUS.eq("active"))
.order_asc(app_users::EMAIL)
.limit(20)
.build()?;
println!("{}", query.summary());
SQL:
SELECT
"id",
"email"
FROM "public"."app_users"
WHERE "status" = $1
ORDER BY "email" ASC
LIMIT $2
Params (2):
$1: String
$2: i64
Cacheable: true
Use query.pretty_sql() when you only want formatted SQL. The exact executable SQL remains available as query.sql.
Core Contract
| Part | Owner | Meaning |
|---|---|---|
| Schema metadata | Server | Fields, Postgres types, operator capabilities, JSON visibility. |
| Query shape | Server Rust code | Sources, joins, projection, CTEs, subqueries, writes, locks, raw fragments. |
| Values | Application or request | Bound through sqlx as Postgres parameters. No user value is interpolated into SQL. |
| JSON search | Client, inside metadata limits | Filter, sort, limit, and offset over exposed fields only. |
| Rendering | rqb | Validated AST becomes Postgres SQL with stable placeholder order. |
Feature Map
Reads
Selects, projections, predicates, ordering, pagination, row-value cursors, counts, set queries, joins, lateral joins, CTEs, subqueries, aggregates, windows.
Writes
Insert, update, delete, returning, defaults, nulls, DTO-derived Insertable and Changeset, upserts, batch VALUES, INSERT ... SELECT, and MERGE.
Postgres Surface
Arrays, JSON/JSONB builders, jsonb_agg_object!, ranges, full-text helpers, advisory locks, row locks, raw statements, raw expressions, raw predicates, raw sources.
Generated Schema
rqb-cli introspects Postgres and emits compact rqb::schema! source with typed fields, aliases, enum types, constraints, and custom type mapping.
Safety Boundaries
- Validation owns correctness checks that rqb can know before rendering.
- Rendering assumes validated input and emits parameterized Postgres SQL.
- Raw SQL is server-owned and still uses rqb placeholders and bind validation.
SearchRequestcannot define projection, joins, CTEs, raw SQL, writes, or subqueries.- Postgres remains the final authority for permissions, constraints, name resolution, and planning.
Install
[dependencies]
rqb = "0.1.7"
sqlx = { version = "0.9.0", default-features = false, features = [
"postgres",
"derive",
"uuid",
"chrono",
"json",
"runtime-tokio",
"tls-rustls-ring-webpki",
] }
uuid = "1"
rqb does not select a sqlx runtime or TLS provider. Choose the runtime-* and tls-* features on your application's direct sqlx dependency.
Install the schema generator when you want to introspect a live database:
cargo install rqb-cli
Read the tutorial next. The exhaustive Rust API reference lives on docs.rs/rqb, and runnable examples live in samples/.