Table functions
On this page
Set-returning producers, with the optimizer hooks that make them fast.
function defineTableFunction
Section titled âfunction defineTableFunctionâexport function defineTableFunction<TArgs = Record<string, any>,TState = null,>(config: TableFunctionConfig<TArgs, TState>): VgiFunctioninterface TableBindParams
Section titled âinterface TableBindParamsâexport interface TableBindParams<TArgs = Record<string, any>>Fields
argsTArgsbindCallBindRequestsettingsRecord<string, any>secretsRecord<string, Record<string, any>>resolvedSecretsProvidedboolean
interface TableFunctionConfig
Section titled âinterface TableFunctionConfigâexport interface TableFunctionConfig<TArgs = Record<string, any>,TState = null,>Fields
namestringonBind(params: TableBindParams<TArgs>) => | { outputSchema: VgiSchema; opaqueData?: Uint8Array; lookupSecretTypes?: string[]; lookupScopes?: string[]; lookupNames?: string[]; } | Promise<{ outputSchema: VgiSchema; opaqueData?: Uint8Array; lookupSecretTypes?: string[]; lookupScopes?: string[]; lookupNames?: string[]; }>Bind: return output schema. May be async â handlers
awaitthe result.process( params: TableProcessParams<TArgs>, state: TState, out: OutputCollector ) => void | Promise<void>Process: emit batches via out, call out.finish() when done
descriptionstringoptionalargsRecord<string, VgiDataType>optionalArgument schema (positional args)
argDocsRecord<string, string>optionalArgument docs
argDefaultsRecord<string, any>optionalArgument defaults
argConstraintsRecord<string, ArgumentConstraints>optionalPer-argument discovery constraints (choices / ge / le / gt / lt / pattern), keyed by argument name. Surfaced via
vgi_function_arguments()for agent discovery AND enforced at bind: a value violating a declared constraint fails the bind with an ArgumentValidationError.varargsstring[]optionalNames of args that accept variable number of arguments
onInit(params: { args: TArgs; initCall: InitRequest; outputSchema: VgiSchema; executionId: Uint8Array; storage: BoundStorage; }) => GlobalInitResponse | Promise<GlobalInitResponse>optionalInit (optional). May be async â common when storage is HTTP-backed.
initialState(params: TableProcessParams<TArgs>) => TStateoptionalState factory
cardinality(params: TableBindParams<TArgs>) => TableCardinality | Promise<TableCardinality>optionalCardinality hints
statistics(params: TableBindParams<TArgs>) => ColumnStatistics[] | nulloptionalPer-column statistics for the functionâs output. Returned to DuckDB via the
table_function_statisticsRPC; the optimizer uses min/max to eliminate impossible filters at plan time (folding scans to EMPTY_RESULT). Returnnullor an empty array when bounds are unknown.dynamicToString( params: TableBindParams<TArgs>, executionId: Uint8Array, storage: BoundStorage, ) => Record<string, string> | Promise<Record<string, string>>optionalPer-execution diagnostics surfaced under EXPLAIN ANALYZE. DuckDB calls this once per parallel scan thread at pipeline FinishSource via the
table_function_dynamic_to_stringRPC. Return ordered keyâvalue strings; the C++ extension merges these with the intrinsic keys (Function, Rows Read, Threads). The framework provides a BoundStorage keyed by the global execution_id so process() can persist counters that this callback then reads back â see profiling_demo for the canonical pattern.projectionPushdownbooleanoptionalfilterPushdownbooleanoptionalsamplingPushdownbooleanoptionallateMaterializationbooleanoptionalOpt in to DuckDBâs late-materialization SEMI-join rewrite; requires a UNIQUE, snapshot-stable rowid column. FunctionInfo.late_materialization.
supportedExpressionFiltersstring[]optionalautoApplyFiltersbooleanoptionalstabilityFunctionStabilityoptionalexamplesFunctionExample[]optionalcategoriesstring[]optionaltagsRecord<string, string>optionalmaxWorkersnumberoptionalrequiredSettingsstring[]optionalrequiredSecretsstring[]optionalpreservesOrderOrderPreservationoptionalRow-order preservation behavior; flows to DuckDBâs TableFunction::order_preservation_type.
nullHandlingNullHandlingoptionalorderDependentOrderDependenceoptionaldistinctDependentDistinctDependenceoptionalsupportsBatchIndexbooleanoptionalEmit per-batch
vgi_batch_index; FunctionInfo.supports_batch_index.partitionKindâNOT_PARTITIONEDâ | âSINGLE_VALUE_PARTITIONSâ | âOVERLAPPING_PARTITIONSâ | âDISJOINT_PARTITIONSâoptionalHive-style partition-columns mode; FunctionInfo.partition_kind.
interface TableProcessParams
Section titled âinterface TableProcessParamsâexport interface TableProcessParams<TArgs = Record<string, any>>Fields
argsTArgsinitCallInitRequestinitResponseGlobalInitResponseoutputSchemaVgiSchemasettingsRecord<string, any>secretsRecord<string, Record<string, any>>pushdownFiltersPushdownFiltersoptionalstorageBoundStorageoptionalatUnitstringoptionalAT (TIMESTAMP|VERSION) clause for this scan, or
undefinedwhen the scan has no AT clause. Carried on the per-scan bind embedded in the init request (initCall.bind_call.at_unit/.at_value), so function-backed tables can read time travel at init alongside their pushdown filters. Mirrors vgi-pythonâsProcessParams.at_unit/.at_value. SeeBindRequest.at_unit.atValuestringoptionalifNoneMatchstringoptionalConditional-revalidation validator (the clientâs stored ETag). Set when the client holds a stale-but-revalidatable cached result and asks the worker to confirm freshness cheaply; a worker that advertised
revalidatablecompares it and, if unchanged, emits a 0-row batch taggedcacheControlMetadata({ notModified: true })instead of re-streaming. Undefined on a normal call.ifModifiedSincestringoptionalConditional-revalidation validator (the clientâs stored Last-Modified). Companion to {@link ifNoneMatch}. Undefined on a normal call.