What's new
vgi-go is at v0.22.0, speaking wire protocol 1.3.0 — the same protocol the Python and TypeScript SDKs speak, driven by the same DuckDB extension. This page groups what landed by theme.
vgi-go versions on its own line and does not track vgi-python’s numbers. Protocol version is what they share: a v0.22.0 Go worker and a 0.28.x Python worker both speak 1.3.0 and are interchangeable behind the same extension.
Breaking changes
Section titled “Breaking changes”A function name was never a unique key. Dispatch was a flat name lookup, so the same name registered in two schemas collided as overloads. Resolution is now keyed on the full path, and the unary RPCs that re-resolve a function by name carry the schema too — without that, a call bound correctly and then ran the other schema’s implementation, returning a wrong-but-plausible answer.
Protocol 1.0.0 → 1.2.0.
Renamed, and the shape changed from a flat list to conjunctive normal form: an AND of OR-groups. See Requiring a filter.
Result caching
Section titled “Result caching”A worker can advertise that its result is reusable by attaching vgi.cache.* metadata to its first
data batch. The vocabulary is HTTP’s — a freshness lifetime, a reuse scope, validators for
conditional revalidation, and stale-serving grace windows.
| Release | What landed |
|---|---|
| v0.15.0 | CacheControl and the vgi.cache.* keys for table functions. |
| v0.16.0 | Cache control from a buffered finalize; conditional-revalidation validators surfaced as params.IfNoneMatch / IfModifiedSince. |
| v0.16.0 | Opt-in for scalar functions. |
| v0.17.0 | PartitionScope for per-partition caching. |
| v0.18.0 | PerValue — per-VALUE memoization for exchange-mode maps. |
Function shapes
Section titled “Function shapes”- Blended table-in-out (v0.16.0) — set
FunctionMetadata.InputFromArgs; positional args are the per-row input columns, so one registration serves a literal call, a column call, and a correlatedLATERAL. v0.16.0 also added per-output-row provenance so batched correlatedLATERALstays correct. - Parallel finalize /
substream_id(v0.16.0) for table-in-out functions. - Const-argument constraints enforced at bind — scalars in v0.10.0, aggregates in
v0.11.0. A
ge=/le=/choices=you declared is actually binding.
Catalogs
Section titled “Catalogs”| Release | What landed |
|---|---|
| v0.19.0 | Global functions — publish selected functions into DuckDB’s system.main so they are callable unqualified. Protocol 1.2.0 → 1.3.0. |
| v0.21.0 | Per-catalog attach options. |
| v0.15.0 | RequiredFilters in CNF — refuse an unbounded scan. |
v0.22.0 — three failures moved to where they are caused
Section titled “v0.22.0 — three failures moved to where they are caused”Each of these used to register cleanly and fail somewhere unrelated.
| Fix | What used to happen |
|---|---|
type= rejects unknown Arrow type names | Was: vgi:“type=bigint” silently became VARCHAR, then failed to bind against an integer literal with an error naming the call site. Now: rejected at registration, with the right Arrow name suggested. |
RegisterAggregate gob-registers its state | Was: you had to call gob.Register(&MyState) yourself, or the first GROUP BY failed. Now: registered from NewState; your own call is a harmless no-op. |
| COPY format name collisions are rejected | Was: a reader and a writer sharing a format name silently lost one of them. Now: rejected at registration, with one handler serving both directions merged to direction=“both”. |
A worker carrying an unrecognised type= will now refuse to start rather than registering a wrong
signature. That is the point of the change, but it is a behaviour change and not merely a better
message — check your struct tags before upgrading. The error names the value and suggests the
correct Arrow name.
Performance
Section titled “Performance”- Data plane (v0.17.0) — per-row and per-batch allocation and CPU cut in the hot paths.
Next steps
Section titled “Next steps”- Start building → Function patterns.
- The full API → Package overview.
- Upstream history → Query-farm/vgi-go releases.