martin-g commented on code in PR #20097:
URL: https://github.com/apache/datafusion/pull/20097#discussion_r2754439897
##########
datafusion/physical-expr/src/expressions/case.rs:
##########
@@ -961,32 +962,40 @@ impl CaseBody {
let then_batch = filter_record_batch(batch, &when_filter)?;
let then_value = self.when_then_expr[0].1.evaluate(&then_batch)?;
- let else_selection = not(&when_value)?;
- let else_filter = create_filter(&else_selection, optimize_filter);
- let else_batch = filter_record_batch(batch, &else_filter)?;
-
- // keep `else_expr`'s data type and return type consistent
- let e = self.else_expr.as_ref().unwrap();
- let return_type = self.data_type(&batch.schema())?;
- let else_expr = try_cast(Arc::clone(e), &batch.schema(),
return_type.clone())
- .unwrap_or_else(|_| Arc::clone(e));
-
- let else_value = else_expr.evaluate(&else_batch)?;
-
- Ok(ColumnarValue::Array(match (then_value, else_value) {
- (ColumnarValue::Array(t), ColumnarValue::Array(e)) => {
- merge(&when_value, &t, &e)
- }
- (ColumnarValue::Scalar(t), ColumnarValue::Array(e)) => {
- merge(&when_value, &t.to_scalar()?, &e)
- }
- (ColumnarValue::Array(t), ColumnarValue::Scalar(e)) => {
- merge(&when_value, &t, &e.to_scalar()?)
+ match &self.else_expr {
+ None => {
+ let then_array = then_value.to_array(when_value.true_count())?;
+ scatter(&when_value,
then_array.as_ref()).map(ColumnarValue::Array)
}
- (ColumnarValue::Scalar(t), ColumnarValue::Scalar(e)) => {
- merge(&when_value, &t.to_scalar()?, &e.to_scalar()?)
+ Some(else_expr) => {
+ let else_selection = not(&when_value)?;
+ let else_filter = create_filter(&else_selection,
optimize_filter);
+ let else_batch = filter_record_batch(batch, &else_filter)?;
+
+ // keep `else_expr`'s data type and return type consistent
+ let return_type = self.data_type(&batch.schema())?;
+ let else_expr =
+ try_cast(Arc::clone(else_expr), &batch.schema(),
return_type.clone())
+ .unwrap_or_else(|_| Arc::clone(else_expr));
Review Comment:
Why there is a fallback here ?
In which case the types may not match and the fallback is needed ?
##########
datafusion/physical-expr/src/expressions/case.rs:
##########
@@ -659,7 +660,7 @@ impl CaseExpr {
&& body.else_expr.as_ref().unwrap().as_any().is::<Literal>()
{
EvalMethod::ScalarOrScalar
- } else if body.when_then_expr.len() == 1 &&
body.else_expr.is_some() {
+ } else if body.when_then_expr.len() == 1 {
EvalMethod::ExpressionOrExpression(body.project()?)
Review Comment:
https://github.com/pepijnve/datafusion/blob/0d640690aa665da749d30148e6a9c6440d2020db/datafusion/physical-expr/src/expressions/case.rs#L76
says `... and both the `then` and `else` are expressions`. But this change
makes the else part optional.
Should ExpressionOrExpression's docstring be updated ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]