编译步骤
到https://github.com/euiko/duckdb-pgwire 下载源代码包,并进入pgwire @ 3055550目录下载它和其它第三方组件源代码包, 注意第三方组件的目录务必和存储库保持一致。
将所有源代码解压到/par/duckdb-pgwire-main及相应目录下,先按照https://github.com/euiko/pgwire 提示单独编译测试pgwire组件,
cpp
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire# cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE -B build -DCMAKE_BUILD_TYPE=Release .
-- The C compiler identification is GNU 14.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Could NOT find QT (missing: QT_DIR)
CMake Warning (dev) at third_party/promise-cpp/CMakeLists.txt:44 (find_package):
Policy CMP0084 is not set: The FindQt module does not exist for
find_package(). Run "cmake --help-policy CMP0084" for policy details. Use
the cmake_policy command to set the policy and suppress this warning.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Could NOT find Qt3 (missing: QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE)
CMake was unable to find desired Qt version: 3. Set advanced values QT_QMAKE_EXECUTABLE and QT3_QGLOBAL_H_FILE.
CMake Warning at third_party/promise-cpp/CMakeLists.txt:46 (message):
QT not found, so project qt_timer will not be compiled
-- Configuring done
-- Generating done
-- Build files have been written to: /par/duckdb-pgwire-main/pgwire/build
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire# cd build
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build# ls
CMakeCache.txt DartConfiguration.tcl Testing compile_commands.json test
CMakeFiles Makefile cmake_install.cmake src third_party
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build# make
[ 1%] Building CXX object third_party/promise-cpp/CMakeFiles/promise.dir/src/promise.cpp.o
[ 2%] Linking CXX static library libpromise.a
[ 2%] Built target promise
[ 3%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/buffer.cpp.o
[ 4%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/exception.cpp.o
[ 4%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/io.cpp.o
[ 3%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/log.cpp.o
[ 4%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/protocol.cpp.o
[ 5%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/server.cpp.o
[ 6%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/session.cpp.o
[ 6%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/types.cpp.o
[ 7%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/utils.cpp.o
[ 8%] Building CXX object src/pgwire/CMakeFiles/pgwire.dir/writer.cpp.o
[ 9%] Linking CXX static library libpgwire.a
make[2]: warning: Clock skew detected. Your build may be incomplete.
[ 11%] Built target pgwire
[ 12%] Building CXX object src/demo/CMakeFiles/pgwire-demo.dir/main.cpp.o
[ 12%] Linking CXX executable pgwire-demo
[ 12%] Built target pgwire-demo
[ 12%] Building CXX object third_party/catch2/src/CMakeFiles/Catch2.dir/catch2/benchmark/catch_chronometer.cpp.o
...
[ 95%] Building CXX object third_party/catch2/src/CMakeFiles/Catch2.dir/catch2/matchers/catch_matchers_templated.cpp.o
[ 96%] Building CXX object third_party/catch2/src/CMakeFiles/Catch2.dir/catch2/matchers/internal/catch_matchers_impl.cpp.o
[ 96%] Linking CXX static library libCatch2.a
[ 96%] Built target Catch2
[ 97%] Building CXX object third_party/catch2/src/CMakeFiles/Catch2WithMain.dir/catch2/internal/catch_main.cpp.o
[ 98%] Linking CXX static library libCatch2Main.a
[ 98%] Built target Catch2WithMain
[ 99%] Building CXX object test/CMakeFiles/pgwire-test.dir/utils.cpp.o
[100%] Linking CXX executable pgwire-test
[100%] Built target pgwire-test
编译完成后执行测试,这个演示程序允许指定IP和端口,默认是127.0.0.1:15432
cpp
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build# cd test
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build/test# ./pgwire-test
Randomness seeded to: 773044056
===============================================================================
All tests passed (3 assertions in 1 test case)
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build/test#
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build/test# cd ..
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire/build# cd ..
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire# ./build/src/demo/pgwire-demo --help
pgwire-demo is a demo program to showcase the usage of pgwire library
Usage: ./build/src/demo/pgwire-demo [OPTIONS]
Available options:
--host (-H) Host to listen on (default: 127.0.0.1)
--port (-P) Port to listen on (default: 15432)
--help (-h) To show this usage
root@6ae32a5ffcde:/par/duckdb-pgwire-main/pgwire# ./build/src/demo/pgwire-demo
2025-10-02T02:44:27+00:00 [INFO] Starting server on 127.0.0.1:15432
2025-10-02T02:45:13+00:00 [INFO] [session #1] started
2025-10-02T02:45:13+00:00 [INFO] [session #1] [query #1] executing query "SELECT * FROM dummy_query"
2025-10-02T02:45:13+00:00 [INFO] [session #1] [query #1] query done, elapsed = 0.61ms
2025-10-02T02:45:20+00:00 [INFO] [session #1] done
另开一个终端,输入命令行,可返回结果,并且服务端有相应提示
cpp
root@6ae32a5ffcde:/# psql 'postgresql://localhost:15432/main' -c 'SELECT * FROM dummy_query'
name | address | age
----------+-----------+------
kharista | indonesia | 1
kharista | indonesia | 2
kharista | indonesia | 3
kharista | indonesia | 4
kharista | indonesia | 5
kharista | indonesia | 6
kharista | indonesia | 7
kharista | indonesia | 8
可见pgwire组件工作正常。
接下来编译duckdb_pgwire插件,先将各个组件的头文件目录全都加入查找路径,才能让g++识别。
cpp
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# g++ -fPIC -shared -o libtest2.so 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 -lduckdb -L /par/libduckdb
In file included from ../pgwire/include/pgwire/server.hpp:3,
from duckdb_pgwire_extension.cpp:17:
../pgwire/include/pgwire/session.hpp:11:10: fatal error: function2/function2.hpp: No such file or directory
11 | #include <function2/function2.hpp>
| ^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# g++ -fPIC -shared -o libtest2.so 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
In file included from duckdb_pgwire_extension.cpp:5:
include/duckdb_pgwire_extension.hpp:9:10: error: 'void duckdb::DuckdbPgwireExtension::Load(duckdb::DuckDB&)' marked 'override', but does not override
9 | void Load(DuckDB &db) override;
| ^~~~
In file included from duckdb_pgwire_extension.cpp:10:
/par/extension-template/duckdb/src/include/duckdb/main/extension_util.hpp:7:15: error: static assertion failed: The DuckDB 'ExtensionUtil' class has been removed, see this PR for more details: https://github.com/duckdb/duckdb/pull/17772
7 | static_assert(false, "The DuckDB 'ExtensionUtil' class has been removed, see this PR for more details: "
| ^~~~~
duckdb_pgwire_extension.cpp: In function 'void duckdb::LoadInternal(DatabaseInstance&)':
duckdb_pgwire_extension.cpp:208:5: error: 'ExtensionUtil' has not been declared
208 | ExtensionUtil::RegisterFunction(instance,
| ^~~~~~~~~~~~~
duckdb_pgwire_extension.cpp:212:5: error: 'ExtensionUtil' has not been declared
212 | ExtensionUtil::RegisterFunction(instance, duckdb_pgwire_scalar_function);
| ^~~~~~~~~~~~~
duckdb_pgwire_extension.cpp: In function 'void duckdb_pgwire_init(duckdb::DatabaseInstance&)':
duckdb_pgwire_extension.cpp:226:16: error: 'class duckdb::DuckDB' has no member named 'LoadExtension'; did you mean 'LoadStaticExtension'?
226 | db_wrapper.LoadExtension<duckdb::DuckdbPgwireExtension>();
| ^~~~~~~~~~~~~
| LoadStaticExtension
duckdb_pgwire_extension.cpp:226:59: error: expected primary-expression before '>' token
226 | db_wrapper.LoadExtension<duckdb::DuckdbPgwireExtension>();
| ^
duckdb_pgwire_extension.cpp:226:61: error: expected primary-expression before ')' token
226 | db_wrapper.LoadExtension<duckdb::DuckdbPgwireExtension>();
| ^
因为duckdb_pgwire插件基于旧版DuckDB设计,很多函数在1.4版中都找不到了,需要对源代码修改。我参考1.4版的quack_extension修改duckdb_pgwire_extension.cpp如下
cpp
#include "duckdb/common/types.hpp"
#include <unordered_map>
#define DUCKDB_EXTENSION_MAIN
#include <duckdb_pgwire_extension.hpp>
#include <duckdb/common/exception.hpp>
#include <duckdb/common/string_util.hpp>
#include <duckdb/function/scalar_function.hpp>
//#include <duckdb/main/extension_util.hpp>
#include <duckdb/main/extension/extension_loader.hpp>
#include <duckdb/parser/parsed_data/create_scalar_function_info.hpp>
#include <atomic>
#include <optional>
#include <pgwire/exception.hpp>
#include <pgwire/log.hpp>
#include <pgwire/server.hpp>
#include <pgwire/types.hpp>
#include <stdexcept>
namespace duckdb {
static std::atomic<bool> g_started;
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},
// uses string
{LogicalTypeId::VARCHAR, pgwire::Oid::Varchar},
{LogicalTypeId::DATE, pgwire::Oid::Date},
{LogicalTypeId::TIME, pgwire::Oid::Time},
{LogicalTypeId::TIMESTAMP, pgwire::Oid::Timestamp},
{LogicalTypeId::TIMESTAMP, pgwire::Oid::TimestampTz},
};
static pgwire::ParseHandler duckdb_handler(DatabaseInstance &db) {
return [&db](std::string const &query) mutable {
Connection conn(db);
pgwire::PreparedStatement stmt;
std::unique_ptr<PreparedStatement> prepared;
std::optional<pgwire::SqlException> error;
std::vector<std::string> column_names;
std::vector<LogicalType> column_types;
std::size_t column_total;
try {
prepared = conn.Prepare(query);
if (!prepared) {
throw std::runtime_error(
"failed prepare query with unknown error");
}
if (prepared->HasError()) {
throw std::runtime_error(prepared->GetError());
}
column_names = prepared->GetNames();
column_types = prepared->GetTypes();
column_total = prepared->ColumnCount();
} catch (std::exception &e) {
error =
pgwire::SqlException{e.what(), pgwire::SqlState::DataException};
}
// rethrow error
if (error) {
throw *error;
}
stmt.fields.reserve(column_total);
for (std::size_t i = 0; i < column_total; i++) {
auto &name = column_names[i];
auto &type = column_types[i];
auto it = g_typemap.find(type.id());
if (it == g_typemap.end()) {
continue;
}
auto oid = it->second;
// can't uses emplace_back for POD struct in C++17
stmt.fields.push_back({name, oid});
}
stmt.handler = [column_total, p = std::move(prepared)](
pgwire::Writer &writer,
pgwire::Values const ¶meters) mutable {
std::unique_ptr<QueryResult> result;
std::optional<pgwire::SqlException> error;
try {
result = p->Execute();
if (!result) {
throw std::runtime_error(
"failed to execute query with unknown error");
}
if (result->HasError()) {
throw std::runtime_error(result->GetError());
}
} catch (std::exception &e) {
// std::cout << "error occured during execute:" << std::endl;
error = pgwire::SqlException{e.what(),
pgwire::SqlState::DataException};
}
if (error) {
throw *error;
}
auto &column_types = p->GetTypes();
for (auto &chunk : *result) {
auto row = writer.add_row();
for (std::size_t i = 0; i < column_total; i++) {
auto &type = column_types[i];
auto it = g_typemap.find(type.id());
if (it == g_typemap.end()) {
continue;
}
auto value = chunk.iterator.chunk->GetValue(i, chunk.row);
if (value.IsNull()) {
row.write_null();
continue;
}
switch (type.id()) {
case LogicalTypeId::FLOAT:
row.write_float4(chunk.GetValue<float>(i));
break;
case LogicalTypeId::DOUBLE:
row.write_float8(chunk.GetValue<double>(i));
break;
case LogicalTypeId::SMALLINT:
row.write_int2(chunk.GetValue<int16_t>(i));
break;
case LogicalTypeId::INTEGER:
row.write_int4(chunk.GetValue<int32_t>(i));
break;
case LogicalTypeId::BIGINT:
row.write_int8(chunk.GetValue<int64_t>(i));
break;
case LogicalTypeId::BOOLEAN:
row.write_bool(chunk.GetValue<bool>(i));
break;
case LogicalTypeId::VARCHAR:
case LogicalTypeId::DATE:
case LogicalTypeId::TIME:
case LogicalTypeId::TIMESTAMP:
case LogicalTypeId::TIMESTAMP_TZ:
row.write_string(chunk.GetValue<std::string>(i));
break;
default:
break;
}
}
}
};
return stmt;
};
}
static void start_server(DatabaseInstance &db) {
using namespace asio;
if (g_started)
return;
g_started = true;
io_context io_context;
ip::tcp::endpoint endpoint(ip::tcp::v4(), 15432);
pgwire::log::initialize(io_context, "duckdb_pgwire.log");
pgwire::Server server(
io_context, endpoint,
[&db](pgwire::Session &sess) mutable { return duckdb_handler(db); });
server.start();
}
inline void PgIsInRecovery(DataChunk &args, ExpressionState &state,
Vector &result) {
result.SetValue(0, false);
}
inline void DuckdbPgwireScalarFun(DataChunk &args, ExpressionState &state, Vector &result) {
auto &name_vector = args.data[0];
UnaryExecutor::Execute<string_t, string_t>(
name_vector, result, args.size(),
[&](string_t name) {
return StringVector::AddString(result, "DuckdbPgwire "+name.GetString()+" 🐥");;
});
}
/*
static void LoadInternal(DatabaseInstance &instance) {
// Register a scalar function
auto pg_is_in_recovery_scalar_function = ScalarFunction(
"pg_is_in_recovery", {}, LogicalType::BOOLEAN, PgIsInRecovery);
ExtensionUtil::RegisterFunction(instance,
pg_is_in_recovery_scalar_function);
auto duckdb_pgwire_scalar_function = ScalarFunction("duckdb_pgwire", {LogicalType::VARCHAR}, LogicalType::VARCHAR, DuckdbPgwireScalarFun);
ExtensionUtil::RegisterFunction(instance, duckdb_pgwire_scalar_function);
std::thread([&instance]() mutable { start_server(instance); }).detach();
}
void DuckdbPgwireExtension::Load(DuckDB &db) { LoadInternal(*db.instance); }
std::string DuckdbPgwireExtension::Name() { return "duckdb_pgwire"; }
*/
static void LoadInternal(ExtensionLoader &loader) {
// Register a scalar function
auto pg_is_in_recovery_scalar_function = ScalarFunction("pg_is_in_recovery", {}, LogicalType::BOOLEAN, PgIsInRecovery);
loader.RegisterFunction(pg_is_in_recovery_scalar_function);
// Register another scalar function
auto duckdb_pgwire_scalar_function = ScalarFunction("duckdb_pgwire", {LogicalType::VARCHAR}, LogicalType::VARCHAR, DuckdbPgwireScalarFun);
loader.RegisterFunction(duckdb_pgwire_scalar_function);
DatabaseInstance & instance=loader.GetDatabaseInstance();
std::thread([&instance]() mutable { start_server(instance); }).detach();
}
void DuckdbPgwireExtension::Load(ExtensionLoader &loader) {
LoadInternal(loader);
}
std::string DuckdbPgwireExtension::Name() {
return "duckdb_pgwire";
}
std::string DuckdbPgwireExtension::Version() const {
#ifdef EXT_VERSION_QUACK
return EXT_VERSION_QUACK;
#else
return "";
#endif
}
} // namespace duckdb
extern "C" {
/*
DUCKDB_EXTENSION_API void duckdb_pgwire_init(duckdb::DatabaseInstance &db) {
duckdb::DuckDB db_wrapper(db);
db_wrapper.LoadExtension<duckdb::DuckdbPgwireExtension>();
}
DUCKDB_EXTENSION_API const char *duckdb_pgwire_version() {
return duckdb::DuckDB::LibraryVersion();
}
*/
DUCKDB_CPP_EXTENSION_ENTRY(duckdb_pgwire, loader) {
duckdb::LoadInternal(loader);
}
}
#ifndef DUCKDB_EXTENSION_MAIN
#error DUCKDB_EXTENSION_MAIN not defined
#endif
同时修改include/duckdb_pgwire_extension.hpp如下
cpp
#pragma once
#include <duckdb.hpp>
namespace duckdb {
class DuckdbPgwireExtension : public Extension {
public:
//void Load(DuckDB &db) override;
void Load(ExtensionLoader &db);
std::string Name() override;
std::string Version() const override;
};
} // namespace duckdb
编译完成后用python脚本添加元数据
cpp
python3 /par/appendmetadata.py -l libtest2.so -n duckdb_pgwire -dv v1.4.0 --duckdb-platform linux_amd64 --extension-version 0.1 --abi-type ""
加载出错,有未定义的符号,想要静态链接libpgwire.a,也出错了
cpp
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# export LD_LIBRARY_PATH=/par/libduckdb
root@6ae32a5ffcde:/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';
IO Error:
Extension "/par/duckdb-pgwire-main/src/duckdb_pgwire.duckdb_extension" could not be loaded: /par/duckdb-pgwire-main/src/duckdb_pgwire.duckdb_extension: undefined symbol: _ZTIN6pgwire12SqlExceptionE
D .exit
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# g++ -fPIC -shared -o libtest2.so 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 ../pgwire/build/src/pgwire/libpgwire.a
/usr/bin/ld: ../pgwire/build/src/pgwire/libpgwire.a(exception.cpp.o): relocation R_X86_64_32S against symbol `_ZTVN6pgwire12SqlExceptionE' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
干脆把pgwire编成动态库libpgwire.so, 然后让duckdb-pgwire插件再动态链接它
cpp
root@6ae32a5ffcde:/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 ../pg
wire/third_party/asio/asio/include -I ../pgwire/third_party/endian/src -I ../pgwire/third_party/function2/include
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# g++ -fPIC -shared -o libtest2.so 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 .
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# python3 /par/appendmetadata.py -l libtest2.so -n duckdb_pgwire -dv v1.4.0 --duckdb-platform linux_amd64 --extension-version 0.1 --abi-type ""
插件可以加载了
cpp
root@6ae32a5ffcde:/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';
D select duckdb_pgwire('asdf');
┌───────────────────────┐
│ duckdb_pgwire('asdf') │
│ varchar │
├───────────────────────┤
│ DuckdbPgwire asdf 🐥 │
└───────────────────────┘
D select pg_is_in_recovery();
┌─────────────────────┐
│ pg_is_in_recovery() │
│ boolean │
├─────────────────────┤
│ false │
└─────────────────────┘
D .exit
root@6ae32a5ffcde:/par/duckdb-pgwire-main/src# /par/duckdb140 -unsigned -cmd "load '/par/duckdb-pgwire-main/src/duckdb_pgwire.duckdb_extension'"
DuckDB v1.4.0 (Andium) b8a06e4a22
Enter ".help" for usage hints.
D select duckdb_pgwire('asdf');
┌───────────────────────┐
│ duckdb_pgwire('asdf') │
│ varchar │
├───────────────────────┤
│ DuckdbPgwire asdf 🐥 │
└───────────────────────┘
但是再开一个客户端,用psql访问不行,
cpp
root@6ae32a5ffcde:/# psql 'postgresql://localhost:15432/main' -c 'select * from generate_series(0, 4)'
psql: error: connection to server at "localhost" (127.0.0.1), port 15432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
仔细比对修改前后源代码,发现我遗漏了一句
cpp
std::thread([&instance]() mutable { start_server(instance); }).detach();
而这里需要的instance, 在函数参数里没有,怎么获取,查看duckdb/main/extension/extension_loader.cpp中定义
cpp
namespace duckdb {
ExtensionLoader::ExtensionLoader(ExtensionActiveLoad &load_info)
: db(load_info.db), extension_name(load_info.extension_name), extension_info(load_info.info) {
}
ExtensionLoader::ExtensionLoader(DatabaseInstance &db, const string &name) : db(db), extension_name(name) {
}
DatabaseInstance &ExtensionLoader::GetDatabaseInstance() {
return db;
}
所以把上述语句改为
cpp
DatabaseInstance & instance=loader.GetDatabaseInstance();
std::thread([&instance]() mutable { start_server(instance); }).detach();
重新编译,处理,加载,这次再用psql就能访问了。
cpp
root@6ae32a5ffcde:/# psql 'postgresql://localhost:15432/main' -c 'select * from generate_series(0, 4)'
generate_series
-----------------
0
1
2
3
4
(5 rows)
至此,我们可以通过插件duckdb-pgwire为duckdb添加postgresql协议,用支持这个协议的工具来访问了。
cpp
root@6ae32a5ffcde:/# psql 'postgresql://localhost:15432/main'
psql (15.13 (Debian 15.13-0+deb12u1), server 14)
Type "help" for help.
main=> select version();
"version"()
-------------
v1.4.0
(1 row)
main=> select * from duckdb_functions() where function_name like '%pgwire%';
database_name | database_oid | schema_name | function_name | alias_of | function_type | description | comment | return_
type | varargs | macro_definition | function_oid | stability
---------------+--------------+-------------+---------------+----------+---------------+-------------+---------+--------
-----+---------+------------------+--------------+------------
system | 0 | main | duckdb_pgwire | | scalar | | | VARCHAR
| | | 1998 | CONSISTENT
(1 row)