利用DeepSeek采用hugeint转字符串函数完善luadbi-duckdb的decimal处理

用如下函数替换原有同名函数,弥补了原函数不能处理非常大的HUGEINT值的缺陷。让DeepSeek利用已有hugeint转换的字符串,结合scale插入小数点,避免除法运算。

c 复制代码
// 将decimal数据转换为字符串
void decimal_to_string_format(uint8_t width, uint8_t scale, void* data, int type, char* buffer, size_t buffer_size) {
    if (data == NULL || buffer == NULL || buffer_size == 0) {
        return;
    }
    
    // 根据类型获取整数值
    int64_t int_value = 0;
    switch (type) {
        case DUCKDB_TYPE_TINYINT: // int8_t
            int_value = *(int8_t*)data;
            break;
        case DUCKDB_TYPE_SMALLINT: // int16_t
            int_value = *(int16_t*)data;
            break;
        case DUCKDB_TYPE_INTEGER: // int32_t
            int_value = *(int32_t*)data;
            break;
        case DUCKDB_TYPE_BIGINT: // int64_t
            int_value = *(int64_t*)data;
            break;
        case DUCKDB_TYPE_HUGEINT: // int128_t
            {
                duckdb_hugeint huge_val = *(duckdb_hugeint*)data;
        
        // 简化处理:如果upper为0,只使用lower部分
        if (huge_val.upper == 0) {
            int_value = *(int64_t*)data;
            break;

            
        } else {
            // 对于非常大的HUGEINT值,用hugeint返回的字符串
            int128_t u128a = ((int128_t)UINT64_MAX + 1) * huge_val.upper + huge_val.lower;
            char a[100];
            int128_to_string_safe(u128a, a, sizeof(a));

            if (scale == 0) {

                snprintf(buffer, buffer_size, "%s", a);
            } else {
                    size_t len = strlen(a);
    
                if (scale >= len) {
                    // 小数位数大于等于数字总长度,需要在前面补0
                    // 例如: "123" scale=5 -> "0.00123"
                    snprintf(buffer, buffer_size, "0.%0*s%s", 
                            scale - len, "0", 
                            a);
                } else {
                    // 正常情况,在合适位置插入小数点
                    // 例如: "12345" scale=2 -> "123.45"
                    size_t decimal_pos = len - scale;
        
                    // 复制整数部分
                    strncpy(buffer, a, decimal_pos);
                    // 添加小数点
                    buffer[decimal_pos] = '.';
                    // 复制小数部分
                    strncpy(buffer + decimal_pos + 1, a + decimal_pos, scale);
                    // 添加结束符
                    buffer[len + 1] = '\0';
                }
            }
            }
    }
            return;
        default:
            // 无效类型
            snprintf(buffer, buffer_size, "decimal(%d,%d,invalid_type,%d)", width, scale, type);
            return;
    }
    
    // 处理负号
    int is_negative = (int_value < 0);
    uint64_t abs_value = is_negative ? (uint64_t)(-int_value) : (uint64_t)int_value;
    
    if (scale == 0) {
        // 整数情况,直接输出
        snprintf(buffer, buffer_size, "%s%lu", is_negative ? "-" : "", abs_value);
    } else {
        // 计算10^scale
        uint64_t divisor = 1;
        for (int i = 0; i < scale; i++) {
            divisor *= 10;
        }
        
        // 分离整数部分和小数部分
        uint64_t integer_part = abs_value / divisor;
        uint64_t fractional_part = abs_value % divisor;
        
        // 构建格式字符串,确保小数部分有正确的位数(前导零)
        char format[32];
        snprintf(format, sizeof(format), "%%s%%lu.%%0%dlu", scale);
        
        // 格式化输出
        snprintf(buffer, buffer_size, format, is_negative ? "-" : "", integer_part, fractional_part);
    }
}

这样改造以后,就可以处理各种大小的decimal数据了,与duckdb的输出一致。

