利用DeepSeek辅助给duckdb_pgwire插件添加psql终端输出int128功能

给pgwire的头文件write.hpp添加类成员函数声明

class RowWriter {
    void write_int16(__int128_t v);//add

给pgwire的实现文件write.cpp添加类成员函数定义

void RowWriter::write_int16(__int128_t v) { //add
    _current_col++;
    
    if (_writer._format_code == FormatCode::Text) {
        char buf[256];
        char *p = buf + 256;
        *--p = '\0';
        
        bool negative = false;
        __int128_t n = v;
        
        if (n < 0) {
            negative = true;
            n = -n;
        }
        
        do {
            *--p = '0' + (n % 10);
            n /= 10;
        } while (n != 0);
        
        if (negative) {
            *--p = '-';
        }
        
        int len = buf + 256 - p - 1;
        _row.put_numeric<int32_t>(len);
        _row.put_bytes(reinterpret_cast<Byte const *>(p), len);
    } else {
        // Binary 格式
        _row.put_numeric<int32_t>(sizeof(__int128_t));
        _row.put_numeric<__int128_t>(v);
    }
}

给duckdb_pgwire_extension.cpp添加两处
一处是在g_typemap中添加一行:

static std::unordered_map<LogicalTypeId, pgwire::Oid> g_typemap = {
    {LogicalTypeId::FLOAT, pgwire::Oid::Float4},
    {LogicalTypeId::DOUBLE, pgwire::Oid::Float8},
    // {LogicalTypeId::TINYINT, pgwire::Oid::Char},
    {LogicalTypeId::SMALLINT, pgwire::Oid::Int2},
    {LogicalTypeId::INTEGER, pgwire::Oid::Int4},
    {LogicalTypeId::BIGINT, pgwire::Oid::Int8},
    {LogicalTypeId::HUGEINT, pgwire::Oid::Int8}, //add

另一处是在static pgwire::ParseHandler duckdb_handler(DatabaseInstance &db) 函数中添加:

                    case LogicalTypeId::HUGEINT:
                        //row.write_int16(dynamic_cast<__int128_t>(chunk.GetValue<hugeint_t>(i)));
                        row.write_int16(static_cast<__int128_t>(chunk.GetValue<hugeint_t>(i).upper) << 64 | 
                static_cast<__int128_t>(chunk.GetValue<hugeint_t>(i).lower));

注意直接用dynamic_cast或其他cast行不通,因为hugeint_t在duckdb中的定义如下,所以需要取出hugeint_t成员来计算__int128_t。
以上write_int16函数和成员计算是DeepSeek辅助完成的。

struct uhugeint_t { // NOLINT
public:
	uint64_t lower;
	uint64_t upper;

public:
	uhugeint_t() = default;
	DUCKDB_API uhugeint_t(uint64_t value); // NOLINT: Allow implicit conversion from `uint64_t`
	constexpr uhugeint_t(uint64_t upper, uint64_t lower) : lower(lower), upper(upper) {
	}
...	

重新编译libpgwire.so和libtest2.so两个动态库,设置环境变量装载插件,

cd /par/duckdb-pgwire-main/src
g++ -fPIC -shared -o libpgwire.so ../pgwire/src/pgwire/*.cpp -I /par/extension-template/duckdb/src/include -I include -I ../pgwire/include  -I ../pgwire/third_party/promise-cpp/include -I ../pgwire/third_party/asio/asio/include  -I ../pgwire/third_party/endian/src -I ../pgwire/third_party/function2/include

g++ -fPIC -shared -o c duckdb_pgwire_extension.cpp -I /par/extension-template/duckdb/src/include -I include -I ../pgwire/include  -I ../pgwire/third_party/promise-cpp/include -I ../pgwire/third_party/asio/asio/include  -I ../pgwire/third_party/endian/src -I ../pgwire/third_party/function2/include -lduckdb -L /par/libduckdb -lpgwire -L .

python3 /par/appendmetadata.py -l libtest2.so -n duckdb_pgwire -dv v1.4.0  --duckdb-platform linux_amd64 --extension-version 0.1 --abi-type ""
export LD_LIBRARY_PATH=/par/libduckdb:/par/duckdb-pgwire-main/src
/par/duckdb140 -unsigned
DuckDB v1.4.0 (Andium) b8a06e4a22
Enter ".help" for usage hints.
D load '/par/duckdb-pgwire-main/src/duckdb_pgwire.duckdb_extension';

在psql中如下输出int128类型的查询都能正确显示了。

main=> select 1::int128;
 CAST(1 AS HUGEINT)
--------------------
                  1
(1 row)

main=>  select sum(i) from range(1,10000001)t(i);
     sum(i)
----------------
 50000005000000
(1 row)


main=> select 50000005000000::int128*50000005000000::int128;
 (CAST(50000005000000 AS HUGEINT) * CAST(50000005000000 AS HUGEINT))
---------------------------------------------------------------------
                                        2500000500000025000000000000
(1 row)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值