[Julia] Improves Julia support for scalar UDFs #15430
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR improves the Julia support for user defined UDFs.
It adds the
ScalarFunction
type and the@create_scalar_function
macro that automatically generates a DuckDB compatible wrapper. See also discussion #13176 for details.Numeric types, dates, strings, missing values and exceptions are supported. Composite types are not yet implemented.
Example Usage:
Performance
The performance of the auto-generated wrapper is comparable to pure DuckDB/Julia. I measured the elapsed time (in seconds) of adding 10 million numbers in a coarse benchmark:
Internals
The scalar functions are tracked in a dictionary in the DuckDBHandle struct. Currently only registering scalar function is supported.
The wrapper is generated via the macro and should be fully type stable. The wrapper is generated via the function
_udf_generate_wrapper()
.Because of limitations of the
@cfunction
macro in Julia, the wrapper needs to be globally accessible. I implemented this by introducing a global (constant) dictionary variable in DuckDB_UDF_WRAPPER_CACHE
which is used to store the generated wrappers. This is defined in_udf_register_wrapper()
. This is, in my opinion not ideal but works. I asked in Julia related forums for a better solution and will update the code, if something better is possible.This is an update to PR #14024