risingwavelabs/risingwave · critical
multiple arguments are not supported for non-option function
Error message
multiple arguments are not supported for non-option function
What it means
This panic comes from the `#[function]` macro's aggregate/codegen builder in src/expr/macro/src/gen.rs. When generating the state-transition expression for an aggregate whose underlying function is not written over `Option<T>` arguments, the macro only supports single-argument forms; a multi-argument (two-or-more params) non-option function hits a `todo!()` placeholder, deliberately aborting expansion. It signals an unsupported codegen case, not a runtime fault.
Source
Thrown at src/expr/macro/src/gen.rs:1007
quote! {{
let state = self.function.create_state();
#next_state
}}
} else {
quote! {{
let state = #state_type::default();
#next_state
}}
};
next_state = quote! {
match (state, v0) {
(Some(state), Some(v0)) => #next_state,
(None, Some(v0)) => #first_state,
(state, None) => state,
}
};
}
_ => todo!("multiple arguments are not supported for non-option function"),
}
}
let update_state = if custom_state.is_some() {
quote! { _ = #next_state; }
} else {
quote! { state = #next_state; }
};
let get_result = if custom_state.is_some() {
quote! { Ok(state.downcast_ref::<#state_type>().into()) }
} else if let AggregateFnOrImpl::Impl(impl_) = user_fn
&& impl_.finalize.is_some()
{
quote! {
let state = match state.as_datum() {
Some(s) => s.as_scalar_ref_impl().try_into().unwrap(),
None => return Ok(None),
};
Ok(Some(self.function.finalize(state).into()))View on GitHub (pinned to 6469eb736d)
Solutions
- Rewrite the function so each argument is wrapped in `Option<T>` (the macro's supported multi-arg path), e.g. `fn my_agg(a: Option<i64>, b: Option<i64>) -> i64` and handle None cases in the body.
- Split the aggregate into a single-argument function, or pre-combine arguments before aggregation.
- If support is genuinely needed, replace the `todo!()` in gen.rs with codegen that folds over multiple `#vN` inputs, and add a test.
Example fix
// before - panics at macro expansion
#[function("my_agg(int8, int8)")]
fn my_agg(a: i64, b: i64) -> i64 { a + b }
// after - Option-wrapped args are supported
#[function("my_agg(int8, int8)")]
fn my_agg(a: Option<i64>, b: Option<i64>) -> i64 {
match (a, b) { (Some(a), Some(b)) => a + b, _ => 0 }
} Defensive patterns
Strategy: validation
Validate before calling
// Before declaring the aggregate, check the fn arity / Option-wrapping
fn is_macro_compatible_agg(sig: &str) -> bool {
// only single-arg non-Option fns or Option-wrapped args are supported
let args = sig.split('(').nth(1).unwrap_or("");
let argc = args.split(',').filter(|a| !a.trim().is_empty()).count();
argc == 1 || sig.contains("Option<")
}
assert!(is_macro_compatible_agg("my_agg(int8, int8)")); // panics here first, before cargo build Prevention
- Prefer Option<T>-wrapped arguments for multi-argument aggregate functions — that is the macro's supported multi-arg path.
- Search existing aggregate declarations in src/expr for the pattern you need and copy it.
- Keep `todo!()` occurrences in gen.rs on your radar when bumping macro complexity; run `cargo check` on the crate early.
When it happens
Trigger: Declaring an aggregate (e.g. via `#[aggregate]` / generate_aggregate_descriptor) whose `accumulate`-style function takes 2+ arguments and whose signature is not the `Option<T>`-argument form the macro handles (Some/None match arms). Any `#[function("agg(...) ...")]` aggregate built from a multi-arg plain (non-Option) function.
Common situations: Contributors adding a new SQL aggregate function in RisingWave write a plain multi-argument Rust function and mark it as an aggregate; older macro versions only implemented the single-arg and Option-wrapped cases, so upgrades or new function shapes hit the unimplemented branch.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- You can't use the macro on this type
- Expected #[serde_prefix_all(skip)]
- type inference function cannot be automatically derived. You
- SIMD optimization for {n} arguments
- expect `impl Iterator` in return type
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/4192b723dc1d6c8f.
Report an issue: GitHub.