Skip to content
Query.Farm
Talk with Us

Table functions

On this page

Row generators: arguments in, a whole relation out.

source
type BatchState struct {
Remaining int64
BatchSize int64
Index int64
}

Description

BatchState tracks the remaining/batchSize/index bookkeeping for table functions that generate a fixed number of rows in batches. Embed this in your state struct to use with GenerateBatch.

Index is a public field so callbacks can read the current row offset. All fields are managed by GenerateBatch — do not modify them directly.

Methods

source
func NewBatchState(count, batchSize int64) BatchState

NewBatchState creates a BatchState with the given total count and batch size.

source
type CardinalityEstimator interface {
// Cardinality estimates the function's output row count for the optimizer.
Cardinality(params *BindParams) (*TableCardinality, error)
}

Description

CardinalityEstimator is an optional interface for TypedTableFunc implementations that can estimate their output row count for query optimization.

source
type ColumnSet map[string]struct{}

Description

ColumnSet is a set of column names, typically used for projection pushdown.

Methods

source
func (cs ColumnSet) Contains(name string) bool

Contains returns true if the named column is in the set.

source
func ProjectedColumns(projectionIDs []int32, fullSchema *arrow.Schema) ColumnSet

ProjectedColumns returns the set of column names that should be generated, given projection IDs and the full (unprojected) schema. If projectionIDs is nil, all columns are included.

source
type OnIniter interface {
// OnInit performs global initialization (e.g. worker count, partitioning).
OnInit(params *InitParams) (*GlobalInitResponse, error)
}

Description

OnIniter is an optional interface for TypedTableFunc implementations that need custom OnInit behavior (e.g., multi-worker partitioning with work queues). If not implemented, the adapter defaults to DefaultInit() (MaxWorkers: 1).

source
type StatisticsProvider interface {
// Statistics reports per-column output statistics to the optimizer.
Statistics(params *BindParams) ([]ColumnStatistics, error)
}

Description

StatisticsProvider is an optional interface for TypedTableFunc implementations that can report per-column output statistics to the optimizer (min/max, null-ness, distinct count, string length).

source
type TableCardinality struct {
// Estimate is the estimated number of rows.
Estimate int64 `vgirpc:"estimate,nullable"`
// Max is the maximum number of rows (-1 = unknown).
Max int64 `vgirpc:"max,nullable"`
}

Description

TableCardinality represents the estimated cardinality of a table function’s output.

source
type TableFunction interface {
// Name returns the function name used in SQL.
Name() string
// Metadata returns descriptive metadata.
Metadata() FunctionMetadata
// ArgumentSpecs returns the function's argument specifications.
ArgumentSpecs() []ArgSpec
// OnBind resolves the output schema given the bind parameters.
OnBind(params *BindParams) (*BindResponse, error)
// OnInit performs one-time initialization and returns execution parameters.
OnInit(params *InitParams) (*GlobalInitResponse, error)
// NewState creates the initial mutable state for this function execution.
NewState(params *ProcessParams) (interface{}, error)
// Process generates the next output batch. It must either emit data via
// out.Emit/EmitArrays or call out.Finish() to signal end-of-stream.
Process(ctx context.Context, params *ProcessParams, state interface{}, out *vgirpc.OutputCollector) error
}

Description

TableFunction is the interface for table VGI functions. Table functions generate output without receiving input (Producer mode).

Methods

source
func AsTableFunction[S any](f TypedTableFunc[S]) TableFunction
source
type TableFunctionWithCardinality interface {
TableFunction
// Cardinality returns an estimated row count for query optimization.
Cardinality(params *BindParams) (*TableCardinality, error)
}

Description

TableFunctionWithCardinality extends TableFunction with cardinality estimation.

source
type TableFunctionWithStatistics interface {
TableFunction
// Statistics returns per-output-column stats (empty slice or nil = unknown).
Statistics(params *BindParams) ([]ColumnStatistics, error)
}

Description

