sqlite3ext.h
Overview
The sqlite3ext.h header file provides the interface specifically designed for building shared library extensions that can be dynamically loaded into an SQLite instance. Rather than including the standard sqlite3.h file, extensions should include sqlite3ext.h to access the SQLite API through a versioned, stable function pointer table. This indirection supports binary compatibility across different SQLite versions by avoiding direct linking with SQLite’s internal symbols.
The core of this interface is the sqlite3_api_routines structure, which contains pointers to all public SQLite API functions. Extensions receive a pointer to this structure on initialization, allowing them to invoke SQLite functionality safely and portably.
This file also defines macros that redirect calls to SQLite API functions through the global sqlite3_api pointer, enabling extensions to call SQLite functions as if they were normal API calls.
Key Components
struct sqlite3_api_routines
This structure encapsulates the entire SQLite API as function pointers. Each member corresponds to one SQLite API function, such as sqlite3_bind_blob, sqlite3_step, or sqlite3_exec. To maintain backward compatibility, new API functions must be appended at the end of this structure.
Important Details:
All SQLite API functions are accessed through this structure in an extension.
The structure is large and comprehensive, covering all operations on database connections, statements, values, virtual tables, backup interfaces, mutexes, virtual file systems, error handling, and more.
Some members are conditionally compiled based on SQLite version or compilation options.
The structure contains functions added progressively as SQLite evolved, with comments indicating the version they were introduced.
Usage Example:
When an extension is loaded, SQLite passes a pointer to an instance of sqlite3_api_routines:
int sqlite3_extension_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi); // Initialize global pointer
// Now the extension can call SQLite functions via sqlite3_api pointer
// e.g., sqlite3_api->exec(db, "CREATE TABLE...", NULL, NULL, NULL);
return SQLITE_OK;
}
typedef int (*sqlite3_loadext_entry)(sqlite3*, char**, const sqlite3_api_routines*);
Defines the standard function signature for SQLite extension entry points. Extensions must implement an initialization function matching this signature to be loaded correctly.
Parameters:
sqlite3 *db: Database handle provided by SQLite.char **pzErrMsg: Pointer to an error message string; can be set by the extension on failure.const sqlite3_api_routines *pThunk: Pointer to the API routines table.
Returns:
An integer SQLite result code (
SQLITE_OKon success).
API Redirection Macros
These macros redefine all SQLite API calls so that calls in extensions are routed through the global sqlite3_api pointer, which points to the sqlite3_api_routines structure provided at runtime.
For example:
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_step sqlite3_api->step
#define sqlite3_finalize sqlite3_api->finalize
This means extension code can use normal SQLite API function calls transparently, while under the hood calls are dispatched through the function pointers.
Conditional Compilation
The macros are only defined when building an extension (
!defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)).When compiling SQLite core or when extension loading is disabled, these macros are not defined to avoid conflicts.
Extension Initialization Macros
Defines macros to assist extension authors in managing the global sqlite3_api pointer:
SQLITE_EXTENSION_INIT1: Declares the global pointer variable.SQLITE_EXTENSION_INIT2(v): Sets the global pointer to the provided API table.SQLITE_EXTENSION_INIT3: Declares the global pointer as external.
Example usage in an extension source file:
SQLITE_EXTENSION_INIT1
int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){
SQLITE_EXTENSION_INIT2(pApi);
// Extension initialization code
return SQLITE_OK;
}
Implementation Details and Algorithms
The file provides an indirection layer between extensions and the SQLite core API, enabling binary compatibility.
By using a structure of function pointers, it allows extensions compiled against one SQLite version to operate with different SQLite versions, assuming API compatibility.
The extensive list of function pointers covers all public API functions, including newly added ones, ensuring extensions can leverage all SQLite capabilities.
The macros allow extension code to remain clean and use the usual SQLite API names without manual pointer dereferencing.
Interaction with Other Parts of the System
Extensions include this header instead of
sqlite3.h.When an extension is loaded via
sqlite3_load_extension(), SQLite passes thesqlite3_api_routinespointer to the extension’s entry point.The extension then uses this pointer to access SQLite functionality, enabling safe and portable API calls.
This header bridges the gap between the SQLite core library and the dynamically loaded extension modules.
It enables the SQLite core to remain unchanged while extensions evolve independently.
Mermaid Diagram
flowchart TD
A[Extension Entry Point] --> B[Receives sqlite3_api_routines*]
B --> C[sqlite3_api pointer initialized]
C --> D[SQLite API calls via macros]
D --> E{sqlite3_api_routines struct}
E --> F[Function pointer: bind_blob]
E --> G[Function pointer: step]
E --> H[Function pointer: finalize]
E --> I[... other API functions ...]
Summary of the Main API Functions in sqlite3_api_routines
Context and Aggregate Functions
aggregate_context(): Allocates/retrieves memory for aggregate functions.aggregate_count(): Retrieves count of rows aggregated so far.
Binding Functions
bind_blob(),bind_double(),bind_int(),bind_null(),bind_text(), etc.: Bind values to prepared statement parameters.
Statement Execution
step(): Advances a prepared statement to the next result.reset(): Resets a prepared statement to its initial state.finalize(): Deletes a prepared statement.
Result Functions
result_blob(),result_double(),result_int(),result_null(),result_text(): Set the result of a user-defined function.
Value Functions
value_blob(),value_double(),value_int(),value_text(): Retrieve typed values from function arguments.
Database Handle Functions
open(),close(): Open and close database connections.exec(): Executes SQL statements directly.last_insert_rowid(): Returns the rowid of the last inserted row.
Collation and Function Creation
create_collation(): Registers collating sequences.create_function(): Registers user-defined functions.create_module(): Registers virtual table modules.
Error Handling
errcode(),errmsg(): Retrieve error codes and messages.result_error(): Report errors from user-defined functions.
Memory Management
malloc(),realloc(),free(): Memory allocation functions.
Advanced Features
Backup API (
backup_init(),backup_step()).Mutex and threading (
mutex_alloc(),mutex_enter(), etc.).Virtual file system (vfs_find(), vfs_register()).
Extension loading (
load_extension()).SQL statement introspection (
expanded_sql(),normalized_sql()).Prepared statement status and explanation (
stmt_status(),stmt_explain()).
Usage Patterns
Extension authors include sqlite3ext.h to gain access to
sqlite3_api_routines.During extension initialization,
sqlite3_apiis initialized with the pointer SQLite passes in.All SQLite API calls in the extension are made via the macros that forward calls through
sqlite3_api.This design isolates extension code from direct linking to SQLite internals, allowing safe ABI compatibility.
References
For detailed API function descriptions, see SQLite C Interface.
For extension development guidelines, see SQLite Extension Loading.
For virtual tables and modules, see SQLite Virtual Tables.
For user-defined functions and collations, see SQLite User-Defined Functions.
This file is a critical component in the SQLite extension mechanism, enabling binary compatibility and safe interaction between dynamically loaded extensions and the SQLite core engine.