MiniSQL is an embedded single-file SQL database written in Go, inspired by SQLite but borrowing ideas from PostgreSQL.
- Pure Go — zero CGO
- MVCC snapshot isolation for reads; serialised single-writer for writes
- B+ tree storage with WAL and crash recovery
- Parallel full-table scan
- JSON and UUID as native column types
- Built-in full-text search (inverted index +
MATCH/TS_RANK) - Built-in JSON inverted index (
JSON_CONTAINS) - Vector similarity search (
VECTOR(n)column +VEC_L2/VEC_COSINE+ HNSW ANN index) - Transparent AES-256-CTR page encryption with HKDF key derivation
go get github.com/RichardKnop/minisqlImport the driver (blank import registers it with database/sql):
import (
"database/sql"
_ "github.com/RichardKnop/minisql"
)db, err := sql.Open("minisql", "./my.db")
if err != nil {
log.Fatal(err)
}
db.SetMaxOpenConns(1) // required — see docs
defer db.Close()See the Getting Started guide and Connection reference for full details.
go install github.com/RichardKnop/minisql/cmd/minisql@latestOr build from source:
git clone https://github.com/RichardKnop/minisql
cd minisql
go build -o minisql ./cmd/minisql/Or install with homebrew:
brew install minisqlSee the CLI Shell
MiniSQL uses mockery to generate interface mocks:
go install github.com/vektra/mockery/v3@v3.7.0
mockeryLOG_LEVEL=info go test ./... -count=1Setting LOG_LEVEL=info suppresses debug output and makes test failures easier to read.
MiniSQL uses Go's built-in fuzzer (go test -fuzz) to find parser bugs and
storage corruption issues that structured unit tests are unlikely to reach.
Three fuzz targets are maintained:
| Target | Package | What it finds |
|---|---|---|
FuzzParser |
./internal/parser/ |
Parser panics / infinite loops on arbitrary SQL input |
FuzzPageUnmarshal |
./internal/minisql/ |
Panics in B-tree page deserialization on truncated/corrupt pages |
FuzzRowView |
./internal/minisql/ |
Panics in row value decoding (RowView.ValueAt) on arbitrary cell bytes |
Run a fuzzer (stops after 60 s; adjust -fuzztime as needed):
go test -fuzz=FuzzParser -fuzztime=60s ./internal/parser/
go test -fuzz=FuzzPageUnmarshal -fuzztime=60s ./internal/minisql/
go test -fuzz=FuzzRowView -fuzztime=60s ./internal/minisql/Run seeds only (fast, no mutation — safe for CI):
go test -run=FuzzParser ./internal/parser/
go test -run=FuzzPageUnmarshal ./internal/minisql/
go test -run=FuzzRowView ./internal/minisql/Corpus entries that previously found real bugs live under each package's
testdata/fuzz/<FuzzTarget>/ directory and are automatically replayed as
ordinary unit tests on every go test run. When the fuzzer discovers a new
crash it writes the minimised input to that directory; commit it so the fix is
covered by CI forever.
make lint