TableFunctionWithStatistics extends TableFunction with per-column statistics that help the optimizer fold or skip filters before running the scan.

source
type TypedTableFunc[S any] interface {
// Name returns the function name used to invoke it in SQL.
Name() string
// Metadata returns descriptive metadata for the function.
Metadata() FunctionMetadata
// ArgumentSpecs returns the function's argument specifications.
ArgumentSpecs() []ArgSpec
// OnBind resolves the output schema and bind state from the bind parameters.
OnBind(params *BindParams) (*BindResponse, error)
// NewState creates a fresh, typed per-scan state value.
NewState(params *ProcessParams) (*S, error)
// Process generates output rows for one scan step, emitting them via out.
Process(ctx context.Context, params *ProcessParams, state *S, out *vgirpc.OutputCollector) error
}

Description

TypedTableFunc is the recommended interface for table functions. It provides compile-time type safety for state management, eliminating the unsafe state.(*myType) assertions required by the lower-level TableFunction interface.

Use the lower-level TableFunction interface only for advanced use cases that need non-standard state patterns.

Implementations may also satisfy OnIniter (custom OnInit) and/or CardinalityEstimator (cardinality estimation). These are detected automatically by AsTableFunction.

source
type typedTableAdapter[S any] struct {
inner TypedTableFunc[S]
onInit func(*InitParams) (*GlobalInitResponse, error)
statsProvider StatisticsProvider
}

Description

typedTableAdapter implements TableFunction by delegating to a TypedTableFunc[S].

Methods

source
func (a *typedTableAdapter[S]) ArgumentSpecs() []ArgSpec

ArgumentSpecs forwards to the wrapped typed function’s ArgumentSpecs.

source
func (a *typedTableAdapter[S]) DynamicToString(ctx context.Context, params *DynamicToStringParams) ([]string, []string, error)

DynamicToString forwards to the inner typed function when it implements the hook. The framework’s RPC handler does the interface check on the adapter (the user-facing TableFunction); without this forwarder a typed function’s hook would be invisible.

source
func (a *typedTableAdapter[S]) Metadata() FunctionMetadata

Metadata forwards to the wrapped typed function’s Metadata.

source
func (a *typedTableAdapter[S]) Name() string

Name forwards to the wrapped typed function’s Name.

source
func (a *typedTableAdapter[S]) NewState(params *ProcessParams) (interface{}, error)

NewState forwards to the wrapped typed function’s NewState, returning the typed state as an untyped interface{}.

source
func (a *typedTableAdapter[S]) OnBind(params *BindParams) (*BindResponse, error)

OnBind forwards to the wrapped typed function’s OnBind.

source
func (a *typedTableAdapter[S]) OnInit(params *InitParams) (*GlobalInitResponse, error)

OnInit invokes the optional OnIniter hook if present, otherwise returns DefaultInit.

source
func (a *typedTableAdapter[S]) Process(ctx context.Context, params *ProcessParams, state interface{}, out *vgirpc.OutputCollector) error

Process type-asserts the untyped state to *S and forwards to the wrapped typed function’s Process, returning an error on a state type mismatch.

source
func (a *typedTableAdapter[S]) Statistics(params *BindParams) ([]ColumnStatistics, error)

Statistics delegates to the wrapped function’s StatisticsProvider if it implements one, returning nil otherwise.

source
type typedTableAdapterWithCard[S any] struct {
*typedTableAdapter[S]
card CardinalityEstimator
}

Description

typedTableAdapterWithCard embeds typedTableAdapter and additionally implements TableFunctionWithCardinality, so the type assertion in protocol.go (fn.(TableFunctionWithCardinality)) succeeds.

Methods

source
func (a typedTableAdapterWithCard) ArgumentSpecs() []ArgSpec

ArgumentSpecs forwards to the wrapped typed function’s ArgumentSpecs.

source
func (a *typedTableAdapterWithCard[S]) Cardinality(params *BindParams) (*TableCardinality, error)

