Vector Gateway Interface for Go

Extend DuckDB with functions written in Go — backed by Apache Arrow, callable straight from SQL.
vgi-go implements the Vector Gateway Interface (VGI) for Go: you write a small worker exposing typed functions, and DuckDB calls them as if they were native. Data moves as Apache Arrow record batches on arrow-go, so it stays columnar across the boundary — no row-by-row marshalling.
Install
Section titled “Install”go get github.com/Query-farm/vgi-go
The module path is github.com/Query-farm/vgi-go; the package you import is
github.com/Query-farm/vgi-go/vgi.
A worker is an ordinary main package. Register your functions on a Worker, then pick a transport:
import "github.com/Query-farm/vgi-go/vgi"
// DoubleFn and doubleArgs are yours — the tutorial builds them in ten minutes.
w := vgi.NewWorker(vgi.WithCatalogName("calc"))
w.RegisterScalar(vgi.AsScalarFunction[doubleArgs](&DoubleFn{}))
w.RunStdio() // or w.RunHttp(addr) / w.RunUnix(path, idle) / w.RunTcp(host, port, idle)
Start here
Section titled “Start here”Two things to know up front
Section titled “Two things to know up front”- Arguments are declared with struct tags. A
vgi:"..."tag on a field drives both the argument spec the catalog advertises and the runtime binding of values into your struct, so the SQL signature and the Go type cannot drift apart. The full grammar is on Argument tags. - You implement an interface, not a base class.
ScalarFunction,TableFunction,TableInOutFunction,TableBufferingFunctionandAggregateFunctionare interfaces. TheTyped*variants (TypedScalarFunc,TypedTableFunc) add the struct-tag ergonomics, andAsScalarFunction/AsTableFunctionadapt one into the other. Optional hooks —OnInit,Statistics,Cardinality— are separate small interfaces you satisfy only if you want them; see Function patterns.
Coming from another SDK? The protocol is identical and a Go worker is wire-compatible with a Python or Rust one — the same DuckDB extension drives all of them, so the concepts carry over unchanged.