Skip to content

v0.34.0

Choose a tag to compare

@rustyconover rustyconover released this 18 Sep 03:48
· 206 commits to main since this release

A required ANY argument can validate itself

A function with a required AnyArrow argument had no way to produce a good error when a caller omitted it. The framework parses arguments before on_bind() runs, so the omission surfaced as

KeyError: "Argument 'questions': not found"

instead of the message the function had written for exactly that case. Two things blocked the obvious fix of default=None, and both are now resolved:

  • parameter_default_values_from_specs rejected any default on an ANY-typed parameter. Only a value default is unrepresentable there — None is fine, because a null-typed array holds nulls and it is column presence, not the value, that marks a parameter as having a default. The guard is now narrowed to non-null defaults.
  • The marker types (AnyArrow, AnyArrowValue, TableInput) are recognised by identity, so AnyArrow | None hid the marker: the parameter silently became NULL-typed, and DuckDB could then cast nothing into it (Unimplemented type for cast (STRUCT(...) -> NULL)) at the first real call. Both detection sites now unwrap an optional union, mirroring what _accepts_none already looks for.

Together these let a function declare

questions: Annotated[AnyArrow | None, Arg("questions", default=None)] = None

for an argument that is required in practice but validated by the function itself, with an error that names it.

Verified end to end against a real DuckDB ATTACH: the missing case raises the function's own message, and the struct, JSON-string and correlated LATERAL call shapes all still work when the argument is present. No API changes; existing declarations are unaffected.