DuckDB Custom Function returns composite type

262 Views Asked by At

I need to define a function that returns a STRUCT data type in C/C++ given an int

I tried

struct ret{
    int N;
    int k;
};

ret func(int value){
    ret t;
    t.N=value;
    t.k = value*value;
    return t;
}

int main(){
    duckdb::DuckDB db(nullptr);
    duckdb::Connection con(db);
 
    con.CreateScalarFunction<ret, int>("function", {duckdb::LogicalType::INTEGER}, duckdb::LogicalType::STRUCT, &func);
}

but it's not working:

"error: no matching member function for call to 'CreateScalarFunction'.
duckdb.hpp:21597:7: note: candidate function template not viable: no known conversion from 'duckdb::LogicalType (child_list_t<duckdb::LogicalType>)' (aka 'duckdb::LogicalType (vector<pair<basic_string<char, char_traits<char>, allocator<char>>, duckdb::LogicalType>>)') to 'duckdb::LogicalType' for 3rd argument
        void CreateScalarFunction(const string &name, vector<LogicalType> args, LogicalType ret_type,
             ^
duckdb.hpp:21591:7: note: candidate function template not viable: requires 2 arguments, but 4 were provided
        void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) {
".

EDIT: If I replace duckdb::LogicalType::STRUCT with duckdb::LogicalTypeId::STRUCT it is still not working

libc++abi: terminating with uncaught exception of type std::runtime_error: Type is not supported!
1

There are 1 best solutions below

2
Pignotto On

As the error states, in:

con.CreateScalarFunction<ret, int>("function", {duckdb::LogicalType::INTEGER}, duckdb::LogicalType::STRUCT, &func);

The template method

template <typename TR, typename... Args> void CreateScalarFunction(const string &name, vector<LogicalType> args, LogicalType ret_type, TR (*udf_func)(Args...))

takes a duckdb::LogicalType as the 3rd argument, but duckdb::LogicalType::STRUCT is a function; in particular it is this function here:

DUCKDB_API static LogicalType STRUCT(child_list_t<LogicalType> children)

(there is no conversion between those 2 types)

It could be possible that you meant to use duckdb::LogicalTypeId::STRUCT (please note the LogiacalTypeId, which is an enum class) for which there is an implicit conversion to duckdb::LogicalType

or to call LogicalType::STRUCT with the appropriate types, which returns a LogicalType of LogicalTypeId STRUCT