当前位置: 首页 > news >正文

DeepSeek辅助整合精简的DuckDB大数运算插件

前文的插件,每个运算都需要一个函数,其中函数体大部分内容都重复,给他一个要实现的操作函数列表,连同文档起发给他,让他整合。

请把减法、除法、取模、平方、平方根等bn函数也实现,另外现在代码冗余很多,请合理地合并大部分相同代码,比如注册用同一个变量循环,调用函数时根据传入的额外参数决定调用哪个特定的bn底层函数,

他一开始给出的代码调用了不存在的duckdb函数,我把文档中存在的类似函数发给他,它自己选了一个代替就好了。

根据你提供的函数列表,应该使用以下语句代替:

// 设置操作类型作为extra_info
duckdb_scalar_function_set_extra_info(function, (void*)(uintptr_t)config.op_type, NULL);// 在函数实现中获取extra_info
bn_operation_t op_type = (bn_operation_t)(uintptr_t)duckdb_scalar_function_get_extra_info(info);

使用 duckdb_scalar_function_set_extra_infoduckdb_scalar_function_get_extra_info 来传递和获取操作类型参数。

编译成功了,但是我的openssl库中没有BN_mod函数,我看文档中说BN_mod() corresponds to BN_div() with dv set to NULL.就改成了case BN_OP_MOD:
success = BN_div(NULL, rem, a, b, ctx);但是执行结果好像不对。select bn_mod(‘1’,‘2’);
0 ,而duckdb内置函数select mod(1,2);
1 ,请修改正确,不做别的

问题在于 BN_div 的使用方式。当 dv 设置为 NULL 时,rem 参数应该接收余数结果。正确的修改如下:

