Files
lancedb/docs/web/sql/ddl/function.mdx
T
Brendan Clement 1db0d3ca5f docs: label early access features and hide ones not ready to document (#4855)
Labels early access features and hides features we aren't documenting
yet.

**Early access label:** Functions (4 pages, plus the GPU refresh,
checkpointing and adaptive execution pages), Secrets (3 pages), Tiered
Index Cache, Blob V2, and merge insert, which is labelled for Enterprise
only. Two sidebar titles are shorter so the tag fits.

**Hidden:** branching, JSON columns and geospatial.
- The JSON functions page and the agent branch-experiments tutorial go
in `.mintignore`.
- `tables/branching` stays reachable but out of the nav, as #4859 left
it, because SDK error messages link to it.
- Other pages' mentions of these features become draft comments, so
they're easy to restore.

**Secrets page:** drops references to manual KMS setup, which the
control plane handles. It keeps the encryption-at-rest facts, states the
Azure value-size limit inline, and points a 501 error to support.
2026-11-05 00:13:02 -08:00

170 lines
6.4 KiB
Plaintext

---
title: "Function"
tag: "Early access"
sidebarTitle: "Function"
description: "Create, describe, alter, list, and drop registered functions with SQL."
icon: function
keywords: ["create function", "drop function", "show functions", "sql", "udf"]
availability:
embedded: unavailable
enterprise: available
---
<Badge color="purple">Early access</Badge>
[SQL runs in LanceDB Enterprise.](/sql)
## CREATE FUNCTION {#create}
<CodeGroup>
```sql SQL icon="database"
CREATE FUNCTION f(x int64) RETURNS int64
LANGUAGE python
AS 'def f(x): return x * 2'
WITH (pip = 'numpy==1.26.4', python_version = '3.11')
```
</CodeGroup>
A function takes more than one parameter; each one binds a separate column
or literal where the function is called:
<CodeGroup>
```sql SQL icon="database"
CREATE FUNCTION ratio(numerator float64, denominator float64) RETURNS float64
LANGUAGE python
AS 'def ratio(numerator, denominator): return numerator / denominator'
```
</CodeGroup>
Parameter and result types are Arrow type names, not SQL ones: `int64`,
`float64`, `utf8`, `bool`, `date32`, and lists such as `list<float32>` or
`fixed_size_list<float32, 768>`. `BIGINT` is refused. A parameter accepts nulls
unless it is declared `NOT NULL`.
The body is Python source. Its dependencies are declared with it and are part
of the **immutable function version**. Changing one produces a new version
rather than altering the registered one, so a column filled by an earlier
version is unaffected.
| Option | |
| --- | --- |
| `pip` | pip requirements for the worker environment |
| `conda` | conda packages instead of pip |
| `conda_channels` | channels in priority order; requires `conda` |
| `apt` | OS packages to install in the worker environment |
| `image` | a specific container image to run the worker in, such as `'host/repo@sha256:...'` |
| `python_version` | worker Python version; `3.12` when omitted, whatever Python you send the statement from |
| `gpu` | `'true'` when every execution needs a GPU |
| `gpu_class` | which configured GPU class to run on, when `gpu = 'true'` |
| `result_stability` | `'input_and_context'` or `'per_call'` |
| `batch_size` | maximum rows per Function call |
| `row_timeout_seconds` | per-row (or per-batch, for a vectorized Function) execution timeout |
**Errors and limits**
| | |
| --- | --- |
| `LANGUAGE` other than `python` | refused |
| `pip` and `conda` together | refused (pick one) |
| `conda_channels` without `conda` | refused |
| `gpu` set to anything but `'true'` | refused |
| An empty body | refused |
| Any other option | refused, and the message lists what is supported |
<Note>
**Enterprise job type:** `create_function`. Registration returns a job because
the function is baked into an image before the version becomes usable.
</Note>
## Artifact registration {#artifact}
`CREATE FUNCTION name FROM '<registration JSON>'` accepts the artifact,
signature, runtime, optional secret bindings, and result stability produced by
the SDK's registration request. Omit its `name` property because the SQL
identifier supplies it. Escape apostrophes in the JSON as doubled apostrophes.
By default, the command waits for its internal image-build job to publish the
version, then returns one UTF-8 `definition` column containing FunctionVersion
JSON. `WITH (wait = false)` instead returns the existing image-build registry
job ID in `job_id`, with `operation` and `status` columns. The SDK's ordinary
registration handle has type `query` and uses the SQL query UUID as its single
`id`; the internal image-build job has type `create_function`.
## DESCRIBE and ALTER FUNCTION {#describe-alter}
```sql
DESCRIBE FUNCTION embed WITH (version = '1', include_source = true)
```
DESCRIBE returns one `definition` JSON column for the exact version.
`include_source` defaults to false; source-inclusive reads report an omission
when the stored artifact exceeds the inline source limit.
`ALTER FUNCTION name FROM '<pinned update JSON>'` accepts a `reference` with
name, namespace, object ID, location, version, and manifest digest, plus optional
`metadata` and `disabled` updates. The command checks that reference before
appending a revision and returns the resulting `definition` JSON.
## Call it {#call}
Once registered, a function is callable by name in any query, the same as a
built-in scalar function:
<CodeGroup>
```sql SQL icon="database"
SELECT id, f(x) AS doubled FROM my_table
```
</CodeGroup>
This is also the fastest way to check a new registration before binding it to
a column: call it over a few rows, or over literal arguments, before
committing to [a computed column](/sql/ddl/table#computed-column) that fills
from it.
## SHOW FUNCTIONS {#show}
<CodeGroup>
```sql SQL icon="database"
SHOW FUNCTIONS
SHOW FUNCTIONS HISTORY IN "analytics" WITH (name = 'embed', limit = 100)
SHOW FUNCTIONS HISTORY WITH (after_name = 'embed', after_version = '1', limit = 100)
```
</CodeGroup>
`SHOW FUNCTIONS` returns the highest published numeric revision for each name.
Add `HISTORY` to list every published revision, as Python's `list_functions()`
does. Rows are ordered by name and numeric revision, so `2` comes before `10`.
`after_name` and `after_version` must be supplied together for keyset pagination.
`limit` bounds
the response; `include_definition = false` omits the optional definition JSON.
## DROP FUNCTION {#drop}
<CodeGroup>
```sql SQL icon="database"
DROP FUNCTION embed WITH (version = '1')
DROP FUNCTION IF EXISTS embed WITH (version = '1')
```
</CodeGroup>
DROP removes only the requested revision from lookup and listing. Other
published revisions and their grants remain available. Dropping the last visible
revision releases the name and object binding; physical cleanup continues
separately. The result reports `dropped` or `not_found`. `IF EXISTS` allows a
missing name or a repeated drop of a previously published revision. A revision
that was never published under an existing name is an error.
All function object commands retain shared results even when general query-result
copying is disabled, so asynchronous polling can resume on another query node.
## What to read next {#next}
<CardGroup cols={2}>
<Card title="Function" icon="function" href="/management/function">
Registering one from the SDK, and diagnosing environment mismatches.
</Card>
<Card title="Computed columns" icon="table-columns" href="/feature-engineering/add-computed-column">
Filling a column with a function instead of an expression.
</Card>
</CardGroup>