ProductDocumentationExamplesBlogRoadmapGitHubGet Started
Available

CREATE FUNCTION

Register a SQL-bodied or Python-bodied function as a callable UDF in the session.

CREATE FUNCTION registers a UDF for the rest of the session. The function can be called from SQL, from the DataFrame API, or from another function.

LANGUAGE SQL

Inline the function body as a SQL query. The query must be a single SELECT (with optional FROM for table-valued functions).

Scalar UDF

CREATE FUNCTION greet(name VARCHAR) RETURNS VARCHAR
LANGUAGE SQL
AS 'SELECT CONCAT(''hello, '', name)';

Call it like any built-in function:

SELECT greet('world');   -- "hello, world"

Table-valued function (TVF)

CREATE FUNCTION recent_orders(cust_id BIGINT)
RETURNS TABLE (order_id BIGINT, amount DOUBLE, ts TIMESTAMP)
LANGUAGE SQL
AS 'SELECT order_id, amount, ts FROM orders
    WHERE customer_id = cust_id
    ORDER BY ts DESC LIMIT 10';

Call it in the FROM clause:

SELECT * FROM recent_orders(42);

LANGUAGE PYTHON

Pass a Python callable. Krishiv wraps the call in a Tokio task and serialises via Arrow C Data Interface.

import krishiv as ks
session = ks.Session.embedded()

@ks.udf(return_type="utf8")
def greet(name: str) -> str:
    return f"hello, {name}"

session.register_udf("greet", greet, ["utf8"], "utf8")
session.sql("SELECT greet('world')").show()

Equivalently, the session's register_scalar_udf and register_aggregate_udf methods accept Rust- or Python-implemented UDFs.

Function lifecycle

Functions are session-scoped. They are dropped on session close. To persist across sessions, use a startup script or the deployment's bootstrap mechanism.

Overloading

You can register multiple functions with the same name and different argument types. The planner picks the best match for each call site. If no match exists, you get a clear type error.

Security

Preview: LANGUAGE PYTHON is gated by the python Cargo feature. In production profiles (KRISHIV_PRODUCTION=1) native scalar UDFs are forbidden by default; enable them only via KRISHIV_ALLOW_FULL_PRIVILEGE_UDFS=1 after reviewing the security implications.

See also