duckdb/duckdb
Extensions (user-facing)
What extensions look like from the SQL side, and the lifecycle the engine runs them through. The set of in-tree extensions is documented in extensions/index. The mechanics that this page describes live in systems/main.
Lifecycle
INSTALL parquet; -- download (or copy) into ~/.duckdb/extensions
LOAD parquet; -- activate in this sessiongraph LR
Install[INSTALL ext] -->|HTTP / local| Cache[Local extension cache]
Cache -->|LOAD ext| Loader[ExtensionLoader]
Loader -->|dlopen / static| Init[ext_init]
Init -->|register| Functions[Scalar / Aggregate / Table / Window / Pragma]
Init -->|register| Types[LogicalType + casts]
Init -->|register| FS[FileSystem]
Init -->|register| Replace[Replacement scans]
Init -->|register| Storage[StorageExtension]
Init -->|register| Opts[Settings + callbacks]Where extensions live
- In-tree.
extension/in this repo. Linked statically by default; in default builds these are always available withoutINSTALL/LOAD. - Out-of-tree. Separate repos. Listed in
.github/config/out_of_tree_extensions.cmake. Downloadable from the DuckDB extension repository at https://extensions.duckdb.org.
A list of installed and loaded extensions is available via SELECT * FROM duckdb_extensions().
Auto-loading
PRAGMA autoload_known_extensions = true (the default) lets DuckDB look up unknown SQL identifiers and table names against a list of known extensions, then auto-install and auto-load the matching extension. The known list is generated by scripts/generate_extensions_function.py.
For example, the first time you run SELECT * FROM 's3://bucket/file.parquet', the engine notices that s3:// is not handled by any active file system, looks it up in the known list (it maps to the httpfs extension), installs and loads httpfs, and re-runs the query.
Signing
Production extensions are signed. PRAGMA allow_unsigned_extensions = true permits loading unsigned extensions for development. Signing keys and verification live in src/main/extension_install_info.cpp and friends; the build pipeline that signs official binaries is .github/workflows/_manual_extension_deploy.yml and StagedUpload.yml.
What an extension can register
| Surface | Implementation |
|---|---|
| Scalar / aggregate / table / window / pragma functions | Through BuiltinFunctions / Catalog::CreateFunction (see systems/function) |
Custom LogicalTypes and casts |
Catalog::AddCast, LogicalType::SetAlias |
| Replacement scans | DBConfig::replacement_scans |
| File systems | VirtualFileSystem::RegisterSubSystem |
| Storage extensions (alternative catalogs/transactions) | StorageExtension interface |
| Settings | DBConfig::AddExtensionOption |
| Optimizer rules | DBConfig::optimizer_extensions |
| Compression codecs | DBConfig::compression_functions |
| Profiling extensions | DBConfig::register_extension_callbacks |
| Logger types | LogManager::RegisterLogStorage |
ExtensionLoader (src/main/extension.cpp) is the central point.
Replacement scans
A replacement scan turns an unrecognized table name (typically a file path) into a table function call. The parquet extension registers a replacement scan for *.parquet so that:
SELECT * FROM 'data.parquet';is rewritten as:
SELECT * FROM parquet_scan('data.parquet');Implementation: parquet_extension.cpp calls DBConfig::AddReplacementScan at load. The engine consults registered scans in order until one matches.
Secrets
CREATE SECRET registers a named credential that storage extensions can consult:
CREATE SECRET aws_creds (TYPE S3, KEY_ID '...', SECRET '...');Secrets are persisted (when persistent) under ~/.duckdb/stored_secrets/. Implementation: src/main/secret/ and the SecretManager. Storage extensions like httpfs and aws consult the secret manager during request signing.
Building your own extension
The canonical reference is extension/README.md. The shortest path:
- Use the extension-template repo, which sets up CMake and the right C ABI shim.
- Implement an
Extensionsubclass with aLoad(DatabaseInstance &)method. - Register your functions/types from
Load. - Build with the matching DuckDB version's headers.
- Sign with
scripts/extension-upload-single.shfor distribution.
In-tree extensions in this repo are useful examples (extension/parquet/, extension/json/).
Where to look
- Mechanism: systems/main,
src/main/extension.cpp,src/main/extension_manager.cpp,src/main/extension_callback_manager.cpp. - In-tree library: extensions.
- Out-of-tree integration:
.github/config/out_of_tree_extensions.cmake,scripts/sync_out_of_tree_extensions.py. - Tests:
test/extension/, plus per-extension tests inextension/<name>/tests/or upstream repos.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.