@@ -205,10 +205,15 @@ impl CaseExpr {
205205        let  mut  current_value = new_null_array ( & return_type,  batch. num_rows ( ) ) ; 
206206        // We only consider non-null values while comparing with whens 
207207        let  mut  remainder = not ( & base_nulls) ?; 
208+         let  mut  non_null_remainder_count = remainder. true_count ( ) ; 
208209        for  i in  0 ..self . when_then_expr . len ( )  { 
209-             let  when_value = self . when_then_expr [ i] 
210-                 . 0 
211-                 . evaluate_selection ( batch,  & remainder) ?; 
210+             // If there are no rows left to process, break out of the loop early 
211+             if  non_null_remainder_count == 0  { 
212+                 break ; 
213+             } 
214+ 
215+             let  when_predicate = & self . when_then_expr [ i] . 0 ; 
216+             let  when_value = when_predicate. evaluate_selection ( batch,  & remainder) ?; 
212217            let  when_value = when_value. into_array ( batch. num_rows ( ) ) ?; 
213218            // build boolean array representing which rows match the "when" value 
214219            let  when_match = compare_with_eq ( 
@@ -224,41 +229,46 @@ impl CaseExpr {
224229                _ => Cow :: Owned ( prep_null_mask_filter ( & when_match) ) , 
225230            } ; 
226231            // Make sure we only consider rows that have not been matched yet 
227-             let  when_match  = and ( & when_match,  & remainder) ?; 
232+             let  when_value  = and ( & when_match,  & remainder) ?; 
228233
229-             // When no rows available for when clause, skip then clause 
230-             if  when_match. true_count ( )  == 0  { 
234+             // If the predicate did not match any rows, continue to the next branch immediately 
235+             let  when_match_count = when_value. true_count ( ) ; 
236+             if  when_match_count == 0  { 
231237                continue ; 
232238            } 
233239
234-             let  then_value = self . when_then_expr [ i] 
235-                 . 1 
236-                 . evaluate_selection ( batch,  & when_match) ?; 
240+             let  then_expression = & self . when_then_expr [ i] . 1 ; 
241+             let  then_value = then_expression. evaluate_selection ( batch,  & when_value) ?; 
237242
238243            current_value = match  then_value { 
239244                ColumnarValue :: Scalar ( ScalarValue :: Null )  => { 
240-                     nullif ( current_value. as_ref ( ) ,  & when_match ) ?
245+                     nullif ( current_value. as_ref ( ) ,  & when_value ) ?
241246                } 
242247                ColumnarValue :: Scalar ( then_value)  => { 
243-                     zip ( & when_match ,  & then_value. to_scalar ( ) ?,  & current_value) ?
248+                     zip ( & when_value ,  & then_value. to_scalar ( ) ?,  & current_value) ?
244249                } 
245250                ColumnarValue :: Array ( then_value)  => { 
246-                     zip ( & when_match ,  & then_value,  & current_value) ?
251+                     zip ( & when_value ,  & then_value,  & current_value) ?
247252                } 
248253            } ; 
249254
250-             remainder = and_not ( & remainder,  & when_match) ?; 
255+             remainder = and_not ( & remainder,  & when_value) ?; 
256+             non_null_remainder_count -= when_match_count; 
251257        } 
252258
253259        if  let  Some ( e)  = self . else_expr ( )  { 
254-             // keep `else_expr`'s data type and return type consistent 
255-             let  expr = try_cast ( Arc :: clone ( e) ,  & batch. schema ( ) ,  return_type. clone ( ) ) ?; 
256260            // null and unmatched tuples should be assigned else value 
257261            remainder = or ( & base_nulls,  & remainder) ?; 
258-             let  else_ = expr
259-                 . evaluate_selection ( batch,  & remainder) ?
260-                 . into_array ( batch. num_rows ( ) ) ?; 
261-             current_value = zip ( & remainder,  & else_,  & current_value) ?; 
262+ 
263+             if  remainder. true_count ( )  > 0  { 
264+                 // keep `else_expr`'s data type and return type consistent 
265+                 let  expr = try_cast ( Arc :: clone ( e) ,  & batch. schema ( ) ,  return_type. clone ( ) ) ?; 
266+ 
267+                 let  else_ = expr
268+                     . evaluate_selection ( batch,  & remainder) ?
269+                     . into_array ( batch. num_rows ( ) ) ?; 
270+                 current_value = zip ( & remainder,  & else_,  & current_value) ?; 
271+             } 
262272        } 
263273
264274        Ok ( ColumnarValue :: Array ( current_value) ) 
@@ -277,10 +287,15 @@ impl CaseExpr {
277287        // start with nulls as default output 
278288        let  mut  current_value = new_null_array ( & return_type,  batch. num_rows ( ) ) ; 
279289        let  mut  remainder = BooleanArray :: from ( vec ! [ true ;  batch. num_rows( ) ] ) ; 
290+         let  mut  remainder_count = batch. num_rows ( ) ; 
280291        for  i in  0 ..self . when_then_expr . len ( )  { 
281-             let  when_value = self . when_then_expr [ i] 
282-                 . 0 
283-                 . evaluate_selection ( batch,  & remainder) ?; 
292+             // If there are no rows left to process, break out of the loop early 
293+             if  remainder_count == 0  { 
294+                 break ; 
295+             } 
296+ 
297+             let  when_predicate = & self . when_then_expr [ i] . 0 ; 
298+             let  when_value = when_predicate. evaluate_selection ( batch,  & remainder) ?; 
284299            let  when_value = when_value. into_array ( batch. num_rows ( ) ) ?; 
285300            let  when_value = as_boolean_array ( & when_value) . map_err ( |_| { 
286301                internal_datafusion_err ! ( "WHEN expression did not return a BooleanArray" ) 
@@ -293,14 +308,14 @@ impl CaseExpr {
293308            // Make sure we only consider rows that have not been matched yet 
294309            let  when_value = and ( & when_value,  & remainder) ?; 
295310
296-             // When no rows available for when clause, skip then clause 
297-             if  when_value. true_count ( )  == 0  { 
311+             // If the predicate did not match any rows, continue to the next branch immediately 
312+             let  when_match_count = when_value. true_count ( ) ; 
313+             if  when_match_count == 0  { 
298314                continue ; 
299315            } 
300316
301-             let  then_value = self . when_then_expr [ i] 
302-                 . 1 
303-                 . evaluate_selection ( batch,  & when_value) ?; 
317+             let  then_expression = & self . when_then_expr [ i] . 1 ; 
318+             let  then_value = then_expression. evaluate_selection ( batch,  & when_value) ?; 
304319
305320            current_value = match  then_value { 
306321                ColumnarValue :: Scalar ( ScalarValue :: Null )  => { 
@@ -317,10 +332,11 @@ impl CaseExpr {
317332            // Succeed tuples should be filtered out for short-circuit evaluation, 
318333            // null values for the current when expr should be kept 
319334            remainder = and_not ( & remainder,  & when_value) ?; 
335+             remainder_count -= when_match_count; 
320336        } 
321337
322338        if  let  Some ( e)  = self . else_expr ( )  { 
323-             if  remainder . true_count ( )  > 0  { 
339+             if  remainder_count  > 0  { 
324340                // keep `else_expr`'s data type and return type consistent 
325341                let  expr = try_cast ( Arc :: clone ( e) ,  & batch. schema ( ) ,  return_type. clone ( ) ) ?; 
326342                let  else_ = expr
0 commit comments