Compiler & Dialects
The compiler turns a QueryPlan into { sql, params, columnTypes }. A Dialect
decides the SQL dialect and parameter style.
compilePlan
Section titled “compilePlan”import { compilePlan } from "@mountsqli/compiler";
const { sql, params } = compilePlan(plan, "postgres");// sql: SELECT * FROM "users" WHERE "age" > $1// params: [18]Parameter style per dialect
Section titled “Parameter style per dialect”| Dialect | Placeholder |
|---|---|
sqlite |
? |
mysql |
? |
postgres |
$1, $2, … |
Injection-safe by construction
Section titled “Injection-safe by construction”compilePlan never string-concatenates values. Every value becomes a bound
parameter. This is a structural guarantee:
db.from(users).where("email", "=", userInput);// → WHERE "email" = ? (userInput is a param, never inlined)Even raw-SQL hatches (selectExpr/whereExpr) reject ;, --, and /* at
build time.
Other compiler phases
Section titled “Other compiler phases”optimize(plan)— rewrites the plan for better SQL.suggestIndexes(plan)— proposes indexes (powersmountsqli analyze).
Dialects are config-only
Section titled “Dialects are config-only”Switching databases changes the dialect, not your code. The same plan runs on SQLite, Postgres, or MySQL.
Best practices
Section titled “Best practices”- Trust the compiler for parameterization — don’t inline values.
- Use
compilePlanin tests to assert SQL shape per dialect.
Common mistakes
Section titled “Common mistakes”- Manually building SQL strings instead of relying on
compilePlan. - Forgetting the dialect arg (defaults to sqlite).
Related
Section titled “Related”- QueryPlan IR — the input.
- Query Execution — the output runs on a driver.
