This should work if you clone and modify the package to add the c api support.
add scalar api to DuckDB.jl package
# ctypes.jl
const duckdb_scalar_function = Ptr{Cvoid}
# api.jl scalar functions
function duckdb_create_scalar_function()
return ccall((:duckdb_create_scalar_function, libduckdb), duckdb_scalar_function, ())
end
function duckdb_destroy_scalar_function(func)
return ccall((:duckdb_destroy_scalar_function, libduckdb), Cvoid, (Ref{duckdb_scalar_function},), func)
end
function duckdb_scalar_function_set_name(func, name)
return ccall((:duckdb_scalar_function_set_name, libduckdb), Cvoid, (duckdb_scalar_function, Ptr{UInt8}), func, name)
end
function duckdb_scalar_function_add_parameter(func, type)
return ccall(
(:duckdb_scalar_function_add_parameter, libduckdb),
Cvoid,
(duckdb_scalar_function, duckdb_logical_type),
func,
type
)
end
function duckdb_scalar_function_set_return_type(func, type)
return ccall(
(:duckdb_scalar_function_set_return_type, libduckdb),
Cvoid,
(duckdb_scalar_function, duckdb_logical_type),
func,
type
)
end
function duckdb_scalar_function_set_function(scalar_func, func)
return ccall(
(:duckdb_scalar_function_set_function, libduckdb),
Cvoid,
(duckdb_scalar_function, Ptr{Cvoid}),
scalar_func,
func
)
end
function duckdb_register_scalar_function(con, func)
return ccall(
(:duckdb_register_scalar_function, libduckdb),
Int32,
(duckdb_connection, duckdb_scalar_function),
con,
func
)
end
MyAddition example
using DuckDB
function MyAddition(info::DuckDB.duckdb_function_info, input::DuckDB.duckdb_data_chunk, output::DuckDB.duckdb_vector)
input = DuckDB.DataChunk(input, false)
n = DuckDB.get_size(input)
a_data = DuckDB.get_array(DuckDB.get_vector(input, 1), Int64, n)
b_data = DuckDB.get_array(DuckDB.get_vector(input, 2), Int64, n)
output_data = DuckDB.get_array(DuckDB.Vec(output), Int64, n)
for row in 1:n
output_data[row] = a_data[row] + b_data[row]
end
end
db = DuckDB.DB()
con = DuckDB.connect(db)
# create a scalar function
f = DuckDB.duckdb_create_scalar_function()
DuckDB.duckdb_scalar_function_set_name(f, "my_addition")
# add two bigint parameters
type = DuckDB.duckdb_create_logical_type(DuckDB.DUCKDB_TYPE_BIGINT)
DuckDB.duckdb_table_function_add_parameter(f, type)
DuckDB.duckdb_table_function_add_parameter(f, type)
# set the return type to bigint
DuckDB.duckdb_scalar_function_set_return_type(f, type)
DuckDB.duckdb_destroy_logical_type(type)
# set up the function
CMyAddition = @cfunction(MyAddition, Cvoid, (DuckDB.duckdb_function_info, DuckDB.duckdb_data_chunk, DuckDB.duckdb_vector))
DuckDB.duckdb_scalar_function_set_function(f, CMyAddition)
# register and cleanup
DuckDB.duckdb_register_scalar_function(con.handle, f)
DuckDB.duckdb_destroy_scalar_function(f)
DuckDB.query(con, "CREATE TABLE big_table AS SELECT i FROM range(9) t(i)")
DuckDB.query(con, "SELECT my_addition(i, i) FROM big_table")