GitHub user haohuaijin closed a discussion: How to evaluate function's args one by one / implement short circuit evaluation
When working on #8927, I find when evaluating a scalar function, we first evaluate all args and then execute the actual function; see below https://github.com/apache/arrow-datafusion/blob/827668ab3d4659329ff30e6672f398c934b803be/datafusion/physical-expr/src/scalar_function.rs#L152-L161 But for a function like `coalesce,` it is a short-circuit function; we should evaluate its args one by one(like we do for `CASE`), otherwise, the below query will get the error: ``` select coalesce(1, 4/0); ``` ------- To do this, I have two ideas ### First change the `ScalarFunctionImplementation` ``` Before pub type ScalarFunctionImplementation = Arc<dyn Fn(&[ColumnarValue]) -> Result<ColumnarValue> + Send + Sync>; ``` ``` After pub type ScalarFunctionImplementation = Arc<dyn Fn(&[Arc<dyn PhysicalExpr], &RecordBatch) -> Result<ColumnarValue> + Send + Sync>; ``` ### Second treat `coalesce` as a specific case in https://github.com/apache/arrow-datafusion/blob/827668ab3d4659329ff30e6672f398c934b803be/datafusion/physical-expr/src/scalar_function.rs#L152-L156 and implement `coalesce` like below ``` (_, Ok(scalar_fun)) if scalar_fun == BuiltinScalarFunction::Coalesce => { return _coalesce(self.args.as_ref(), batch); } ``` ### Third add a function to identify if the function is a short-circuit function, and create the function with different args for non-short-circuit and short-circuit functions(`create_physical_expr`), then add two functions to `ScalarUDFImpl` that make use can create themself short-circuit the function. just like ``` pub trait ScalarUDFImpl: Debug + Send + Sync { ...... fn short_circuit(&self) -> bool { false } fn invoke_short_circuit(&self, args: &[Arc<dyn PhysicalExpr>], batch: &RecordBatch) -> Result<ColumnarValue>; } ``` GitHub link: https://github.com/apache/datafusion/discussions/8959 ---- This is an automatically sent email for [email protected]. To unsubscribe, please send an email to: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
