Skip to content

Make extension callback registration thread-safe, and change extension callback registration APIs to enable this#20599

Merged
Mytherin merged 12 commits intoduckdb:v1.5-variegatafrom
Mytherin:threadsaferegistry
Jan 20, 2026
Merged

Make extension callback registration thread-safe, and change extension callback registration APIs to enable this#20599
Mytherin merged 12 commits intoduckdb:v1.5-variegatafrom
Mytherin:threadsaferegistry

Conversation

@Mytherin
Copy link
Collaborator

Follow-up from #20547

There are various extension callbacks that extensions can register, e.g.:

  • ParserExtension
  • StorageExtension
  • OperatorExtension
  • OptimizerExtension
  • ExtensionCallback

Currently registering these extensions is not done in a thread-safe manner. As a result, loading extensions that register these callbacks while concurrent activity is taking place in the database is not safe. This usually doesn't matter as extensions are generally loaded up-front, but long-term it would be better to just use thread-safe interfaces here.

We use the same trick as we did in #20547 for making these registrations thread-safe while limiting the impact on reading as much as possible - i.e. the cost of making this thread safe is almost entirely pushed onto the registration (which is generally rarely done - i.e. we only register a few extensions in total).

As a consequence of this, the API for registering these extensions is now different, e.g. instead of doing this:

config.storage_extensions["ducklake"] = make_uniq<DuckLakeStorageExtension>();

We now need to do this:

StorageExtension::Register(config, "ducklake", make_shared_ptr<DuckLakeStorageExtension>());

The same applies for the other types:

OptimizerExtension::Register(config, std::move(postgres_optimizer));
ExtensionCallback::Register(config, make_shared_ptr<PostgresExtensionCallback>());
ParserExtension::Register(config, QuackExtension());

Transient Includes Removal

Now that these extensions are no longer part of the DBConfig, their includes have also been removed from config.hpp. This uncovered the fact that we were transiently including a lot of stuff in the DBConfig through these extensions. Since the DBConfig is also included in a lot of places, this meant we were including a lot of files in a lot of places.

I've opted to remove these includes to limit include propagation - but this does mean that a lot of files that previously depended on these transient includes now need to actually include what they are using. Common culprits based on fixing this seem to be:

  • duckdb/planner/expression/bound_columnref_expression.hpp
  • duckdb/parser/expression/columnref_expression.hpp
  • duckdb/planner/binder.hpp
  • duckdb/catalog/catalog_search_path.hpp

@Mytherin Mytherin merged commit 18d7116 into duckdb:v1.5-variegata Jan 20, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant