User-defined functions

User-Defined Functions (UDFs) allow you to extend FeatureQL language capabilities by implementing custom functions in the target language.

There are typically two main types of User-Defined Functions (UDFs):

Scalar UDFs

  • Takes one or more input parameters and returns a single value
  • Executes once for each row in the result set
  • Common use cases: string manipulation, custom calculations, data transformations
  • Example: Creating a function to format phone numbers or calculate age from birthdate

Table-Valued UDFs (TVFs)

  • Returns a table result set rather than a single value
  • Can process multiple rows and return multiple columns
  • Often used for more complex data transformations or business logic
  • Example: A function that takes a date range and returns a detailed sales analysis

While the UDF capability supports only Scalar UDFs and is currently experimental, it provides powerful customization options through configurations and templating.

Implementing a UDF

To create a UDF, you'll need to provide a JSON configuration dictionary with the following required fields:

  • positions: Maps positional arguments to named parameters
  • variants: Defines the supported function signatures (input and output types)
  • template_{target}: Specifies transpilation rules for different systems (supported: featureql, trino, duckdb, datafusion)

UDFs in action

Here's an example that implements a custom normalized_quarter() function:

This configuration:

  • Defines a function taking a date or timestamp as an argument
  • Returns a string representing the normalized quarter
  • Uses Jinja2 syntax for template-based transpilation

Avoid UDFs when possible

Avoid creating UDFs when native FeatureQL functions can achieve almost the same result.

For example, the normalized_quarter() function above could be written as a regular feature. UDFs is just useful to support polymorphism here.

or even a macro:

Last update at: 2025/10/13 10:23:46