Cardinality forwards to the wrapped CardinalityEstimator’s Cardinality.

source
func (a typedTableAdapterWithCard) DynamicToString(ctx context.Context, params *DynamicToStringParams) ([]string, []string, error)

DynamicToString forwards to the inner typed function when it implements the hook. The framework’s RPC handler does the interface check on the adapter (the user-facing TableFunction); without this forwarder a typed function’s hook would be invisible.

source
func (a typedTableAdapterWithCard) Metadata() FunctionMetadata

Metadata forwards to the wrapped typed function’s Metadata.

source
func (a typedTableAdapterWithCard) Name() string

Name forwards to the wrapped typed function’s Name.

source
func (a typedTableAdapterWithCard) NewState(params *ProcessParams) (interface{}, error)

NewState forwards to the wrapped typed function’s NewState, returning the typed state as an untyped interface{}.

source
func (a typedTableAdapterWithCard) OnBind(params *BindParams) (*BindResponse, error)

OnBind forwards to the wrapped typed function’s OnBind.

source
func (a typedTableAdapterWithCard) OnInit(params *InitParams) (*GlobalInitResponse, error)

OnInit invokes the optional OnIniter hook if present, otherwise returns DefaultInit.

source
func (a typedTableAdapterWithCard) Process(ctx context.Context, params *ProcessParams, state interface{}, out *vgirpc.OutputCollector) error

Process type-asserts the untyped state to *S and forwards to the wrapped typed function’s Process, returning an error on a state type mismatch.

source
func (a typedTableAdapterWithCard) Statistics(params *BindParams) ([]ColumnStatistics, error)

Statistics delegates to the wrapped function’s StatisticsProvider if it implements one, returning nil otherwise.

source
func BatchFromMap(schema *arrow.Schema, columns map[string]arrow.Array, numRows int64) (arrow.RecordBatch, error)

BatchFromMap reorders columns from a name-keyed map to match schema field order and creates a RecordBatch. It consumes all arrays in the map — every array (both schema-matched and extra) is released on success and on error, matching GenerateBatch’s ownership model. Returns an error if a schema field is missing from the map. Extra map keys are silently ignored but their arrays are still released.

source
func BuildAllNullArray(dt arrow.DataType, n int64) arrow.Array

BuildAllNullArray creates an n-row all-NULL array of the given type. The type is created via NewBuilder so any Arrow primitive / nested type works.

source
func BuildArray[T any, B ArrayBuilder[T]](n int64, newBuilder func(memory.Allocator) B, fn func(i int64) T) arrow.Array

BuildArray creates an array of any type using the ArrayBuilder generic constraint. Use this for types not covered by BuildInt64Array, BuildFloat64Array, etc.

source
func BuildBinaryArray(n int64, fn func(i int64) []byte) arrow.Array

BuildBinaryArray creates a binary array by calling fn for each row index.

source
func BuildBooleanArray(n int64, fn func(i int64) bool) arrow.Array

BuildBooleanArray creates a boolean array by calling fn for each row index.

source
func BuildFloat64Array(n int64, fn func(i int64) float64) arrow.Array

BuildFloat64Array creates a float64 array by calling fn for each row index.

source
func BuildInt32Array(n int64, fn func(i int64) int32) arrow.Array

BuildInt32Array creates an int32 array by calling fn for each row index.

source
func BuildInt64Array(n int64, fn func(i int64) int64) arrow.Array

BuildInt64Array creates an int64 array by calling fn for each row index. The caller is responsible for releasing the returned array, unless using GenerateBatch which handles release automatically.

source
func BuildStringArray(n int64, fn func(i int64) string) arrow.Array

BuildStringArray creates a string array by calling fn for each row index.

source
func BuildUint64Array(n int64, fn func(i int64) uint64) arrow.Array

BuildUint64Array creates a uint64 array by calling fn for each row index.

source
func FindColumn(batch arrow.RecordBatch, name string) arrow.Array

