This document captures a possible future direction for pgQuill.
It is intentionally outside the current implementation scope. The main project should focus first on the typed PostgreSQL DSL, schema generation, runtime integration, and record layer.
A strong future version of sql! should:
- parse SQL using PostgreSQL's real parser
- validate referenced schemas, tables, columns, aliases, and functions against a generated snapshot
- infer parameter types
- infer output row shape
- fail at compile time when the schema and query disagree
Example direction:
let q = sql!(
r#"
select u.id, u.name
from public.users as u
where u.id = :user_id
"#,
user_id: i64
);
let row: (i64, String) = q.fetch_one(&db).await?;Recommendation:
- keep it string-based first
- validate it against generated schema metadata or prepare-time artifacts
- rewrite named parameters to PostgreSQL positional binds internally
Why string-based first instead of token-tree SQL immediately:
- PostgreSQL has many operators (
@>,->>,#>>,?|, casts, array syntax) - Rust tokenization can make a token-tree SQL macro awkward quickly
$1placeholders are not a great Rust macro UX
If a token-like macro is ever added later, this is a safer direction:
let q = psql!(
SELECT u.id, u.name
FROM public.users AS u
WHERE u.id = ${user_id}
);This repository already has local precedent for the hardest part:
backend-rust/schemalane/schemalane-coreusespg_querybackend-rust/schemalane/pg_query_fmtformats PostgreSQL AST back to SQL
That means pgQuill can likely reuse the same parser family for:
- splitting and parsing SQL
- AST walking
- location-aware errors
- formatting validated queries for debugging
The most important scope decision here is this:
- PostgreSQL parsing is realistic locally
- full PostgreSQL semantic analysis is a much larger project
So the recommended direction is a hybrid:
- use
pg_query-style parsing locally for syntax, formatting, and diagnostics - use a prepare/generate step against a real PostgreSQL database for authoritative type validation and result-shape capture
- check generated metadata or wrappers into the repo for offline CI builds
That is much closer to the SQLx / Cornucopia model, and it avoids turning pgQuill into a full PostgreSQL compiler front-end too early.
Potential implementation phases for this idea:
sql!(r#"..."#, binds...)orsql_file!("queries/foo.sql")- validate queries during an explicit prepare/generate step against a dev database
- capture bind types and result-column metadata into generated artifacts
- emit lightweight wrappers that execute through
tokio-postgres
- use local PostgreSQL parsing for richer editor diagnostics and better error reporting
- support direct decoding into generated row structs or tuples
- add stronger support for CTE scopes, lateral scopes, subqueries, and set operations in generated metadata
- optional token-tree sugar macro
- better diagnostics with highlighted query spans
- deeper local validation where it clearly adds value without duplicating PostgreSQL's whole type checker
Important caution:
Do not block the entire project on perfect local SQL inference. A useful sql! backed by authoritative database validation is already extremely valuable.