Skip to main content
chDB allows you to register Python functions as SQL-callable UDFs. These run natively in-process — no subprocess spawning, no serialization overhead. Functions are type-safe, support automatic type inference from Python annotations, and offer configurable NULL and exception handling.

Quick start

Examples in this guide run query() with the default CSV output format. Inline comments show the logical result values; the raw output prints NULL as \N and applies CSV quoting to string and date values (for example "Hello, world!").

Registration methods

@func decorator

The simplest way to register a UDF. The function’s __name__ becomes the SQL function name.
The decorated function remains callable as normal Python:

create_function

Register any callable (lambda, function, method) with an explicit name:

drop_function

Remove a registered UDF. Dropping a name that is not registered does nothing, so it is safe to call unconditionally:
Registering a name that is already registered raises an error — UDFs are not silently replaced. Call drop_function(name) first to re-register a function, for example when re-running a notebook cell.

Type system

Available types

All types are importable from chdb.sqltypes:

Specifying types

Types can be provided in four ways:

Automatic type inference

When arg_types or return_type is omitted, chDB infers types from Python type annotations:
If arg_types is provided explicitly, it must cover all parameters — partial explicit + partial inferred is not supported. This applies to both create_function and the @func decorator: either specify types for all parameters, or omit them entirely and let chDB infer from annotations.
A return type is always required: if return_type is omitted and the function has no return annotation, registration fails. Argument types, by contrast, are optional — a parameter with neither an explicit type nor an annotation accepts any supported input type dynamically.

NULL handling

The on_null parameter controls behavior when any input argument is NULL. You can also use the enum: chdb.NullHandling.SKIP / chdb.NullHandling.PASS.

Example: default (skip)

Example: pass NULL as None

Example: multiple arguments

Exception handling

The on_error parameter controls behavior when the Python function raises an exception. You can also use the enum: chdb.ExceptionHandling.PROPAGATE / chdb.ExceptionHandling.IGNORE.

Example: default (propagate)

Example: ignore errors

Combining NULL and exception handling

The on_null and on_error options can be combined:

DateTime and timezone support

UDFs fully support date and time types with timezone awareness.

Date types

DateTime with timezones

DateTime64 (high precision)

DATETIME64 defaults to scale 6 (microseconds):
  • Input DateTime/DateTime64 values carry timezone info from ClickHouse
  • Output datetime objects preserve timezone info
  • Timezone conversion is handled automatically

Using UDFs with sessions

UDFs are registered globally and available across all sessions in the same process:
Last modified on July 30, 2026