Fast, accurate SQL tooling for SQLite and its dialects.
This crate provides parsing, formatting, and semantic validation for SQL,
built on SQLite's own tokenizer and grammar rules. Four design principles
guide the library:
- Reliability — uses
SQLite's own grammar rules; formatting is round-trip safe and validation mirrors real engine behaviour. - Speed — all core types ([
Formatter], [SemanticAnalyzer], [Catalog]) are designed for reuse across many inputs without re-allocation. - Portability — the core formatting and validation engine has no runtime dependencies beyond the standard library; optional features (
lsp,serde) pull in additional crates. - Flexibility — supports multiple database dialects that extend
SQLite's grammar with their own tokens and rules.
Parsing
Use Parser to parse SQL source text into a typed AST:
use ParseErrorKind;
use ;
let parser = new;
let mut session = parser.parse;
loop
See the [parse] module for additional types like
IncrementalParseSession,
ParserConfig, and
ParserToken.
Validation
Use [SemanticAnalyzer] to check SQL against a known schema. The analyzer
produces a SemanticModel containing structured
[Diagnostic] values with byte-offset spans and "did you mean?" suggestions.
use CatalogLayer;
use ;
let mut analyzer = new;
let mut catalog = new;
// Register a table so the analyzer can resolve column references.
catalog.layer_mut
.insert_table;
let config = default;
let model = analyzer.analyze;
// All names resolve — no diagnostics.
assert!;
For richer output, use DiagnosticRenderer to produce rustc-style
error messages with source context and underlines.
Formatting
Use [Formatter] to pretty-print SQL with consistent style. The formatter
parses each statement, runs a bytecode interpreter over the AST, and
renders the result with a Wadler-style pretty-printer.
# use KeywordCase;
# use ;
let mut fmt = with_config;
let output = fmt.format.unwrap;
assert!;
assert!;
See [FormatConfig] for all available options (line width, indent width,
keyword casing, semicolons).
Features
sqlite(default): enables the built-inSQLitegrammar, [Dialect], and re-exportsParser,Tokenizer, and typed AST [nodes].fmt(default): enables [Formatter], [FormatConfig], andKeywordCase.validation(default): enables [SemanticAnalyzer], [Catalog], [Diagnostic], and related types.lsp: enablesLspServerand [lsp::LspHost] for editor integration.experimental-embedded: enables [embedded] SQL extraction from Python and TypeScript/JavaScript source files.serde: addsSerialize/Deserializeimpls for diagnostics and AST nodes.serde-json: adds JSON convenience helpers (catalog from JSON, AST dump).
Choosing an API
- Use
ParserandTokenizerfor parsing and tokenizing SQL. - Use [
SemanticAnalyzer] + [Catalog] when you need to validate SQL against a database schema (table/column/function resolution). - Use [
Formatter] when you need to pretty-print or normalize SQL text. - Use
LspServer(requires thelspfeature) to embed a full Language Server Protocol implementation in an editor or tool. - Use [
typed] when building reusable code over known generated grammars. - Use [
any] when grammar choice happens at runtime or crosses FFI/plugin boundaries.