sqlite3ext.h
Overview
sqlite3ext.h is a header file that defines the interface for SQLite extension shared libraries. Extensions are dynamically loaded modules that add new functionalities to an SQLite database engine instance. This header provides the necessary declarations to develop extensions compatible with SQLite's internal API. Extensions that are intended to be loaded as shared libraries by SQLite should include this file instead of the standard sqlite3.h to access the SQLite API in a way that maintains binary compatibility across different SQLite versions.
The core feature of this interface is the sqlite3_api_routines structure, which contains pointers to all SQLite API functions. Extensions use this structure to call SQLite functions indirectly, ensuring compatibility with the SQLite host application that loads the extension.
Key Components
sqlite3_api_routines Structure
This structure encapsulates pointers to all SQLite API functions, providing an indirection layer for extensions. Each member is a function pointer corresponding to an SQLite API routine.
Purpose: Allow extensions to call SQLite functions without linking directly against SQLite's static library, enabling version-independent binary compatibility.
Usage: The SQLite engine passes a pointer to this structure (
sqlite3_api) to extensions upon loading, which extensions then use to invoke SQLite functionality.
Important Notes:
To maintain backward compatibility, new API functions are added only at the end of this structure.
The structure contains a comprehensive list of SQLite functions, including database connection management, statement preparation and execution, binding parameters, result handling, virtual tables, blob I/O, mutex operations, and more.
The structure evolves with SQLite versions, with comments indicating version-specific additions.
Examples of API Functions Included:
aggregate_context: Get a pointer to the aggregate context for aggregate SQL functions.bind_blob,bind_double,bind_int, etc.: Bind parameters to prepared statements.create_function,create_module: Define user functions and virtual table modules.exec: Execute SQL statements.prepare,step,finalize: Prepare, execute, and finalize SQL statements.result_text,result_int,result_null: Set function results.blob_open,blob_read,blob_write: Operate on BLOBs.mutex_alloc,mutex_enter,mutex_leave: Thread safety primitives.sqlite3_load_extension: Load an extension dynamically.
Many others covering the full SQLite API surface.
sqlite3_loadext_entry Function Pointer Type
Defines the prototype for entry points of SQLite extensions.
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
Parameters:
db: Pointer to the SQLite database connection on which the extension will operate.pzErrMsg: Pointer to a string pointer used to return an error message if initialization fails.pThunk: Pointer to thesqlite3_api_routinesstructure that provides access to SQLite API functions.
Returns: An integer status code (
SQLITE_OKon success, or an SQLite error code on failure).Usage: An extension must implement an entry point matching this signature, which SQLite calls when loading the extension.
API Redirection Macros
To simplify calling SQLite API functions via the sqlite3_api pointer, this header defines macros that map the usual SQLite API function names to calls through the sqlite3_api structure.
These macros are active only when the extension is compiled outside the core SQLite and when extension loading is enabled.
For example,
sqlite3_bind_blobis defined assqlite3_api->bind_blob, which calls the corresponding function pointer.This design ensures extensions use the correct API version provided at runtime.
Extension Initialization Macros
These macros help manage the sqlite3_api pointer in extension source files:
SQLITE_EXTENSION_INIT1: Declares thesqlite3_apipointer.SQLITE_EXTENSION_INIT2(v): Assigns the passedsqlite3_api_routinespointer tosqlite3_api.SQLITE_EXTENSION_INIT3: Declares thesqlite3_apipointer as extern for use in other files.
These enable extensions to initialize their access to SQLite functions properly.
Implementation Details
The API indirection via
sqlite3_api_routinesis a form of dynamic dispatch, allowing extensions to remain compatible across SQLite versions without recompilation.The structure layout must remain stable; new API functions are appended, never inserted in the middle, to avoid breaking ABI compatibility.
The header guards (
SQLITE3EXT_H) prevent multiple inclusions.The file includes
sqlite3.hto reuse core SQLite type definitions.The file contains conditional compilation to differentiate between extension builds and the core SQLite build (
SQLITE_COREandSQLITE_OMIT_LOAD_EXTENSIONmacros).Extension developers use this header to write code that calls SQLite API functions via the
sqlite3_apipointer rather than linking directly to SQLite.
Interaction with Other System Components
This header acts as the contract between SQLite core and extension modules.
Extensions implementing new SQL functions, virtual tables, collations, or loadable modules include this file to obtain access to SQLite APIs.
The SQLite core library loads shared library extensions and passes them a pointer to the
sqlite3_api_routinesstructure for API calls.The API redirection macros ensure that calls by the extension use the SQLite core's current API functions, enabling extensions to work correctly with the running SQLite version.
Usage Example
An extension source file would typically start with:
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
int sqlite3_myextension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) {
SQLITE_EXTENSION_INIT2(pApi);
// Extension initialization code here, e.g. register functions
return SQLITE_OK;
}
This ensures sqlite3_api is properly initialized to call SQLite API functions indirectly.
Mermaid Diagram: Structure of sqlite3_api_routines
classDiagram
class sqlite3_api_routines {
+aggregate_context()
+aggregate_count()
+bind_blob()
+bind_double()
+bind_int()
+bind_int64()
+bind_null()
+bind_parameter_count()
+bind_parameter_index()
+bind_parameter_name()
+bind_text()
+bind_text16()
+bind_value()
+busy_handler()
+busy_timeout()
+changes()
+close()
+collation_needed()
+column_blob()
+column_bytes()
+column_count()
+column_database_name()
+column_decltype()
+column_double()
+column_int()
+column_int64()
+column_name()
+column_origin_name()
+column_table_name()
+column_text()
+column_type()
+column_value()
+commit_hook()
+complete()
+create_collation()
+create_function()
+create_module()
+data_count()
+db_handle()
+declare_vtab()
+enable_shared_cache()
+errcode()
+errmsg()
+exec()
+finalize()
+free()
+free_table()
+get_autocommit()
+get_auxdata()
+get_table()
+interruptx()
+last_insert_rowid()
+libversion()
+libversion_number()
+malloc()
+mprintf()
+open()
+prepare()
+profile()
+progress_handler()
+realloc()
+reset()
+result_blob()
+result_double()
+result_error()
+result_int()
+result_null()
+result_text()
+rollback_hook()
+set_authorizer()
+set_auxdata()
+xsnprintf()
+step()
+table_column_metadata()
+thread_cleanup()
+total_changes()
+trace()
+transfer_bindings()
+update_hook()
+user_data()
+value_blob()
+value_bytes()
+value_double()
+value_int()
+value_int64()
+value_numeric_type()
+value_text()
+value_type()
+vmprintf()
+overload_function()
+prepare_v2()
+clear_bindings()
+create_module_v2()
+bind_zeroblob()
+blob_bytes()
+blob_close()
+blob_open()
+blob_read()
+blob_write()
+create_collation_v2()
+file_control()
+memory_highwater()
+memory_used()
+mutex_alloc()
+mutex_enter()
+mutex_free()
+mutex_leave()
+mutex_try()
+open_v2()
+release_memory()
+result_error_nomem()
+result_error_toobig()
+sleep()
+soft_heap_limit()
+vfs_find()
+vfs_register()
+vfs_unregister()
+xthreadsafe()
+result_zeroblob()
+result_error_code()
+test_control()
+randomness()
+context_db_handle()
+extended_result_codes()
+limit()
+next_stmt()
+sql()
+status()
+backup_finish()
+backup_init()
+backup_pagecount()
+backup_remaining()
+backup_step()
+compileoption_get()
+compileoption_used()
+create_function_v2()
+db_config()
+db_mutex()
+db_status()
+extended_errcode()
+log()
+soft_heap_limit64()
+sourceid()
+stmt_status()
+strnicmp()
+unlock_notify()
+wal_autocheckpoint()
+wal_checkpoint()
+wal_hook()
+blob_reopen()
+vtab_config()
+vtab_on_conflict()
+close_v2()
+db_filename()
+db_readonly()
+db_release_memory()
+errstr()
+stmt_busy()
+stmt_readonly()
+stricmp()
+uri_boolean()
+uri_int64()
+uri_parameter()
+xvsnprintf()
+wal_checkpoint_v2()
+auto_extension()
+bind_blob64()
+bind_text64()
+cancel_auto_extension()
+load_extension()
+malloc64()
+msize()
+realloc64()
+reset_auto_extension()
+result_blob64()
+result_text64()
+strglob()
+value_dup()
+value_free()
+result_zeroblob64()
+bind_zeroblob64()
+value_subtype()
+result_subtype()
+status64()
+strlike()
+db_cacheflush()
+system_errno()
+trace_v2()
+expanded_sql()
+set_last_insert_rowid()
+prepare_v3()
+bind_pointer()
+result_pointer()
+value_pointer()
+vtab_nochange()
+value_nochange()
+vtab_collation()
+keyword_count()
+keyword_name()
+keyword_check()
+str_new()
+str_finish()
+str_appendf()
+str_vappendf()
+str_append()
+str_appendall()
+str_appendchar()
+str_reset()
+str_errcode()
+str_length()
+str_value()
+create_window_function()
+normalized_sql()
+stmt_isexplain()
+value_frombind()
+drop_modules()
+hard_heap_limit64()
+uri_key()
+filename_database()
+filename_journal()
+filename_wal()
+create_filename()
+free_filename()
+database_file_object()
+txn_state()
+changes64()
+total_changes64()
+autovacuum_pages()
+error_offset()
+vtab_rhs_value()
+vtab_distinct()
+vtab_in()
+vtab_in_first()
+vtab_in_next()
+deserialize()
+serialize()
+db_name()
+value_encoding()
+is_interrupted()
+stmt_explain()
+get_clientdata()
+set_clientdata()
+setlk_timeout()
}
This diagram illustrates the extensive list of SQLite API functions accessible via the sqlite3_api_routines structure, which is central to extension development and interaction with the SQLite core.