vgi.scalar_function
Module overview
Scalar functions: per-row transforms with single-column output.
Scalar functions are the simplest function type in VGI. They transform each input row into exactly one output value, producing a single column of results.
Key characteristics:
- 1:1 row mapping: Output has exactly the same number of rows as input
- Single column output: Output schema has exactly one column named “result”
- No finish(): Processing ends when the caller closes the input stream.
Common use cases:
- Mathematical operations: multiply, add, abs
- String transforms: upper, lower, concat, trim
- Type conversions: cast, parse
- Field extraction: get nested values, parse JSON fields
This module provides two base classes:
ScalarFunction(recommended)- Declarative API using
Param/ConstParam/Returnsannotations oncompute(). Also supportsSetting,Secret, andOutputLengthannotations. Overrideoutput_type()only if the output type depends on input schema. ScalarFunctionGenerator(advanced)- Per-batch callback API for fine-grained control. Override
output_type()andprocess().
class BindParameters
Section titled “class BindParameters”Description
Parameters passed to a scalar function’s bind() method.
Attributes
attribute constant_arguments
Section titled “attribute constant_arguments”Constant arguments provided at query planning time.
attribute arguments_schema
Section titled “attribute arguments_schema”Schema describing the input columns.
attribute settings
Section titled “attribute settings”pa.RecordBatch | None
DuckDB settings as a single-row RecordBatch, or None.
attribute secrets
Section titled “attribute secrets”SecretsAccessor for accessing resolved and dynamic secrets.
attribute auth_context
Section titled “attribute auth_context”Authentication context for the current request.
attribute attach_opaque_data
Section titled “attribute attach_opaque_data”bytes | None
Catalog attach ID, if the function was invoked through an ATTACHed catalog.
attribute transaction_opaque_data
Section titled “attribute transaction_opaque_data”bytes | None
Catalog transaction ID, if invoked inside a catalog transaction.
class BindResult
Section titled “class BindResult”Bases: ArrowSerializableDataclass
Description
Result of calling bind() on a scalar function.
Unlike table functions which return a full schema, scalar functions return a single output type since they produce one value per row.
Attributes
attribute opaque_data
Section titled “attribute opaque_data”ArrowSerializableDataclass | None
Optional serialized data, opaque to the caller,
that will be passed to global_init() and process().
class RowCountMismatchError
Section titled “class RowCountMismatchError”Bases: Exception
Description
Raised when scalar function output row count doesn’t match input.
Scalar functions must produce exactly one output row for each input row.
This error indicates the compute() method returned an array with the
wrong number of elements.
Attributes
attribute input_rows
Section titled “attribute input_rows”int | None
Number of rows in the input batch.
attribute output_rows
Section titled “attribute output_rows”int | None
Number of rows in the output batch.
attribute function_name
Section titled “attribute function_name”str
Name of the function that produced the mismatch.
class ScalarFunction
Section titled “class ScalarFunction”Bases: ScalarFunctionGenerator
Description
Base class for scalar functions (1:1 row mapping, single output column).
Scalar functions transform each input row to exactly one output value.
Use Param/ConstParam/Returns annotations on compute() to declare types.
Type Validation
Input and output types are validated at runtime:
Paramtypes are checked against actual array typesReturnstype is checked againstcompute()resultAnyArrowparameters skip validationTypeMismatchErroris raised on mismatch
Methods to Override
compute(self, …) -> pa.Array- Transform input arrays to output. Use
Param/ConstParamannotations.
output_type(params) -> pa.DataType (classmethod)- Override when output type depends on input schema or arguments.
Methods
method catalog_output_schema
Section titled “method catalog_output_schema”catalog_output_schema() -> pa.SchemaReturn output schema for catalog introspection.
Returns the output schema with a single “result” field using the
type from the Returns() annotation. If no explicit type was declared
(dynamic type), returns null() with metadata indicating “any” type.
method output_type
Section titled “method output_type”output_type(params: BindParameters) -> pa.DataTypeReturn the Arrow type for the output column.
Default implementation uses _returns_output_type from Returns()
annotation. Override when the output type depends on input schema
or arguments (use params.arguments_schema, params.constant_arguments).
method on_bind
Section titled “method on_bind”on_bind(params: BindParameters) -> BindResultProduce the output type during the bind phase.
Override to perform custom bind-time logic such as validating arguments, examining input schema, or computing a dynamic output type.
Note
Constant arguments needed during process() are automatically
serialized by the protocol. The opaque_data field is for
additional bind-time state you need to pass forward.
method process
Section titled “method process”process(
*,
batch: pa.RecordBatch,
init_call: InitRequest,
init_response: BaseInitResponse,
storage: BoundStorage,
auth_context: AuthContext,
) -> pa.RecordBatchConvert compute() to per-batch callback.
This method calls your compute() method for the input batch.
Keyword-only parameters in compute() are automatically populated
from the batch columns.
Inherited members (8)
get_metadatamethod · from MetadataMixin — Get the resolved metadata for this function class.describemethod · from MetadataMixin — Get metadata as a dictionary (for JSON serialization).loggerattribute · from Functionstorageattribute · from FunctionCACHE_CONTROLattribute · from ScalarFunctionGeneratorbindmethod · from ScalarFunctionGenerator — Bind protocol entry point. Do not override; useon_bind()instead.on_initmethod · from ScalarFunctionGenerator — Initialize the function during the init API call.global_initmethod · from ScalarFunctionGenerator — Global init protocol entry point. Do not override; useon_init()instead.
class ScalarFunctionGenerator
Section titled “class ScalarFunctionGenerator”Bases: vgi.function.Function
Description
Per-batch callback base class for scalar functions.
This is the advanced API for scalar functions. For most use cases,
use ScalarFunction instead, which provides a simpler compute() callback.
Scalar functions have these constraints:
- 1:1 row mapping: Output row count must equal input row count
- Single value output: Produces one value per input row
- No finalization: Processing ends when input is exhausted
Methods to Override
output_type(params) -> pa.DataType- Return the Arrow type for the output value. Required.
process(…) -> pa.RecordBatch- Process one input batch. Must return output with same row count. Required.
on_bind(params) -> BindResult- Optional. Override to perform custom bind-time logic.
on_init(…) -> GlobalInitResponse- Optional. Override to perform custom initialization.
Protocol Entry Points (called by worker, do not override)
bind(input) -> BindResponse- Handles the bind API call
global_init(input) -> GlobalInitResponse- Handles the global_init API call
Attributes
attribute CACHE_CONTROL
Section titled “attribute CACHE_CONTROL”CacheControl | None
Opt into the extension’s result cache: when set, this CacheControl’s vgi.cache.* metadata is attached to every output batch, so the C++ side memoizes the scalar’s output per distinct input value (see docs/exchange_dedup_pervalue.md). A pure, deterministic scalar only — advertising this on a non-pure scalar serves stale rows.
Methods
method output_type
Section titled “method output_type”output_type(params: BindParameters) -> pa.DataTypeReturn the Arrow type for the output value.
method on_bind
Section titled “method on_bind”on_bind(params: BindParameters) -> BindResultProduce the output type during the bind API call.
Override to perform custom bind-time logic such as validating arguments or computing a dynamic output type.
method catalog_output_schema
Section titled “method catalog_output_schema”catalog_output_schema() -> pa.SchemaReturn output schema for catalog introspection.
A generator-style scalar function computes its output type at bind
time, so no static type is known here. Report a single dynamic
result column (null() tagged vgi:any) so catalog
consumers treat the type as resolved-at-bind. ScalarFunction
overrides this when a static Returns() type is available.
method bind
Section titled “method bind”bind(
input: BindRequest,
*,
ctx: CallContext | None = None,
attach_plaintext: bytes | None = None,
) -> BindResponseBind protocol entry point. Do not override; use on_bind() instead.
Constructs BindParameters, validates type bounds, calls on_bind(),
and wraps the result for transmission to global_init. If on_bind()
triggers dynamic secret lookups or if compute() declares Secret()
annotations that haven’t been resolved, returns a secret scope request.
method on_init
Section titled “method on_init”on_init(
*,
bind_call: BindRequest,
opaque_data: bytes | None,
storage: BoundStorage,
) -> GlobalInitResponseInitialize the function during the init API call.
Override to perform one-time setup that should happen after bind but before processing batches. The default returns max_processes=1.
method global_init
Section titled “method global_init”global_init(
input: InitRequest,
*,
attach_plaintext: bytes | None = None,
) -> GlobalInitResponseGlobal init protocol entry point. Do not override; use on_init() instead.
Deserializes the wrapped bind data, calls on_init(), and wraps the result for transmission to process().
attach_plaintext is the full framework plaintext (uuid||catalog
bytes) the worker unwrapped; storage shards on its UUID. Scalar
on_init does not expose the attach to bodies, so only storage uses it.
method process
Section titled “method process”process(
*,
batch: pa.RecordBatch,
init_call: InitRequest,
init_response: BaseInitResponse,
storage: BoundStorage,
auth_context: AuthContext,
) -> pa.RecordBatchProcess one input batch.
Override this method to implement your scalar transformation.
Must return an output RecordBatch with exactly the same number
of rows as the input batch.
Inherited members (4)
get_metadatamethod · from MetadataMixin — Get the resolved metadata for this function class.describemethod · from MetadataMixin — Get metadata as a dictionary (for JSON serialization).loggerattribute · from Functionstorageattribute · from Function
class TypeMismatchError
Section titled “class TypeMismatchError”Bases: TypeError
Description
Raised when array type doesn’t match declared parameter or return type.
This error indicates a mismatch between the declared type in Param() or Returns()
and the actual array type at runtime.
Attributes
attribute param_name
Section titled “attribute param_name”str
Name of the parameter with the type mismatch.