复制代码
root@66d4e20ec1d7:/par/luadbi# lua ../duck.lua
-15
2025-09-25 12:26:55.123456
-1234567890123456789012345
-12345678900020250922.12345
root@66d4e20ec1d7:/par/luadbi# ../duckdb141 lua_duckdb -c "from table_1"
┌───────┬────────────────────────────┬────────────────────────────┬─────────────────────────────┐
│  id   │          column1           │          column2           │           column3           │
│ int32 │         timestamp          │           int128           │        decimal(34,5)        │
├───────┼────────────────────────────┼────────────────────────────┼─────────────────────────────┤
│  -15  │ 2025-09-25 12:26:55.123456 │ -1234567890123456789012345 │ -12345678900020250922.12345 │
└───────┴────────────────────────────┴────────────────────────────┴─────────────────────────────┘

root@66d4e20ec1d7:/par/luadbi# lua ../duck.lua
-15
2025-09-25 12:26:55.123456
-1234567890123456789012345
-345.00000
root@66d4e20ec1d7:/par/luadbi# ../duckdb141 lua_duckdb -c "from table_1"
┌───────┬────────────────────────────┬────────────────────────────┬───────────────┐
│  id   │          column1           │          column2           │    column3    │
│ int32 │         timestamp          │           int128           │ decimal(34,5) │
├───────┼────────────────────────────┼────────────────────────────┼───────────────┤
│  -15  │ 2025-09-25 12:26:55.123456 │ -1234567890123456789012345 │  -345.00000   │
└───────┴────────────────────────────┴────────────────────────────┴───────────────┘

root@66d4e20ec1d7:/par/luadbi# lua ../duck.lua
-15
2025-09-25 12:26:55.123456
-1234567890123456789012345
-12345678900.03450
root@66d4e20ec1d7:/par/luadbi# ../duckdb141 lua_duckdb -c "from table_1"
┌───────┬────────────────────────────┬────────────────────────────┬────────────────────┐
│  id   │          column1           │          column2           │      column3       │
│ int32 │         timestamp          │           int128           │   decimal(34,5)    │
├───────┼────────────────────────────┼────────────────────────────┼────────────────────┤
│  -15  │ 2025-09-25 12:26:55.123456 │ -1234567890123456789012345 │ -12345678900.03450 │
└───────┴────────────────────────────┴────────────────────────────┴────────────────────┘

测试脚本如下

lua 复制代码
DBI = require "DBI"

dbd, err = DBI.Connect( 'DuckDB', 'lua_duckdb', 'dbuser', 'password' )
assert(dbd, err)

dbd:autocommit(true)
statement = dbd:prepare( "create or replace table table_1 as select -15 id, timestamp'2025-09-25 12:26:55.123456'column1, '-1234567890123456789012345'::hugeint  column2,'-12345678900.0345'::decimal(34,5) column3 ;" )
statement:execute()

statement = assert(dbd:prepare( "select * from table_1 where id = $1;" ))
statement:execute( -15 )

for row in statement:rows(true) do
         print(row['id'])
	 print(row['column1'])
	 print(row['column2'])
	 print(row['column3'])

end
相关推荐
我登哥MVP19 小时前
VS Code 安装 Claude Code 并接入 DeepSeek V4 Model
人工智能·python·node.js·agent·codex·deepseek·claude code
CAir219 小时前
copilot配置deepseek和skills
vscode·copilot·skill·deepseek
asdfg125896319 小时前
一文通俗理解JDBC中的核心概念+案例
java·数据库·oracle·jdbc
点灯小铭19 小时前
基于单片机与DAC0832的双路波形信号发生系统设计
数据库·单片机·mongodb·毕业设计·课程设计·期末大作业
小陈phd19 小时前
Text2SQL智能体学习笔记(二)——NL2SQL落地的隐形基石:元数据库
数据库·笔记·学习
霸道流氓气质19 小时前
阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南
数据库·spring boot·阿里云
茉莉玫瑰花茶19 小时前
综合案例 - AI 智能租房助手 [ 4 ]
数据库·python·ai·langgraph
ULIi096kr19 小时前
MySQL查看表创建时间、修改时间、最后更新时间(精准排查僵尸表)
数据库·mysql
折哥的程序人生 · 物流技术专研19 小时前
Tomcat 严重警告:JDBC 驱动未注销 + 工作线程泄漏 —— 原因、影响与彻底修复(生产级终极指南)
java·运维·数据库·mysql·oracle·tomcat
初圣魔门首席弟子19 小时前
Qt C++ 项目实战:修改共享头文件后的高效增量编译与快速发布流程
数据库