case BN_OP_MOD:rem = BN_new();success = BN_div(NULL, rem, a, b, ctx);if (success) {// 将余数结果复制到result中success = BN_copy(result, rem);}if (rem) BN_free(rem);break;

这样修改后,bn_mod('1','2') 应该返回 1,与 DuckDB 内置的 mod(1,2) 结果一致。

我把代码复制粘贴到原代码,执行bn_mod总是内存错误,我又让他单独写了一个测试bn_mod的程序,没有问题。
将它与前面调用相同的BN_div函数的除法代码比较,少了一行rem = BN_new();
可笑的是,ds的代码就有rem = BN_new();,我粘贴漏了,白白浪费了很多功夫。

正确的完整代码如下

#include "duckdb_extension.h"
#include <string.h>
#include <stdlib.h>
// 声明BN函数(来自OpenSSL)
//extern "C" {typedef struct bignum_st BIGNUM;typedef struct bn_ctx_st BN_CTX;BIGNUM* BN_new();int BN_copy(BIGNUM*, const BIGNUM*);void BN_free(BIGNUM*);int BN_dec2bn(BIGNUM**, const char*);char* BN_bn2dec(const BIGNUM*);int BN_add(BIGNUM*, const BIGNUM*, const BIGNUM*);int BN_sub(BIGNUM*, const BIGNUM*, const BIGNUM*);int BN_mul(BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);int BN_div(BIGNUM*, BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);//int BN_mod(BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);int BN_sqr(BIGNUM*, const BIGNUM*, BN_CTX*);BIGNUM* BN_mod_sqrt(BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);int BN_exp(BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);int BN_mod_exp(BIGNUM*, const BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);int BN_gcd(BIGNUM*, const BIGNUM*, const BIGNUM*, BN_CTX*);BN_CTX* BN_CTX_new();void BN_CTX_free(BN_CTX*);void free(void*);
//}DUCKDB_EXTENSION_EXTERN// 支持的BN操作类型
typedef enum {BN_OP_ADD,      // 加法BN_OP_SUB,      // 减法BN_OP_MUL,      // 乘法BN_OP_DIV,      // 除法(返回商)BN_OP_MOD,      // 取模BN_OP_SQR,      // 平方BN_OP_SQRT,     // 平方根BN_OP_EXP,      // 指数BN_OP_MOD_EXP,  // 模指数BN_OP_GCD       // 最大公约数
} bn_operation_t;// 从duckdb_string_t提取C字符串
static char* extract_string(duckdb_string_t str) {char* result = NULL;if (duckdb_string_is_inlined(str)) {result = duckdb_malloc(str.value.inlined.length + 1);memcpy(result, str.value.inlined.inlined, str.value.inlined.length);result[str.value.inlined.length] = '\0';} else {result = duckdb_malloc(str.value.pointer.length + 1);memcpy(result, str.value.pointer.ptr, str.value.pointer.length);result[str.value.pointer.length] = '\0';}return result;
}// 设置duckdb_string_t为C字符串
static void set_string(duckdb_string_t* str, const char* cstr) {size_t len = strlen(cstr);if (len <= 12) { // 内联字符串最大长度str->value.inlined.length = len;memcpy(str->value.inlined.inlined, cstr, len);str->value.inlined.inlined[len] = '\0';} else {char* ptr = duckdb_malloc(len + 1);memcpy(ptr, cstr, len);ptr[len] = '\0';str->value.pointer.ptr = ptr;str->value.pointer.length = len;}
}// 通用的BN操作函数
static void BNGenericFunction(duckdb_function_info info, duckdb_data_chunk input, duckdb_vector output) {//bn_operation_t op_type = (bn_operation_t)duckdb_function_info_get_bind_data(info);// 在函数实现中获取extra_infobn_operation_t op_type = (bn_operation_t)(uintptr_t)duckdb_scalar_function_get_extra_info(info);idx_t input_size = duckdb_data_chunk_get_size(input);duckdb_vector a_vec = duckdb_data_chunk_get_vector(input, 0);duckdb_string_t* a_data = (duckdb_string_t*)duckdb_vector_get_data(a_vec);duckdb_string_t* result_data = (duckdb_string_t*)duckdb_vector_get_data(output);// 获取有效性位图uint64_t* a_validity = duckdb_vector_get_validity(a_vec);uint64_t* b_validity = NULL;uint64_t* c_validity = NULL;duckdb_string_t* b_data = NULL;duckdb_string_t* c_data = NULL;// 根据操作类型获取不同的输入向量if (op_type != BN_OP_SQR && op_type != BN_OP_SQRT) {duckdb_vector b_vec = duckdb_data_chunk_get_vector(input, 1);b_data = (duckdb_string_t*)duckdb_vector_get_data(b_vec);b_validity = duckdb_vector_get_validity(b_vec);}if (op_type == BN_OP_MOD_EXP) {duckdb_vector c_vec = duckdb_data_chunk_get_vector(input, 2);c_data = (duckdb_string_t*)duckdb_vector_get_data(c_vec);c_validity = duckdb_vector_get_validity(c_vec);}BN_CTX* ctx = BN_CTX_new();if (!ctx) return;for (idx_t row = 0; row < input_size; row++) {// 检查NULL值bool has_null = (a_validity && !duckdb_validity_row_is_valid(a_validity, row)) ||(b_validity && !duckdb_validity_row_is_valid(b_validity, row)) ||(c_validity && !duckdb_validity_row_is_valid(c_validity, row));if (has_null) {duckdb_vector_ensure_validity_writable(output);uint64_t* result_validity = duckdb_vector_get_validity(output);duckdb_validity_set_row_invalid(result_validity, row);continue;}BIGNUM* a = BN_new();BIGNUM* b = NULL;BIGNUM* c = NULL;BIGNUM* result = BN_new();BIGNUM* rem = NULL;char* a_str = NULL;char* b_str = NULL;char* c_str = NULL;char* res_str = NULL;int success = 0;if (!a || !result) {goto cleanup;}// 提取输入字符串a_str = extract_string(a_data[row]);if (b_data) {b_str = extract_string(b_data[row]);b = BN_new();if (!b) goto cleanup;}if (c_data) {c_str = extract_string(c_data[row]);c = BN_new();if (!c) goto cleanup;}// 将字符串转换为大数if (!BN_dec2bn(&a, a_str) || (b && !BN_dec2bn(&b, b_str)) || (c && !BN_dec2bn(&c, c_str))) {goto cleanup;}// 根据操作类型执行相应的BN函数switch (op_type) {case BN_OP_ADD:success = BN_add(result, a, b);break;case BN_OP_SUB:success = BN_sub(result, a, b);break;case BN_OP_MUL:success = BN_mul(result, a, b, ctx);break;case BN_OP_DIV:rem = BN_new();success = BN_div(result, rem, a, b, ctx);if (rem) BN_free(rem);break;case BN_OP_MOD:rem = BN_new();success = BN_div(NULL , rem, a, b, ctx);//BN_mod(result, a, b, ctx);if (success) {// 将余数结果复制到result中success = BN_copy(result, rem);}if (rem) BN_free(rem);break;case BN_OP_SQR:success = BN_sqr(result, a, ctx);break;case BN_OP_SQRT:{BIGNUM* sqrt_result = BN_mod_sqrt(result, a, b, ctx);success = (sqrt_result != NULL);}break;case BN_OP_EXP:success = BN_exp(result, a, b, ctx);break;case BN_OP_MOD_EXP:success = BN_mod_exp(result, a, b, c, ctx);break;case BN_OP_GCD:success = BN_gcd(result, a, b, ctx);break;default:success = 0;break;}if (!success) {goto cleanup;}// 将结果转换为字符串res_str = BN_bn2dec(result);if (res_str) {set_string(&result_data[row], res_str);free(res_str);}cleanup:if (a_str) duckdb_free(a_str);if (b_str) duckdb_free(b_str);if (c_str) duckdb_free(c_str);if (a) BN_free(a);if (b) BN_free(b);if (c) BN_free(c);if (result) BN_free(result);}BN_CTX_free(ctx);
}// 函数配置信息
typedef struct {const char* name;bn_operation_t op_type;int num_params;
} bn_function_config;static bn_function_config bn_functions[] = {{"bn_add", BN_OP_ADD, 2},{"bn_sub", BN_OP_SUB, 2},{"bn_mul", BN_OP_MUL, 2},{"bn_div", BN_OP_DIV, 2},{"bn_mod", BN_OP_MOD, 2},{"bn_sqr", BN_OP_SQR, 1},{"bn_sqrt", BN_OP_SQRT, 2},{"bn_exp", BN_OP_EXP, 2},{"bn_mod_exp", BN_OP_MOD_EXP, 3},{"bn_gcd", BN_OP_GCD, 2}
};// 注册所有BN函数
void RegisterBNFunctions(duckdb_connection connection) {duckdb_logical_type varchar_type = duckdb_create_logical_type(DUCKDB_TYPE_VARCHAR);for (size_t i = 0; i < sizeof(bn_functions) / sizeof(bn_functions[0]); i++) {bn_function_config config = bn_functions[i];duckdb_scalar_function function = duckdb_create_scalar_function();duckdb_scalar_function_set_name(function, config.name);// 添加参数for (int j = 0; j < config.num_params; j++) {duckdb_scalar_function_add_parameter(function, varchar_type);}// 设置返回类型duckdb_scalar_function_set_return_type(function, varchar_type);// 设置操作类型作为bind_data// duckdb_function_info info = duckdb_scalar_function_get_function_info(function);// duckdb_function_info_set_bind_data(info, (void*)(uintptr_t)config.op_type);// 设置操作类型作为extra_infoduckdb_scalar_function_set_extra_info(function, (void*)(uintptr_t)config.op_type, NULL);        // 设置函数实现duckdb_scalar_function_set_function(function, BNGenericFunction);// 注册函数duckdb_register_scalar_function(connection, function);duckdb_destroy_scalar_function(&function);}duckdb_destroy_logical_type(&varchar_type);
}

编译运行成功。

/par/cext# gcc -fPIC -shared -o libtest2.so *.c -I . -lssl -lcrypto
/par/cext# python3 ./appmeta.py -l libtest2.so -n add -dv v1.2.0  --duckdb-platform linux_arm64 --extension-version 0.1
Creating extension binary:- Input file: libtest2.so- Output file: add.duckdb_extension/par/cext# /par/duckdb140 -unsigned
DuckDB v1.4.0 (Andium) b8a06e4a22
Enter ".help" for usage hints.
D load '/par/cext/add.duckdb_extension';
D select bn_mod('256','7');
┌────────────────────┐
│ bn_mod('256', '7') │
│      varchar       │
├────────────────────┤
│ 4                  │
└────────────────────┘
http://www.dtcms.com/a/398457.html

相关文章:

  • InnoDB Undo Log机制全解析
  • K8s学习笔记(三) kubectl 常用命令
  • 第二章:Java到Go的思维转变
  • EFR32MG21模组(Zigbee)与STM32单片机通信
  • 部署的git仓库地址变更后更改新地址
  • 加强部门网站建设wordpress验证码失效
  • 昆山做网站的jofuns商务网站开发课程体会
  • PyTorch 神经网络模型构建与训练笔记(2)
  • 某旅游学院网络安全项目:构建高效监控集中管理与巡检系统
  • 【开题答辩全过程】以 J2EE应用于母婴健康管理系统的开发与实施为例,包含答辩的问题和答案
  • 网站设计与制作公司中铁中基建设集团网站
  • 怎么样自己做百度网站做网站什么主题好做
  • es的java调用
  • Jenkins运维之路(初次调试共享库)
  • 离线下载npm包
  • 【UE5.6.1】UE5初学者教程学习笔记:编辑器操作 (1-7集)
  • 伊春seo公司seo网站页面诊断
  • Spring依赖注入:@Resource与@Autowired详解及避免空指针的最佳实践
  • 52Hz——FreeRTOS学习笔记——延时函数
  • 阿里巴巴做网站教程免费网站模板下载大全下载
  • 贪心算法之分数背包问题
  • LLMs之AgentDevP:FastGPT的简介、安装和使用方法、案例应用之详细攻略
  • 贪心算法之船舶装载问题
  • 面试_常见大厂面试题
  • 网站地图怎么建设wordpress文章页样式修改
  • 网站如何做交互热门seo推广排名稳定
  • 【第29话:路径规划】自动驾驶启发式搜索算法(A星搜索算法( A* 搜索算法))详解及代码举例说明
  • React学习教程,从入门到精通,React Router 语法知识点及使用方法详解(28)
  • Docker Compose 从入门到实践
  • D3.js 与数据可视化