You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DuckDB C/C++自定义函数返回STRUCT类型报错求助

解决DuckDB自定义返回STRUCT类型标量函数的问题

问题重现

尝试定义接收int参数、返回自定义STRUCT类型的DuckDB标量函数时,遇到两个问题:

  1. 调用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...)) {
  1. 将返回类型改为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);
}

错误原因

  1. 不能直接使用C++原生struct作为UDF返回类型:DuckDB的UDF系统无法直接映射自定义C++结构体,必须用DuckDB提供的Value类型封装结构化数据。
  2. STRUCT类型定义不完整:仅使用LogicalType::STRUCT未指定STRUCT的子字段信息,DuckDB无法识别具体结构,必须明确字段名和对应类型。
  3. 函数模板参数不匹配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:28:18