The C++ worker SDK for VGI (Vector Gateway Interface) — write DuckDB functions and catalogs in C++, ship them as one binary, no DuckDB extension to compile and no version coupling.
A worker is an ordinary binary that DuckDB launches and talks to over Apache Arrow IPC. It can expose scalar / table / aggregate functions and whole catalogs that behave like native DuckDB objects. This repo is the C++ sibling of the Rust and Python SDKs, and is built on the C++ vgi-rpc port.
Version 0.13.1 uses vgi.v3 / 3.0.0 and requires a matching VGI
extension. Keep 0.12.x for existing vgi.v2 installations; upgrade the extension
and worker SDKs together. The shared contract prepares for DuckDB 2.0 while
remaining usable by the 1.5 adapter. Optional catalog and query capabilities
still depend on the provider. This release uses vgi-rpc-cpp 0.11.0.
The example worker passes the VGI integration suite in
vgi over the subprocess transport. What
is and is not implemented is written down in
docs/roadmap.md, and the suite — not that file — is the
specification.
git clone https://github.com/Query-farm/vgi-rpc-cpp.git ../vgi-rpc-c++
export VCPKG_ROOT=/path/to/vcpkg
cmake --preset default # Debug + tests
cmake --build build
ctest --test-dir buildvgi-rpc-c++ is built from a sibling checkout by default, since the two move
together and an installed copy goes stale silently. Override with
-DVGI_RPC_SOURCE_DIR=<path>, or use an installed copy with
-DVGI_USE_INSTALLED_RPC=ON.
Note for Linux and macOS: vcpkg builds libsodium through its autotools script,
so autoconf and automake need to be installed. Windows uses MSBuild and
needs neither.
#include <vgi/worker.h>
class UpperCase : public vgi::ScalarFunction {
std::string name() const override { return "upper_case"; }
vgi::FunctionMetadata metadata() const override {
vgi::FunctionMetadata md;
md.return_type = arrow::utf8();
return md;
}
std::vector<vgi::ArgSpec> argument_specs() const override {
return {vgi::ArgSpec::column("value", 0, "varchar")};
}
std::shared_ptr<arrow::RecordBatch> process(
const vgi::ProcessParams& params,
const std::shared_ptr<arrow::RecordBatch>& batch) const override;
};
int main(int argc, char** argv) {
vgi::Worker worker;
worker.register_scalar(std::make_shared<UpperCase>());
worker.run(argc, argv); // stdio, --unix <path> [--idle-timeout SEC], or --http
}example-worker/ is the full fixture set the integration suite runs against —
several hundred functions across every shape the protocol has, and the best
place to look for how any one of them is meant to behave.
scripts/run_tests.sh # the whole in-scope suite
scripts/run_tests.sh scalar # one category
scripts/run_tests.sh test/sql/integration/scalar/upper_case.testIt drives ~/Development/vgi's unittest binary against the release worker.
VGI_EXT points at the extension checkout, VGI_CPP_BUILD at the build
directory, and VGI_CPP_TEST_CACHE at a scratch directory — the last matters
when two runs go at once, since they would otherwise share one log.
See Hosted protocols and Identity for serving
other vgi-rpc protocols beside vgi.v3 and for hosting vgi_rpc.Identity.v2.
See Attach tickets for letting a runner reattach a
user's catalog later, as that user, with a grant and a sealed vgia1. ticket
(vgi.attach_tickets.v1, enabled by VGI_SIGNING_KEY plus grant keys).
See Iroh operations for the in-process C ABI client and identity-preserving raw or HTTP worker bridge setup.
Query Farm Source-Available License, Version 1.0 — see LICENSE.
The same licence as vgi-python and the DuckDB extension.
HTTP workers serve the shared browser catalog and bundled client at / and
the configured HTTP prefix. The page discovers schemas, tables, views, and
functions through VGI RPC. ?format=json returns worker identity. Asset routes
use the same authentication and proxy-proof policy as RPC and support HEAD
and ETag revalidation. The assets are embedded in the library; no runtime
files are needed. This requires vgi-rpc-cpp 0.5.0 or newer.