Compile-time SQL validation extracted from SQLx.
This crate provides a check! macro that validates SQL queries at compile time by connecting to a database and ensuring the query is valid.
- Compile-time SQL validation: Catch SQL errors before your code runs
- Feature-gated: Enable/disable validation with a feature flag
- Multi-database support: PostgreSQL, MySQL, and SQLite
- Zero runtime overhead: Validation happens only at compile time
Add sql-check to your Cargo.toml:
[dependencies]
sql-check = "0.9.0-alpha.1"
# Enable database support
sql-check = { version = "0.9.0-alpha.1", features = ["postgres"] }Important
SQL Check uses the same feature flags as SQLx for database, async runtime, and TLS support. See Feature Flags for details.
SQL Check's versioning aligns with SQLx. If you, for whatever reason, use both in your project, ensure you use the same version of SQL Check as you're using for SQLx.
use sql_check::check;
// This will be validated at compile time
let sql = check!("SELECT * FROM users WHERE id = 1");
// Use the SQL string with your database library
let result = database.execute(sql).await?;check(default): Enables compile-time SQL validation- When enabled: Validates SQL by connecting to database, then returns the SQL string
- When disabled: Macro becomes a no-op and just returns the SQL string
postgres: PostgreSQL supportmysql: MySQL supportsqlite: SQLite support
_rt-tokio: Use Tokio runtime (recommended)_rt-async-std: Use async-std runtime_rt-smol: Use smol runtime_rt-async-global-executor: Use async-global-executor runtime
_tls-rustls-ring-webpki: Use rustls with ring and webpki_tls-rustls-aws-lc-rs: Use rustls with AWS-LC_tls-rustls-ring-native-roots: Use rustls with ring and native roots_tls-native-tls: Use native-tls
[dependencies]
sql-check = {
version = "0.9.0-alpha.1",
features = ["postgres", "_rt-tokio", "_tls-rustls-ring-webpki"]
}The macro requires the following environment variables:
DATABASE_URL: Connection string for your database- PostgreSQL:
postgres://user:pass@host/db - MySQL:
mysql://user:pass@host/db - SQLite:
sqlite://path/to/db.sqlite
- PostgreSQL:
# Set DATABASE_URL before building
export DATABASE_URL="postgres://user:pass@localhost/mydb"
cargo buildFor production builds, or when you don't have a database connection, disable the check feature:
[dependencies]
sql-check = { version = "0.9.0-alpha.1", default-features = false }Or use cargo build flags:
cargo build --release --no-default-features- At Compile Time: The macro connects to your database
- Sends PREPARE: Database parses and validates the SQL
- Returns Metadata: Database returns column and parameter information
- Compilation Success: If valid, macro expands to the SQL string
- Compilation Error: If invalid, compilation fails with database error
let sql = check!("SELECT invalid_column FROM nonexistent_table");Compile Error:
error: SQL validation failed: relation "nonexistent_table" does not exist
--> src/main.rs:5:15
|
5 | let sql = check!("SELECT invalid_column FROM nonexistent_table");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| Feature | SQL Check check! |
SQLx query! |
|---|---|---|
| SQL Validation | ✅ | ✅ |
| Type Checking | ❌ | ✅ |
| Returns | SQL String | Typed Query |
| Use Case | Compile-time validation | Full ORM |
The check! macro is ideal when you:
- Want SQL validation without SQLx's full macro system
- Use a different database library (e.g., tokio-postgres, diesel)
- Need just validation, not type generation
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
This crate is extracted from SQLx (based on the Extract Compile Time SQL Statement Verification into its own macro crate issue).
Contributions are welcome!