Search Shortcut cmd + k | ctrl + k
func_apply

Dynamic function invocation - call any scalar function or macro by name at runtime

Maintainer(s): teaguesterling

Installing and Loading

INSTALL func_apply FROM community;
LOAD func_apply;

Example

-- Load the extension
LOAD func_apply;

-- Call scalar functions dynamically
SELECT apply('upper', 'hello world');
-- Result: HELLO WORLD

SELECT apply('substr', 'hello world', 7, 5);
-- Result: world

-- Call table functions dynamically
SELECT * FROM apply_table('range', 5);
-- Returns: 0, 1, 2, 3, 4

SELECT * FROM apply_table('generate_series', 1, 10, 2);
-- Returns: 1, 3, 5, 7, 9

-- Check if a function exists before calling
SELECT function_exists('my_custom_func');
-- Result: true/false

About func_apply

The FuncApply extension enables dynamic function invocation in DuckDB, allowing you to call any scalar function or macro by name at runtime. This is useful for data-driven transformations, dynamic SQL generation, and building flexible data pipelines.

Functions

Function Description
apply(func_name, ...args) Call a function by name with arguments
apply_with(func_name, args, kwargs) Call a function with arguments as a list
apply_table(func_name, ...args) Call a table function by name with arguments
apply_table_with(func_name, args, kwargs) Call a table function with arguments as a list
function_exists(name) Check if a function exists

Use Cases

Data-Driven Transformations

-- Store transformation rules in a table
CREATE TABLE transforms (column_name VARCHAR, func_name VARCHAR);
INSERT INTO transforms VALUES ('name', 'upper'), ('email', 'lower');

-- Apply transformations dynamically
SELECT apply(t.func_name, d.value) as result
FROM data d JOIN transforms t ON d.column = t.column_name;

Dynamic Function Selection

-- Choose function based on data type
SELECT apply(
    CASE typeof(value)
        WHEN 'VARCHAR' THEN 'upper'
        WHEN 'INTEGER' THEN 'abs'
    END,
    value
) FROM my_table;

Supported Function Types

  • Scalar functions (e.g., upper, abs, substr)
  • Macros (e.g., list_sum, list_reverse)

Aggregate and table functions are not supported.

Security Model

apply and apply_table run on the caller's own context — they add no privilege beyond the SQL the caller could already execute directly. They are a dynamic-dispatch convenience, not a sandbox.

For scenarios that embed func_apply and want to restrict which functions can be invoked (e.g. accepting a function name from less-trusted input), an optional, opt-in policy is available. It is per session and defaults to none (no restriction):

Function Description
func_apply_set_security_mode(mode) 'none', 'blacklist', 'whitelist', or 'validator'
func_apply_set_whitelist([...]) / func_apply_set_blacklist([...]) Set the allowed/denied function names
func_apply_lock_security() Irreversibly lock the current session's policy

The policy lives on the session's ClientContext and does not leak across connections. Versions before 0.2.0 stored it process-globally and could quote-escape injected identifiers — see security advisory GHSA-55g5-vp25-phpg; upgrade to 0.2.0 (DuckDB v1.5.4 track).

Added Functions

function_name function_type description comment examples
apply scalar NULL NULL  
apply_table table Dynamically invoke a table function by name with variable arguments. NULL [SELECT * FROM apply_table('range', 5)]
apply_table_with table Dynamically invoke a table function with structured args and kwargs. NULL [SELECT * FROM apply_table_with('range', args := [5])]
apply_with scalar Dynamically invoke a scalar function with a list of positional args and struct of kwargs. NULL [apply_with('upper', args := ['hello'])]
func_apply_get_security_config scalar Get the current security configuration as a JSON string. NULL [func_apply_get_security_config()]
func_apply_lock_security scalar Lock the current security configuration to prevent further modifications. NULL [func_apply_lock_security()]
func_apply_set_blacklist scalar Set the list of disallowed functions in blacklist security mode. NULL [func_apply_set_blacklist(['system', 'read_csv'])]
func_apply_set_block_default scalar Set the default return value when a blocked function is encountered. NULL [func_apply_set_block_default('BLOCKED')]
func_apply_set_on_block scalar Set behavior when a blocked function is called ('error', 'null', or 'default'). NULL [func_apply_set_on_block('error')]
func_apply_set_security_mode scalar Set the security mode for dynamic function execution ('permissive', 'whitelist', or 'blacklist'). NULL [func_apply_set_security_mode('permissive')]
func_apply_set_validator scalar Set a custom SQL validator function to check candidate function invocations. NULL [func_apply_set_validator('my_validator')]
func_apply_set_whitelist scalar Set the list of allowed functions in whitelist security mode. NULL [func_apply_set_whitelist(['upper', 'lower', 'abs'])]
function_exists scalar Check if a function exists in the catalog. NULL [function_exists('upper')]

Overloaded Functions

This extension does not add any function overloads.

Added Types

This extension does not add any types.

Added Settings

This extension does not add any settings.