Documentation
¶
Overview ¶
Package fdw provides a Go framework for writing SQLite virtual tables -- the SQLite equivalent of PostgreSQL's foreign data wrappers.
Users implement Source and Cursor to describe their data source. A backend package wires that implementation into a specific Go SQLite library:
- github.com/values-conflict/go-sqlite-fdw/modernc -- modernc.org/sqlite (pure Go)
- github.com/values-conflict/go-sqlite-fdw/zombiezen -- zombiezen.com/go/sqlite
- github.com/values-conflict/go-sqlite-fdw/ncruces -- github.com/ncruces/go-sqlite3
- github.com/values-conflict/go-sqlite-fdw/loadext -- loadable .so extension
Each backend exports a Register function that accepts a connection of the appropriate type alongside the module name and factory function. The factory receives a ConnectArgs describing the virtual table being created or reconnected, and returns a Source instance and a CREATE TABLE declaration string declaring the virtual table's column schema.
Query planning ¶
SQLite calls Source.BestIndex during query planning to discover which WHERE-clause constraints and ORDER BY terms the virtual table can handle efficiently. BestIndex fills in the output fields of IndexInfo to communicate its chosen plan back to SQLite. The same idxNum and idxStr values are later passed to Cursor.Filter when a scan begins.
Batch delivery ¶
Cursors may optionally implement BatchCursor for sources that naturally deliver rows in batches (paginated APIs, network cursors, etc.). The IPC backend (loadext) uses BatchCursor to reduce pipe round-trips; in-process backends fall back to calling Next one row at a time when BatchCursor is not implemented.
Writable tables ¶
Sources that support INSERT, UPDATE, and DELETE may implement WritableSource. The backend detects this via interface assertion at registration time.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BatchCursor ¶
type BatchCursor interface {
Cursor
// NextBatch advances up to max rows and returns them as a slice of [Row] values. Each [Row] contains one value per column in column order. Returning fewer than max rows is always valid. Returning nil or an empty slice signals EOF.
NextBatch(max int) ([]Row, error)
}
BatchCursor may be implemented by a Cursor to support batch row delivery. The IPC backend uses NextBatch to reduce pipe round-trips; in-process backends may use it to express sources that naturally deliver rows in chunks.
When implementing BatchCursor, the Filter, Next, EOF, Column, and RowID methods of Cursor are still required -- backends may call either interface.
type BatchSizeHinter ¶
type BatchSizeHinter interface {
PreferredBatchSize() int
}
BatchSizeHinter may be implemented by a Cursor alongside BatchCursor to declare a preferred batch size for the first fetch. When not implemented, backends use a default batch size.
type ConnectArgs ¶
type ConnectArgs struct {
Module string // the registered module name
Database string // "main", "temp", or the name given to ATTACH
Table string // the virtual table name
Args []string // user-supplied arguments from CREATE VIRTUAL TABLE ... USING module(args...)
}
ConnectArgs holds the arguments passed to a virtual table Create or Connect call. They correspond to the argv array in the SQLite xCreate/xConnect C callbacks.
type ConnectFactory ¶
type ConnectFactory = func(ConnectArgs) (Source, string, error)
ConnectFactory is the standard factory function type for creating virtual table Source instances. The first return value is the source; the second is a CREATE TABLE schema declaration string; the third is any error.
type Cursor ¶
type Cursor interface {
// Filter begins a scan with the given index and constraint argument values. idxNum and idxStr are the values set in [IndexInfo] by [Source.BestIndex]. args contains the constraint values corresponding to entries where ArgvIndex > 0, in ArgvIndex order (args[0] is the constraint with ArgvIndex == 1, etc.).
Filter(idxNum int, idxStr string, args []Value) error
// Next advances to the next row. It is called after Filter and after each successful call to Next.
Next() error
// EOF reports whether the cursor is past the last row. It is called after Filter and after each call to Next.
EOF() bool
// Column returns the value of column n in the current row. n is zero-based and matches the column order in the schema declaration.
Column(n int) (Value, error)
// RowID returns the row ID of the current row.
RowID() (int64, error)
// Close releases any resources associated with the cursor.
Close() error
}
Cursor iterates over the rows of a virtual table. Implementations may optionally implement BatchCursor and BatchSizeHinter for sources that naturally deliver rows in chunks.
type IndexConstraint ¶
type IndexConstraint struct {
Column int // column index; -1 for the rowid
Op IndexConstraintOp // the constraint operator
Usable bool // false when the constraint must be ignored (eg, in some join orderings)
}
IndexConstraint describes a single WHERE-clause constraint passed to Source.BestIndex.
type IndexConstraintOp ¶
type IndexConstraintOp uint8
IndexConstraintOp is the operator for an IndexConstraint. The numeric values match the SQLITE_INDEX_CONSTRAINT_* constants.
https://sqlite.org/c3ref/c_index_constraint_eq.html
const ( OpEQ IndexConstraintOp = 2 OpGT IndexConstraintOp = 4 OpLE IndexConstraintOp = 8 OpLT IndexConstraintOp = 16 OpGE IndexConstraintOp = 32 OpMatch IndexConstraintOp = 64 OpLike IndexConstraintOp = 65 OpGlob IndexConstraintOp = 66 OpRegexp IndexConstraintOp = 67 OpNE IndexConstraintOp = 68 OpIsNot IndexConstraintOp = 69 OpIsNotNull IndexConstraintOp = 70 OpIsNull IndexConstraintOp = 71 OpIs IndexConstraintOp = 72 OpLimit IndexConstraintOp = 73 OpOffset IndexConstraintOp = 74 // OpFunction and values through 255 represent overloaded SQL functions. // https://sqlite.org/vtab.html#xfindfunction OpFunction IndexConstraintOp = 150 )
type IndexConstraintUsage ¶
type IndexConstraintUsage struct {
// ArgvIndex is the 1-based position in the args slice passed to [Cursor.Filter]. Zero or negative means this constraint is not passed to Filter. The set of positive ArgvIndex values across all entries must be a contiguous sequence starting at 1 with no duplicates.
ArgvIndex int
// Omit is a hint to SQLite that the virtual table guarantees this constraint is fully satisfied, so SQLite need not re-check it.
Omit bool
}
IndexConstraintUsage describes how Source.BestIndex chose to handle a constraint.
type IndexInfo ¶
type IndexInfo struct {
// Inputs -- read-only in BestIndex.
Constraints []IndexConstraint
OrderBy []IndexOrderBy
ColumnsUsed uint64 // bitmask; bit n is set when column n is referenced by the query
// Outputs -- filled by BestIndex.
ConstraintUsage []IndexConstraintUsage
IdxNum int32
IdxStr string
OrderByConsumed bool // true when output is already ordered per OrderBy
EstimatedCost float64 // estimated number of rows scanned; 0 uses SQLite's default
EstimatedRows int64 // estimated number of rows returned; 0 uses SQLite's default
IdxFlags IndexScanFlag
// RHSValue returns the right-hand side value of constraint i, if known at planning time. Useful for equality constraints against constants (eg, "col = 'foo'"). Returns (Value, false) when the RHS is not a constant or is unavailable.
RHSValue func(i int) (Value, bool)
// Collation returns the collation sequence name for constraint i. Returns "BINARY" when the collation is the default binary comparison.
Collation func(i int) string
}
IndexInfo describes the constraints and ordering for a query against a virtual table. Source.BestIndex receives a pointer to an IndexInfo, fills in the output fields, and returns.
The Constraints and OrderBy slices are inputs from SQLite and must not be modified. ConstraintUsage must be set to a slice of the same length as Constraints; entries left at the zero value mean the corresponding constraint is not used.
See https://sqlite.org/vtab.html#xbestindex for the full SQLite documentation.
type IndexOrderBy ¶
IndexOrderBy describes a term in the ORDER BY clause.
type IndexScanFlag ¶
type IndexScanFlag uint32
IndexScanFlag is a bitmask of flags set in IndexInfo.IdxFlags.
const ( // IndexScanUnique indicates the scan visits at most one row. IndexScanUnique IndexScanFlag = 1 // IndexScanHex causes EXPLAIN QUERY PLAN to display IdxNum in hexadecimal. IndexScanHex IndexScanFlag = 2 )
type RenameSource ¶
RenameSource may be implemented by a Source to support RENAME TABLE.
type Source ¶
type Source interface {
// BestIndex informs SQLite how to best access this virtual table. It fills in the output fields of info before returning. SQLite may call BestIndex multiple times per query with different inputs.
BestIndex(info *IndexInfo) error
// Open creates a new cursor for scanning this table.
Open() (Cursor, error)
// Disconnect releases any resources associated with this table instance. It is called when the database connection is closed or the virtual table is no longer needed for this connection.
Disconnect() error
// Destroy is called when the virtual table is dropped (DROP TABLE). For read-only sources with no persistent state, Destroy may simply call Disconnect.
Destroy() error
}
Source is a virtual table instance. Each backend accepts a factory of the form func(ConnectArgs) (Source, string, error), where the string is a CREATE TABLE statement declaring the virtual table's schema.
The minimum implementation is BestIndex, Open, Disconnect, and Destroy. Sources that support DML may additionally implement WritableSource. Sources that support RENAME may additionally implement RenameSource.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is a SQLite column value. The zero value is NULL.
func (Value) Blob ¶
Blob returns the blob value. The result is meaningful only when Value.Type returns Blob.
func (Value) Float64 ¶
Float64 returns the floating-point value. The result is meaningful only when Value.Type returns Float.
func (Value) Int64 ¶
Int64 returns the integer value. The result is meaningful only when Value.Type returns Integer.
func (Value) Text ¶
Text returns the text value. The result is meaningful only when Value.Type returns Text.
type WritableSource ¶
type WritableSource interface {
Source
// Insert inserts a new row with the given column values. rowid may be non-nil when the INSERT statement supplies an explicit rowid; it must be set to the actual rowid of the inserted row on return.
Insert(cols []Value, rowid *int64) error
// Update replaces the row identified by oldRowid. newRowid may differ from oldRowid when the UPDATE changes the rowid column. newRowid must be set to the actual rowid of the updated row on return.
Update(oldRowid int64, cols []Value, newRowid *int64) error
// Delete removes the row with the given rowid.
Delete(rowid int64) error
}
WritableSource may be implemented by a Source to support DML operations. Backends detect this via interface assertion at registration time.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
memory
Package memory provides a simple in-memory fdw.Source implementation.
|
Package memory provides a simple in-memory fdw.Source implementation. |
|
zipfile
Package zipfile provides an fdw.Source that exposes the contents of a ZIP archive as a virtual table.
|
Package zipfile provides an fdw.Source that exposes the contents of a ZIP archive as a virtual table. |
|
Package fdwtest provides a shared integration test suite for go-sqlite-fdw backends.
|
Package fdwtest provides a shared integration test suite for go-sqlite-fdw backends. |
|
loadext
module
|
|
|
modernc
module
|
|
|
ncruces
module
|