GitHub - RichardKnop/minisql: Embedded single file SQL database written in Golang

2 min read Original article ↗

CI Status Go Report Card Donate Bitcoin

MiniSQL is an embedded single-file SQL database written in Go, inspired by SQLite but borrowing ideas from PostgreSQL.

Documentation

Features

  • 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

Installation

go get github.com/RichardKnop/minisql

Import 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.

CLI

go install github.com/RichardKnop/minisql/cmd/minisql@latest

Or build from source:

git clone https://github.com/RichardKnop/minisql
cd minisql
go build -o minisql ./cmd/minisql/

Or install with homebrew:

See the CLI Shell

Development

Generate mocks

MiniSQL uses mockery to generate interface mocks:

go install github.com/vektra/mockery/v3@v3.7.0
mockery

Run tests

LOG_LEVEL=info go test ./... -count=1

Setting LOG_LEVEL=info suppresses debug output and makes test failures easier to read.

Fuzz testing

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.

Run linter

Benchmarks & profiling

See benchmarks/README.md and benchmarks/RESULTS.md.

Acknowledgements