This file will make SQLite internals geeks very happy, and will explain to everyone else where the changes in the Not-forking recipes need to be.
Given an SQLite version, will the LumoSQL not-fork mods apply, and what build system or API boundaries does it cross? We need to answer this question when
picking SQLITE_RANGE / SQLITE_VERSIONS / SQLITE_FOR_LMDB* for a matrix run, and when a target fails. We don't care what the backend might be, we only care
if we have correctly tracked the version changes in SQLite so that the backend can be correctly built. There has been bugs where we accidentally specified in a
.mod file that function X got an additional parameter before SQLite version Y did.
Summary
SQLite 3.43.0 is the lower bound for an LMDBv1 (or any LumoSQL with rowsum on). SQLite versions in the not-fork cache can optionally go from 3.6.10 (2009)
through current trunk and all of them are of course in the SQLite fossil database. LumoSQL doesn't apply to them all, as follows:
| Range | Status with current mods |
|---|---|
< 3.30.0 |
Not in scope for LumoSQL, probably not ever |
3.30.0 .. 3.34.x |
All four fragment_patch mods fail (see below) |
3.35.0 .. 3.42.x |
cursor-shadow-flag.mod fails (see below) |
3.43.0 .. 3.47.x |
All mods apply; pre-Autosetup build system |
3.48.0 .. 3.53.x |
All mods apply; new Autosetup build system |
>= 3.54.0 |
Excluded from current matrix scripts |
71 SQLite versions are in [3.30.0, 3.54.0); 34 of them are in the 100% full-feature working range of [3.43.0, 3.54.0).
Boundaries
Boundaries where the LumoSQL mod set has to set either set the version directive (so the mod is skipped below the boundary), or moves a fragment_patch anchor
(so the mod fails to apply below the boundary).
3.43.0 boundary -- colCache:1 added to struct VdbeCursor
- Affects:
not-fork.d/sqlite3/cursor-shadow-flag.mod - The mod adds an
isShadow:1bit-field tostruct VdbeCursorinsrc/vdbeInt.h, anchored on the existing lineBool colCache:1;(immediately followed byu16 seekHit;). Bool colCache:1;first appears in 3.43.0. In 3.42.1 and earlier the surrounding bit-field block has a different shape and the anchor is absent.cursor-shadow-flag.modhas NOversiondirective, so on any version below 3.43.0 not-fork dies withfragment_patch: Fragment not found.- This is the lower bound for any build that defines
LUMO_EXTENSIONS-- which includes every LMDBv1 build and everyOPTION_ROWSUM=onbuild, regardless of backend.
3.48.0 boundary -- Autotools to Autosetup build-system migration
- Affects:
not-fork.d/sqlite3/makefile.mod(gatedversion < 3.48) andnot-fork.d/sqlite3/makefile-autosetup.mod(gatedversion >= 3.48). - SQLite 3.48.0 (2025-01-14) replaced Autotools with Autosetup and
restructured the canonical-source build system. Most rules moved from
Makefile.intomain.mk; the# libtoolsection that the pre-3.48 mod anchors on no longer exists; the main compile variable was renamed fromTCCtoT.cc.sqlite. - Both mods are version-gated, so this boundary is handled cleanly: each build picks up the correct mod and the other is skipped.
3.35.0 boundary -- threshold for vdbe-changes.mod and rowsum-function.mod
- Both mods carry
version >= 3.35and are skipped on older SQLite. - In practice this gate doesn't help: the same builds also exercise
cursor-shadow-flag.mod(no gate), which fails first below 3.43.0. The 3.35 gate would matter again only if cursor-shadow-flag.mod gained anolder-SQLitevariant or its own version gate.
The .mod files
All mods live under not-fork.d/sqlite3/
| Mod | Method | Version gate | Notes |
|---|---|---|---|
backend-new-files.mod |
replace |
none | Drops in lumo_*.c files |
backend-rename.mod |
sed |
none | Renames backup.c etc. -> lumo_*.c. Word-boundary regex; robust across versions |
cursor-shadow-flag.mod |
fragment_patch |
none | Bool isShadow:1 in struct VdbeCursor. Needs colCache:1 anchor (3.43.0+) |
fix-readline-freebsd.mod |
sed |
none | OS-specific build fix |
fix-readline-netbsd.mod |
sed |
none | OS-specific build fix |
keyinfo-lumo-flag.mod |
fragment_patch |
none | Three hunks (struct KeyInfo, sqlite3KeyInfoOfIndex, sqlite3KeyInfoAlloc). All anchors found across the sample including 3.30.0 |
lumo-extensions.mod |
append |
none | Appends #define BTREE_LUMO_EXTENSIONS to src/btree.h |
makefile.mod |
sed |
< 3.48 |
Pre-Autosetup Makefile.in hook |
makefile-autosetup.mod |
sed |
>= 3.48 |
Autosetup main.mk hook |
replace-files.mod |
replace |
none | Adds .lumosql/* files, src/lumo-sha3.c etc. |
rowsum-function.mod |
fragment_patch |
>= 3.35 |
Registers lumo_rowsum() in aBuiltinFunc[] in src/func.c |
source_id.mod |
sed |
none | Teaches mksqlite3h.tcl about backend name/version |
vdbe-changes.mod |
fragment_patch |
>= 3.35 |
Largest mod: 7 hunks across src/vdbe.c and src/pragma.c (OP_Column, OP_MakeRecord, OP_Insert, OP_IdxInsert, OP_OpenWrite, pragma include, sqlite3Pragma). All anchors found across the sample from 3.35.0 onward |
Mods on the lmdbv1 side:
| Mod | Method | Notes |
|---|---|---|
lumo-new-files.mod |
replace |
Drops in .lumosql/* files for the lmdbv1 build |
SQLite-API boundaries inside not-fork.d/lmd*/files/
The vendored btree.c and pager.c files under not-fork.d/lmdb/files/
and not-fork.d/lmdbv1/files/ stub SQLite's internal API for the LMDB
backend. SQLite's internal API drifts; these stubs gate the drift with
#if SQLITE_VERSION_NUMBER blocks. Boundaries verified against
src/btree.h and src/pager.h in the SQLite fossil repo at each
release tag:
| SQLite version | Change in internal API | Symbol |
|---|---|---|
| 3.31.0 | Pager * first argument becomes const Pager * |
sqlite3PagerFilename |
| 3.33.0 | int (Btree*, int) becomes Pgno (Btree*, Pgno) |
sqlite3BtreeMaxPageCount |
| 3.34.0 | Removed; replaced by sqlite3BtreeTxnState |
sqlite3BtreeIsInTrans |
| 3.34.0 | SQLITE_TXN_NONE, SQLITE_TXN_READ, SQLITE_TXN_WRITE macros added |
(transaction-state sentinels) |
| 3.37.0 | Third parameter int *pnChange becomes i64 *pnChange |
sqlite3BtreeClearTable |
| 3.40.1 | Introduced | sqlite3BtreeClearCache |
| 3.41.0 | Return type becomes int; error message moves to OUT char **pzOut |
sqlite3BtreeIntegrityCheck |
| 3.45.0 | Fourth parameter int *pnVal becomes u64 *pnVal |
sqlite3PagerCacheStat |
| 3.46.0 | Inserts OUT sqlite3_value *aCnt after aRoot |
sqlite3BtreeIntegrityCheck |
| 3.51.0 | Drops the leading KeyInfo * argument |
sqlite3VdbeRecordUnpack |
| 3.51.0 | Introduced | sqlite3BtreeIsEmpty |
sqlite3BtreeIntegrityCheck's signature evolution, by zone:
< 3.41.0:char *F(sqlite3*, Btree*, Pgno*, int, int, int*)3.41.0 .. 3.45.x:int F(sqlite3*, Btree*, Pgno*, int, int, int*, char**)3.46.0 .. current:int F(sqlite3*, Btree*, Pgno*, sqlite3_value*, int, int, int*, char**)
Practical recipes
Giant LMDBv1 + crypto matrix:
SQLITE_RANGE='3.43.0+ -3.54.0+',SQLITE_FOR_LMDBV1="$SQLITE_RANGE",LMDBV1_VERSIONS=1.0, crossOPTION_ROWSUMandOPTION_LMDBV1_ENCRYPTover{off, on}. Seebenchmark/lumosql-matrix-on-big-machine.sh.Smoke test of a single crypto build:
make build SQLITE_VERSIONS=3.53.1 USE_SQLITE=no USE_LMDB=no \ USE_LMDBV1=yes LMDBV1_VERSIONS=1.0 SQLITE_FOR_LMDBV1=3.53.1 \ OPTION_LMDBV1_ENCRYPT=onA single rowsum-on native SQLite build:
(Requiresmake build SQLITE_VERSIONS=3.53.1 USE_LMDB=no USE_LMDBV1=no \ OPTION_ROWSUM=on>= 3.43.0for cursor-shadow-flag to apply;>= 3.35.0for the vdbe and rowsum mods.)