FindColumn returns the column array from a RecordBatch by field name, or nil if not found.

source
func GenerateBatch(bs *BatchState, out *vgirpc.OutputCollector, generateFn func(size int64) ([]arrow.Array, error)) error

GenerateBatch handles one batch of a batch-splitting table function. Call this from Process — it handles the complete remaining-work pattern:

  1. If Remaining <= 0, calls out.Finish() and returns
  2. Computes size = min(Remaining, BatchSize)
  3. Calls generateFn(size) to produce arrays
  4. Emits the arrays via out.EmitArrays
  5. Releases all returned arrays
  6. Updates Remaining and Index

VGI’s Process is called once per batch by the framework. This function processes exactly one batch per call — it does NOT loop.

The generateFn closure should capture bs.Index at the start to know the current row offset before GenerateBatch advances it.

source
func GenerateBatchMap(bs *BatchState, out *vgirpc.OutputCollector, schema *arrow.Schema, generateFn func(size int64) (map[string]arrow.Array, error)) error

GenerateBatchMap handles one batch of a batch-splitting table function using name-keyed columns. Same lifecycle as GenerateBatch (check remaining, compute size, call callback, update state) but the callback returns map[string]arrow.Array. Uses BatchFromMap internally and emits via out.Emit.

source
func OptionalBool(args *Arguments, name string, defaultVal bool) bool

OptionalBool extracts a named bool argument, returning defaultVal if the argument is null, not present, or cannot be converted to bool.

source
func OptionalFloat64(args *Arguments, name string, defaultVal float64) float64

OptionalFloat64 extracts a named float64 argument, returning defaultVal if the argument is null, not present, or cannot be converted to float64.

source
func OptionalInt64(args *Arguments, name string, defaultVal int64) int64

OptionalInt64 extracts a named int64 argument, returning defaultVal if the argument is null, not present, or cannot be converted to int64. This is a convenience helper that never returns an error — type mismatches silently return the default value.

source
func OptionalString(args *Arguments, name string, defaultVal string) string

OptionalString extracts a named string argument, returning defaultVal if the argument is null, not present, or cannot be converted to string.

source
func assertGobEncodable(t reflect.Type, path string, seen map[reflect.Type]bool)

assertGobEncodable panics if t — reachable from a state field via path — holds a value gob cannot encode. seen guards against self-referential types.

source
func implementsGobEncoder(t reflect.Type) bool

AsTableFunction wraps a TypedTableFunc into a TableFunction for registration with Worker.RegisterTable. The adapter:

  • Provides type-safe state casting (returns error instead of panic)
  • Defaults OnInit to DefaultInit() (MaxWorkers: 1) unless OnIniter is implemented
  • Delegates Cardinality if CardinalityEstimator is implemented

Usage:

func NewSequenceFunction() vgi.TableFunction {
return vgi.AsTableFunction[sequenceState](&SequenceFunction{})
}

implementsGobEncoder reports whether t (or *t) defines its own gob encoding, in which case it manages its own serialization and is exempt from inspection.

source
func validateGobStateS any

validateGobState fails fast (at registration) when the per-scan state type S cannot be gob-encoded for HTTP rehydration. gob otherwise surfaces these only mid-query, on the first HTTP continuation, with a cryptic message. Two pitfalls are caught by walking S’s exported, gob-reachable fields:

  • a struct whose fields are all unexported (e.g. struct{ done bool }): gob
encodes nothing and reports "type ... has no exported fields".
  • an exported field of a kind gob cannot encode — an interface (the common
case being an Arrow `arrow.Record`/`arrow.Array` stashed in state to emit
later), a chan, a func, or an unsafe.Pointer. The fix is to store plain
serializable Go values (slices, scalars) in state and rebuild the Arrow
batch in Process, mirroring the SDK's static_data.go example.

A truly empty struct{} is fine, and any type providing its own gob.GobEncoder is exempt (at the top level or as a nested field). Mirrors vgi-python enforcing serializable state at class-definition time.