Open-Source Wikis

/

DuckDB

/

Features

/

Extensions (user-facing)

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 session
graph 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 without INSTALL/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:

  1. Use the extension-template repo, which sets up CMake and the right C ABI shim.
  2. Implement an Extension subclass with a Load(DatabaseInstance &) method.
  3. Register your functions/types from Load.
  4. Build with the matching DuckDB version's headers.
  5. Sign with scripts/extension-upload-single.sh for 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 in extension/<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.

Extensions (user-facing) – DuckDB wiki | Factory