利用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/includeg++ -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)