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]

Reply via email to