Skip to content

v0.4.0 — func_dispatch

Latest

Choose a tag to compare

@teaguesterling teaguesterling released this 14 Oct 01:10
· 11 commits to main since this release
9f11987

Adds func_dispatch(routes, key, args...) and fixes a pre-existing return-type
bug in apply().

Dispatches to the function named by routes[key] (a MAP(VARCHAR,VARCHAR)),
forwarding the remaining arguments, with a '*' wildcard fallback and NULL on a
miss.

CREATE MACRO normalize_name(filename) AS
  func_dispatch(MAP{'git': 'clean_git', 'https': 'clean_http'},
                urlpattern_protocol(filename),
                filename);

Routing a value to one of several functions was already possible with
apply(routes[key], arg). What did not work was typing: with a dynamic function
name apply has nothing to bind against and falls back to VARCHAR, so a
list-returning macro came back as the string '[7, 7]'.

func_dispatch receives the whole routing table, so when it is constant it binds
every candidate at plan time and unifies their return types:

dispatch integer-returning macro list-returning macro
apply, dynamic name 42 VARCHAR '[7, 7]' VARCHAR
func_dispatch, constant map 42 INTEGER [7,7] INTEGER[]

A non-constant routing map still falls back to VARCHAR.

The shared return-type inference substituted a typed NULL for non-foldable
arguments. || folds a NULL operand to SQLNULL, which the binder rewrites to
INTEGER, so this failed at runtime:

CREATE MACRO clean_git(p) AS 'GIT:' || p;
SELECT apply('clean_git', path) FROM t;
-- Could not convert string 'GIT:...' to INT32

Present since the first release. Inference now uses a non-NULL probe value and
never propagates SQLNULL.

  • Routes in a constant map must all accept the forwarded arguments; one that
    cannot is a bind error rather than a silent VARCHAR degradation.
  • Nested argument types (LIST, STRUCT, ...) fall back to VARCHAR identically on
    both supported DuckDB lines.
  • Argument forwarding is positional; alias names are accepted and ignored, as in
    apply.
  • The session security policy applies at run time to every route, including the
    '*' fallback. No SQL text is constructed.

358 assertions across 5 test files, green on DuckDB v1.5.6 and v2.0-cyanoptera.
All documented examples were executed against a built binary.