Skip to content

Virtual-table extensions

These expose data through CREATE VIRTUAL TABLE name USING module(...); some accept Go data via sqlite.Pointer(slice).

import (
sqlite "gosqlite.org"
_ "gosqlite.org/ext/array/auto"
)
// Bind a Go slice as a SQL table:
db.Where(`id IN (SELECT value FROM array(?))`,
sqlite.Pointer([]int64{1, 5, 17})).Find(&users)
// Or DDL-based vtabs:
db.Exec(`CREATE VIRTUAL TABLE temp.log USING lines(data='INFO ok\nERROR …')`)
db.Exec(`CREATE VIRTUAL TABLE recent USING statement('SELECT name FROM users WHERE id >= ?')`)
PackageWhat it exposes
arraya Go slice as a SQL table (transparent sqlite.Pointer path)
linessplit a text blob/file into rows (typed lines.Table)
csvCSV files/strings as tables — delimiters, column affinity, skip=N (typed csv.Table)
statementparametrized views with ?N / :name HIDDEN bind columns
closuretransitive_closure graph walker with optional depth bounds (typed closure.Graph)
pivotthree-SELECT cross-tab — rows × columns × cell aggregate
rtreeR-Tree spatial index over the built-in rtree/geopoly vtabs + custom geometry/query callbacks + a circle() geometry (typed rtree.Table)
seriesgenerate_series(start, stop[, step]) integer sequence

Typed handles (csv.Table, lines.Table, closure.Graph, rtree.Table) hide the DDL + query SQL. Demos under examples/features/extensions/; end-to-end against gorm: examples/features/gorm/ext-vtabs/.

csv, lines, fileio, blobio accept a sandbox fs.FS at registration time (which the /auto package can’t carry). Install a connect-hook on the singleton driver before gorm.Open so every pooled conn picks it up:

sqlite.DefaultDriver().RegisterConnectionHook(
func(c sqlite.ExecQuerierContext, _ string) error {
return csv.RegisterFS(c.(*sqlite.Conn), myFsys)
})

The same shape works for lines.RegisterFS, fileio.RegisterFS, blobio.RegisterFS. blobio provides incremental BLOB I/O; fileio provides sandboxed file read/write SQL functions.