{"record":{"id":"61d79177bd24007b","repo":"databendlabs/databend","slug":"typed-calc-domain-must-be-specified","errorCode":null,"errorMessage":"typed calc_domain must be specified","messagePattern":"typed calc_domain must be specified","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/expression/src/function/function_builder.rs","lineNumber":387,"sourceCode":"\n    pub fn derive_stat(\n        mut self,\n        func: fn(StatCardinality, ctx: &FunctionContext) -> Result<Option<ReturnStat>, String>,\n    ) -> Self {\n        self.derive_stat = Some(DeriveStat::Nullary(func));\n        self\n    }\n\n    pub fn vectorized<F>(self, eval: F) -> B\n    where F: VectorizedFn0<O> + 'static {\n        let Self {\n            builder,\n            return_type,\n            calc_domain,\n            derive_stat,\n        } = self;\n        let mut builder = builder;\n        let calc_domain = calc_domain.expect(\"typed calc_domain must be specified\");\n\n        let signature = FunctionSignature {\n            name: builder.name().to_string(),\n            args_type: Vec::new(),\n            return_type: return_type.clone(),\n        };\n\n        let calc_wrapper = TypedNullaryCalcDomain {\n            calc_domain,\n            return_type: return_type.clone(),\n            _marker: PhantomData,\n        };\n        let eval_wrapper = TypedNullaryFunction {\n            func: eval,\n            return_type,\n            _marker: PhantomData,\n        };\n","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/function/function_builder.rs#L369-L405","documentation":"`TypedNullaryFunctionBuilder::vectorized` requires a typed `calc_domain` (the function's nullability/domain calculus) to have been set before building the final `FunctionEval::Scalar`. It is `None` here, so the builder panics. `calc_domain` is mandatory because the constant folder consults it for every scalar function evaluation.","triggerScenarios":"Building a nullary (zero-argument) function via `TypedNullaryFunctionBuilder` and calling `vectorized` without first calling `.calc_domain(...)`, or a code path that conditionally skips the `calc_domain` call.","commonSituations":"Registering a new zero-argument function (e.g. `now()`, `version()`) and omitting the domain specification; copy-pasting a registration snippet from a non-typed builder; a refactor that renamed the `calc_domain` call site.","solutions":["Call `.calc_domain(...)` on the builder (typically `CalcDomain::full` for functions whose nullability doesn't depend on inputs) before `vectorized`.","Use the crate's registration macros that supply a default calc_domain for nullary functions.","Review the builder chain so every required setter appears before the terminal build call."],"exampleFix":"// before\nlet f = TypedNullaryFunctionBuilder::new(\"pi\")\n    .return_type(DataType::Number(f64))\n    .vectorized(...);\n// after\nlet f = TypedNullaryFunctionBuilder::new(\"pi\")\n    .return_type(DataType::Number(f64))\n    .calc_domain(CalcDomain::full)\n    .vectorized(...);","handlingStrategy":"validation","validationCode":"// before vectorized():\nassert!(calc_domain_set, \"calc_domain must be set before vectorized\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Include `.calc_domain(...)` immediately after `return_type` in every nullary function builder chain.","Use `CalcDomain::full` as the default for nullability-independent functions.","Run existing function test suites when adding new registrations."],"tags":["rust","builder-pattern","calc-domain"],"backgroundTag":"missing-required-argument","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}