A barebones SQLite implementation in Rust, built for the CodeCrafters "Build Your Own SQLite" challenge. Zero dependencies: everything (SQL parsing, B-tree traversal, record decoding) is implemented from scratch against the official SQLite file format spec, with the SQLite database file format diagrams as a supplementary document for better illustration.
.dbinfoand.tablesdot-commandsSELECTwith column projection,SELECT *,COUNT(*)WHEREfiltering via full table scanWHEREfiltering via index scan (uses the index B-tree to find rowids, then point-lookups into the table B-tree)
$ ./your_program.sh companies.db "select id, name from companies where country = 'eritrea'"- How SQLite lays out a database file: the header, pages, B-tree page types (interior vs. leaf), and cell pointer arrays
- How indexes work in SQLite: finding rowids via the index B-tree, then rowid lookups into the table B-tree + choosing between index scan and full table scan at query time
- How to write a tokenizer + parser with an AST for SQL in Rust
- Zero-copy binary parsing in Rust with slices and methods like
split_first_chunk/split_at_checked - How varints pack a 64-bit integer into 1-9 bytes, and how SQLite's varint differs from Protocol Buffers' LEB128 (the 9th byte uses all 8 bits)
Fun detail: the implementation bootstraps itself by parsing SQLite's own
sqlite_schema CREATE TABLE statement with its own parser, then uses that to
decode every other table's schema.
| File | Role |
|---|---|
src/main.rs |
CLI entry point; query planning (index scan vs. table scan) |
src/sql.rs |
Tokenizer + recursive-descent parser for SELECT / CREATE TABLE / CREATE INDEX |
src/sqlite.rs |
File format layer: pages, B-trees, varints, record decoding, schema maps |
src/error.rs |
Error types |