How to evaluate function's args one by one / implement short circuit evaluation #8959
Replies: 4 comments
|
In my opinion, the overall solution is reasonable. But I'm not sure about details like the design of the interface. |
|
I agree this is a very reasonable usecase to try and support One challenge is likely to be that Maybe we can take advantage of having a trait for defining scalar functions now, For example, perhaps we could provide a version of invoke like Something like this perhaps 🤔 pub trait ScalarUDFImpl: Debug + Send + Sync {
// existing API in terms of columnar value
fn invoke(&self, args: &[ColumnarValue]) -> Result<ColumnarValue> {
// calls new API invoke_short_circuit
}
/// Evaluate the function without first evaluating arguments.
/// if the function needs values of its arguments, it calls some
/// method on `ArgEvaluator`
fn invoke_short_circuit(&self, args: &dyn ArgEvaluator) {
...
}
} |
|
I think we can use SQL annotations to implement it, like this: -- set short circuited=true |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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 forCASE), otherwise, the below query will get the error:To do this, I have two ideas
First
change the
ScalarFunctionImplementationSecond
treat
coalesceas a specific case in https://github.com/apache/arrow-datafusion/blob/827668ab3d4659329ff30e6672f398c934b803be/datafusion/physical-expr/src/scalar_function.rs#L152-L156and implement
coalescelike belowThird
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 toScalarUDFImplthat make use can create themself short-circuit the function. just likeAll reactions