Architecture
sqlite3-partitioner is a SQLite extension implemented in Rust. It exposes a virtual table module that partitions incoming rows into separate physical tables behind the scenes.
Components
src/vtab_interface— virtual table implementation (create,connect,insert,update,delete,open,filter,best_index, etc.). The planner hook (best_index) translates constraints on the partition column into partition ranges, reports them to SQLite viaomit, and estimates costs from the_statstable.src/shadow_tables— backing tables that store metadata:_root— partition column, interval, and lifetime._template— schema that new partitions copy, including indexes._lookup— partition start epoch → physical table name, plus expiry._stats— per-partition row counts used for query planning andpartitioner_count_between.
src/cleanup.rs— thepartitioner_cleanupscalar function: drops expired partitions and purges their_lookup/_statsrows in one transaction.src/companions— pluggable companion shadow tables (experimental). ACompaniontrait with lifecycle hooks on flush/insert/delete/cleanup; the sqlite-vec (vec0) implementation lives behind thevecCargo feature. Each data partition owns its matching companion table and shares its rowids with it; declarations are stored in a<name>_companionsshadow table.src/types— parsed column declarations, constraints, and WHERE-clause helpers.src/utils— interval parsing, value-type parsing, and datetime helpers.src/error— shared error types.
How it works
CREATE VIRTUAL TABLEcreates the shadow tables and records the partitioning configuration (interval, partition column, optional lifetime) in_root.INSERTroutes rows to an in-memory batch keyed by partition value. When the batch fills, or before a read/update/delete, the extension creates the target partition table (copying the template schema and indexes, plus the automatic partition-column index) and flushes the buffered rows as a multi-row insert.SELECTusesbest_indexto turnWHEREconstraints on the partition column into a partition range; only those physical tables are scanned. Because partitions are disjoint, ordered ranges of the partition column,ORDER BY <partition column>is answered by scanning partitions in order — no temp b-tree.UPDATEandDELETEflush pending rows first, then use a rowid mapper to locate the physical row.partitioner_cleanup('<name>')drops every partition whose expiry has passed (from_lookup.expires_at) and removes its metadata, returning the number of partitions dropped. It only runs when called.
Repository structure
src/
├── error/ # error types
├── shadow_tables/ # root, template, lookup, stats, interface
├── types/ # column declarations, constraints
├── utils/ # parsing and validation helpers
├── vtab_interface/ # virtual table module and operations
├── benchmarks.rs # ignored-by-default benchmark suite
├── cleanup.rs # partitioner_cleanup scalar function
├── companions/ # pluggable companion shadows (vec0 behind `vec` feature)
└── lib.rs