DuckDB C/C++自定义函数返回STRUCT类型报错求助
解决DuckDB自定义返回STRUCT类型标量函数的问题
问题重现
尝试定义接收int参数、返回自定义STRUCT类型的DuckDB标量函数时,遇到两个问题:
- 调用
CreateScalarFunction出现函数匹配错误,报错信息:
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...)) {
- 将返回类型改为
duckdb::LogicalTypeId::STRUCT后,运行时抛出异常:
libc++abi: terminating with uncaught exception of type std::runtime_error: Type is not supported!
原尝试代码:
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); }
错误原因
- 不能直接使用C++原生struct作为UDF返回类型:DuckDB的UDF系统无法直接映射自定义C++结构体,必须用DuckDB提供的
Value类型封装结构化数据。 - STRUCT类型定义不完整:仅使用
LogicalType::STRUCT未指定STRUCT的子字段信息,DuckDB无法识别具体结构,必须明确字段名和对应类型。 - 函数模板参数不匹配:
CreateScalarFunction的模板参数需对应DuckDB支持的类型,而非自定义结构体。
修复后的代码
#include "duckdb.hpp" using namespace duckdb; // 返回值用DuckDB的Value封装STRUCT数据 Value func(int value) { // 构造STRUCT的子字段值 vector<Value> struct_values; struct_values.emplace_back(value); struct_values.emplace_back(value * value); // 定义STRUCT的字段结构(字段名+数据类型) child_list_t<LogicalType> struct_fields = { {"N", LogicalType::INTEGER}, {"k", LogicalType::INTEGER} }; // 构建STRUCT类型的Value并返回 return Value::STRUCT(struct_values, struct_fields); } int main() { DuckDB db(nullptr); Connection con(db); // 构造完整的STRUCT逻辑类型 child_list_t<LogicalType> struct_fields = { {"N", LogicalType::INTEGER}, {"k", LogicalType::INTEGER} }; LogicalType struct_type = LogicalType::STRUCT(struct_fields); // 创建标量函数,模板参数对应返回值类型(Value)和参数类型(int) con.CreateScalarFunction<Value, int>("my_struct_func", {LogicalType::INTEGER}, struct_type, &func); // 测试调用 auto result = con.Query("SELECT my_struct_func(5)"); if (result) { result->Print(); } return 0; }
关键说明
- 用
Value封装结构化数据:DuckDB的Value类型可表示所有支持的数据类型,通过Value::STRUCT方法将字段值和结构定义组合成STRUCT类型的Value。 - 明确STRUCT字段定义:必须通过
child_list_t<LogicalType>定义STRUCT的每个字段名称和数据类型,再以此构建完整的LogicalType::STRUCT类型。 - 匹配模板参数:
CreateScalarFunction的模板参数顺序为[返回值类型, 参数类型1, 参数类型2,...],这里返回值是Value,参数是int,与函数签名一致。
内容的提问来源于stack exchange,提问作者massimo
相关产品推荐
相关产品推荐

