Skip to content

Releases

v0.4.0 — func_dispatch

Choose a tag to compare

@teaguesterling teaguesterling released this 14 Oct 01:10
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.

v0.3.3 — DuckDB v2.0 (cyanoptera) family-C port

Choose a tag to compare

@teaguesterling teaguesterling released this 03 Oct 20:44
3ba0d30

DuckDB v2.0 (cyanoptera) family-C port.

  • Ports the named_parameter declarations to the FunctionSignature typed-kwargs
    shim so the extension builds on DuckDB v2.0-cyanoptera (where
    named_parameters was removed), while remaining correct on the v1.5.x line.
  • CI gains a real cyanoptera leg (builds and tests on v2.0 on this exact
    commit) plus a version-drift guard, so the v2.0 line is verified in-flight
    rather than only at descriptor-repoint time.

Builds green on both the v1.5.6 and v2.0-cyanoptera lines.

v0.3.2

Choose a tag to compare

@teaguesterling teaguesterling released this 25 Sep 04:29
ba98516

func_apply v0.3.2

DuckDB v2.0 compatibility

  • Build ConstantExpression through a compat shim (#11) — v2.0 changed its construction.
  • Drop the include for a header v2.0 removed (#10).
  • Build against DuckDB v2.0 as well as the pinned v1.5 line (#7).

First func_apply release validated against DuckDB v2.0 (ref == ref_next in the community-extensions descriptor). Supersedes the never-tagged v0.3.1.

v0.3.0

Choose a tag to compare

@teaguesterling teaguesterling released this 06 Sep 07:51
ed51705

Builds against DuckDB 2.0.0 as well as the pinned v1.5 line.

  • DuckDB 2.0 compatibility. CompatName is derived from table_function_bind_t's fourth parameter with a static_assert pinning it, rather than probed for with __has_include — identifier.hpp was backported into v1.5-variegata without the accompanying signature change, so a header-presence probe returns the wrong answer as soon as pins advance. All four Catalog::GetEntry call sites are wrapped, including the templated one in BindApplyWith, along with the child_list_t keys and the FunctionExpression/BindScalarFunction name sites.
  • The security model is documented. Modes (none/blacklist/whitelist/validator) and the func_apply_set_* functions existed but were absent from the README, with the default being mode = "none" — no restrictions. The function table was also incomplete: it named validator as a mode with no documented way to set it.
  • A README example that never worked is fixed. apply_table_with('generate_series', args := [1], kwargs := {stop: 10, step: 2}) errored on every version that shipped it — stop/step are positional parameters, and kwargs is not a keyword-flavoured way to spell them. Replaced with examples that run, plus the first passing tests for apply_table_with's kwargs; the only prior case asserted a failure.
  • Return-type behaviour documented, including that VARCHAR is the fallback when a constant name fails bind-time lookup, not only for dynamic names.

Verified on both lines: main CI green, and the DuckDB-main canary's Build and Test steps both passing — this repo's first green canary on main.

v0.2.0 — Security fix

Choose a tag to compare

@teaguesterling teaguesterling released this 19 Jul 19:13
8c3a74e

Security fix (GHSA-55g5-vp25-phpg)

This release fixes an identifier-injection vulnerability and hardens the extension's security configuration. Community-extensions users on 0.1.0 should upgrade.

  • Identifier injection in apply_table_with — a crafted function name could break out of the reparsed table-function SQL and bypass the extension's own whitelist/blacklist. Injected identifiers are now quoted. Note this was never a privilege escalation against DuckDB: apply runs on the caller's own context and adds no reach beyond the caller's existing SQL. The whitelist is a guardrail for embedding scenarios, and that guardrail is what could be bypassed.
  • Security config is now per-session — the mode and whitelist/blacklist live in per-session state (ClientContext) rather than process-global state, so one connection can't observe or mutate another's configuration, and func_apply_lock_security() binds the session that set it.

Regression test test/sql/func_apply_security_injection.test covers the injection bypass.

DuckDB v1.5.4

Built against DuckDB v1.5.4 (from v1.4.3). Stable builds are green on all platforms (Linux amd64/arm64, macOS amd64/arm64, Windows MSVC/mingw, Wasm ×3).

Known follow-up

The duckdb-next-build leg (DuckDB main/v1.6) does not yet compile — the v1.6 Identifier API migration (named-parameter vectors, Catalog::GetEntry) is tracked separately and does not affect this v1.5.4 release.

v0.1.0

Choose a tag to compare

@teaguesterling teaguesterling released this 23 Feb 23:42

Initial release with DuckDB v1.5 compatibility.

v1.0.0 - Initial Release

Choose a tag to compare

@teaguesterling teaguesterling released this 02 Jan 21:25
Fix formatting

Signed-off-by: Teague Sterling <teaguesterling@gmail.com>