# Extension points — sqlite/sqlite

> Canonical page: https://codevetter.com/unpack/sqlite/extension-points

# Extension points — sqlite/sqlite

Scanned commit fde3a84dddf35f4c19797c8afad04a44c596f4d8 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

SQLite is built almost entirely out of registries, which is why it has such a large third-party ecosystem. At the C level there are seven pluggable interfaces: VFS, virtual-table modules, scalar/aggregate/window functions, collations, page cache, memory allocator, and mutex implementation — plus auto-extensions that fire on every new connection. Above that, FTS5 has its own nested registry for tokenizers and ranking functions. On the source-tree side, the extension points are code generators: adding a PRAGMA means editing `tool/mkpragmatab.tcl`, adding an opcode means adding a `case OP_` in `vdbe.c`, adding grammar means editing `parse.y`, and adding a CLI dot-command means editing the `do_meta_command` chain in `shell.c.in`.
- VFS registry: `sqlite3_vfs_register()`/`sqlite3_vfs_unregister()`/`sqlite3_vfs_find()` form the OS-abstraction plug point, used in-tree by `memdb.c` (the `memdb` VFS) and `os_kv.c` (`kvvfs`), and exported to loadable extensions through the `sqlite3_api_routines` thunk in `loadext.c`. — [src/loadext.c#L320](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/loadext.c#L320) [src/memdb.c#L935](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/memdb.c#L935) [src/os_kv.c#L1086-L1095](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/os_kv.c#L1086-L1095)
- Virtual-table registry: `sqlite3_create_module()` and `sqlite3_create_module_v2()` in `src/vtab.c:108-130` register a `sqlite3_module` vtable implementation; this is how `series`, `zipfile`, `dbstat`, `dbpage`, FTS and R-Tree all attach. — [src/vtab.c#L84-L130](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/vtab.c#L84-L130) [ext/misc/series.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/misc/series.c) [src/dbstat.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/dbstat.c)
- Function registry: built-ins are installed by `sqlite3RegisterBuiltinFunctions()` (`src/func.c:3368`) from a static `FUNCTION(...)` macro table, and the same mechanism is exposed publicly as `sqlite3_create_function*` — extensions like `decimal.c`, `base85.c` and `shathree.c` use it exclusively. — [src/func.c#L3368](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/func.c#L3368) [ext/misc/decimal.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/misc/decimal.c) [ext/misc/shathree.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/misc/shathree.c)
- Collation registry: `createCollation()` (`src/main.c:2907`) backs `sqlite3_create_collation*`; SQLite seeds four built-ins — BINARY in UTF8/UTF16BE/UTF16LE, plus NOCASE and RTRIM — at connection open. — [src/main.c#L2907](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/main.c#L2907) [src/main.c#L3579-L3587](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/main.c#L3579-L3587)
- Auto-extension registry: `sqlite3_auto_extension()` appends to the process-global `sqlite3Autoext` list guarded by `SQLITE_MUTEX_STATIC_MAIN`, and `sqlite3AutoLoadExtensions()` replays it on every new connection. — [src/loadext.c#L800-L830](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/loadext.c#L800-L830) [src/loadext.c#L911](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/loadext.c#L911)
- Loadable-extension ABI: `sqlite3LoadExtension` looks for `sqlite3_extension_init`, and if absent derives a name of the form `sqlite3_X_init` from the filename between the last `/` and the first `.`, lowercasing alphabetic characters — this is the convention every `ext/misc/*.c` file follows. — [src/loadext.c#L605-L640](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/loadext.c#L605-L640) [ext/misc/fileio.c#L1270](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/misc/fileio.c#L1270)
- FTS5 exposes a second-level registry through `fts5_api`: `xCreateTokenizer`, `xCreateTokenizer_v2` (for custom text segmentation) and `xCreateFunction` (for auxiliary/ranking functions receiving an `Fts5ExtensionApi`). — [ext/fts5/fts5.h#L350-L360](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/fts5/fts5.h#L350-L360) [ext/fts5/fts5.h#L696-L735](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/ext/fts5/fts5.h#L696-L735)
- Pluggable subsystem hooks are set through `sqlite3_config()` (`src/main.c:443`), which accepts `SQLITE_CONFIG_MALLOC`, `SQLITE_CONFIG_PAGECACHE`, `SQLITE_CONFIG_MUTEX`, `SQLITE_CONFIG_LOG`, `SQLITE_CONFIG_URI` and threading modes — the CLI itself uses the LOG, URI and MULTITHREAD forms. — [src/main.c#L443](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/main.c#L443) [src/shell.c.in#L13878-L13884](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/shell.c.in#L13878-L13884)
- PRAGMA extension point: new pragmas are declared as `NAME:`/`TYPE:`/`ARG:`/`IF:` records in the `pragma_def` block of `tool/mkpragmatab.tcl`, which regenerates `pragma.h`; the matching `case PragTyp_XXXXX:` is then added in `src/pragma.c`. — [tool/mkpragmatab.tcl#L1-L50](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/tool/mkpragmatab.tcl#L1-L50) [src/pragma.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/pragma.c) [AGENTS.md](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/AGENTS.md)
- Grammar extension point: SQL syntax changes go in `src/parse.y` (2,169 lines), compiled by the in-tree Lemon generator `tool/lemon.c` against the `tool/lempar.c` template — never by editing `parse.c`. — [src/parse.y](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/parse.y) [tool/lemon.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/tool/lemon.c) [tool/lempar.c](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/tool/lempar.c) [README.md#L252-L262](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/README.md#L252-L262)
- Shell extension point: `src/shell.c.in` supports an `SQLITE_SHELL_EXTFUNCS` preprocessing hook in `open_db()` for downstream builds to register their own functions, alongside the `INCLUDE ../ext/...` mechanism processed by `tool/mkshellc.tcl`. — [src/shell.c.in#L5183-L5190](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/shell.c.in#L5183-L5190) [src/shell.c.in#L259-L326](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/shell.c.in#L259-L326) [tool/mkshellc.tcl](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/tool/mkshellc.tcl)
- Authorizer hook: `sqlite3_set_authorizer()` (`src/auth.c:70`) installs a callback consulted by `sqlite3AuthCheck`/`sqlite3AuthRead` at code-generation time — `sqlite3Select` calls `sqlite3AuthCheck(pParse, SQLITE_SELECT, …)` before compiling any query — which is the hook the shell's `.auth` and safe mode both build on. — [src/auth.c#L70-L250](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/auth.c#L70-L250) [src/select.c#L7710](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/select.c#L7710) [src/shell.c.in#L2838-L2875](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/shell.c.in#L2838-L2875)
- Build-system extension point: `--amalgamation-extra-src` is threaded through `auto.def` into `AMALGAMATION_EXTRA_SRC`, letting downstream builds fold additional C files into the generated `sqlite3.c`. — [auto.def#L46-L48](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/auto.def#L46-L48) [main.mk#L1145-L1150](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/main.mk#L1145-L1150) [tool/mksqlite3c.tcl#L26-L33](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/tool/mksqlite3c.tcl#L26-L33)
- TCL binding extension point: `Sqlite3_Init` registers the `sqlite3` TCL command via `DbMain`, whose per-database object command `DbObjCmd` is the dispatch table that all 1,195 `.test` scripts drive. — [src/tclsqlite.c#L2485](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/tclsqlite.c#L2485) [src/tclsqlite.c#L4310](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/tclsqlite.c#L4310) [src/tclsqlite.c#L4499-L4513](https://github.com/sqlite/sqlite/blob/fde3a84dddf35f4c19797c8afad04a44c596f4d8/src/tclsqlite.c#L4499-L4513)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
