@@ -375,7 +375,44 @@ impl PhysicalExpr for BinaryExpr {
375375                // as it takes into account cases where the selection contains null values. 
376376                let  batch = filter_record_batch ( batch,  selection) ?; 
377377                let  right_ret = self . right . evaluate ( & batch) ?; 
378-                 return  pre_selection_scatter ( selection,  right_ret) ; 
378+ 
379+                 match  & right_ret { 
380+                     ColumnarValue :: Array ( array)  => { 
381+                         // When the array on the right is all true or all false, skip the scatter process 
382+                         let  boolean_array = array. as_boolean ( ) ; 
383+                         let  true_count = boolean_array. true_count ( ) ; 
384+                         let  length = boolean_array. len ( ) ; 
385+                         if  true_count == length { 
386+                             return  Ok ( lhs) ; 
387+                         }  else  if  true_count == 0  && boolean_array. null_count ( )  == 0  { 
388+                             // If the right-hand array is returned at this point,the lengths will be inconsistent; 
389+                             // returning a scalar can avoid this issue 
390+                             return  Ok ( ColumnarValue :: Scalar ( ScalarValue :: Boolean ( 
391+                                 Some ( false ) , 
392+                             ) ) ) ; 
393+                         } 
394+ 
395+                         return  pre_selection_scatter ( selection,  Some ( boolean_array) ) ; 
396+                     } 
397+                     ColumnarValue :: Scalar ( scalar)  => { 
398+                         if  let  ScalarValue :: Boolean ( v)  = scalar { 
399+                             // When the scalar is true or false, skip the scatter process 
400+                             if  let  Some ( v)  = v { 
401+                                 if  * v { 
402+                                     return  Ok ( lhs) ; 
403+                                 }  else  { 
404+                                     return  Ok ( right_ret) ; 
405+                                 } 
406+                             }  else  { 
407+                                 return  pre_selection_scatter ( selection,  None ) ; 
408+                             } 
409+                         }  else  { 
410+                             return  internal_err ! ( 
411+                                 "Expected boolean scalar value, found: {right_ret:?}" 
412+                             ) ; 
413+                         } 
414+                     } 
415+                 } 
379416            } 
380417        } 
381418
@@ -974,13 +1011,8 @@ fn check_short_circuit<'a>(
9741011/// However, this is difficult to achieve under the immutable constraints of [`Arc`] and [`BooleanArray`]. 
9751012fn  pre_selection_scatter ( 
9761013    left_result :  & BooleanArray , 
977-     right_result :  ColumnarValue , 
1014+     right_result :  Option < & BooleanArray > , 
9781015)  -> Result < ColumnarValue >  { 
979-     let  right_boolean_array = match  & right_result { 
980-         ColumnarValue :: Array ( array)  => array. as_boolean ( ) , 
981-         ColumnarValue :: Scalar ( _)  => return  Ok ( right_result) , 
982-     } ; 
983- 
9841016    let  result_len = left_result. len ( ) ; 
9851017
9861018    let  mut  result_array_builder = BooleanArray :: builder ( result_len) ; 
@@ -990,22 +1022,39 @@ fn pre_selection_scatter(
9901022
9911023    // keep track of how much is filled 
9921024    let  mut  last_end = 0 ; 
993-     SlicesIterator :: new ( left_result) . for_each ( |( start,  end) | { 
994-         // the gap needs to be filled with false 
995-         if  start > last_end { 
996-             result_array_builder. append_n ( start - last_end,  false ) ; 
1025+     // reduce if condition in for_each 
1026+     match  right_result { 
1027+         Some ( right_result)  => { 
1028+             SlicesIterator :: new ( left_result) . for_each ( |( start,  end) | { 
1029+                 // the gap needs to be filled with false 
1030+                 if  start > last_end { 
1031+                     result_array_builder. append_n ( start - last_end,  false ) ; 
1032+                 } 
1033+ 
1034+                 // copy values from right array for this slice 
1035+                 let  len = end - start; 
1036+                 right_result
1037+                     . slice ( right_array_pos,  len) 
1038+                     . iter ( ) 
1039+                     . for_each ( |v| result_array_builder. append_option ( v) ) ; 
1040+ 
1041+                 right_array_pos += len; 
1042+                 last_end = end; 
1043+             } ) ; 
9971044        } 
1045+         None  => SlicesIterator :: new ( left_result) . for_each ( |( start,  end) | { 
1046+             // the gap needs to be filled with false 
1047+             if  start > last_end { 
1048+                 result_array_builder. append_n ( start - last_end,  false ) ; 
1049+             } 
9981050
999-         // copy values from right array for this slice 
1000-         let  len = end - start; 
1001-         right_boolean_array
1002-             . slice ( right_array_pos,  len) 
1003-             . iter ( ) 
1004-             . for_each ( |v| result_array_builder. append_option ( v) ) ; 
1051+             // append nulls for this slice derictly 
1052+             let  len = end - start; 
1053+             result_array_builder. append_nulls ( len) ; 
10051054
1006-         right_array_pos += len ; 
1007-         last_end = end ; 
1008-     } ) ; 
1055+             last_end = end ; 
1056+         } ) , 
1057+     } 
10091058
10101059    // Fill any remaining positions with false 
10111060    if  last_end < result_len { 
@@ -5211,7 +5260,6 @@ mod tests {
52115260/// 4. Test single true at first position 
52125261/// 5. Test single true at last position 
52135262/// 6. Test nulls in right array 
5214- /// 7. Test scalar right handling 
52155263#[ test]  
52165264    fn  test_pre_selection_scatter ( )  { 
52175265        fn  create_bool_array ( bools :  Vec < bool > )  -> BooleanArray  { 
@@ -5222,11 +5270,9 @@ mod tests {
52225270            // Left: [T, F, T, F, T] 
52235271            // Right: [F, T, F] (values for 3 true positions) 
52245272            let  left = create_bool_array ( vec ! [ true ,  false ,  true ,  false ,  true ] ) ; 
5225-             let  right = ColumnarValue :: Array ( Arc :: new ( create_bool_array ( vec ! [ 
5226-                 false ,  true ,  false , 
5227-             ] ) ) ) ; 
5273+             let  right = create_bool_array ( vec ! [ false ,  true ,  false ] ) ; 
52285274
5229-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5275+             let  result = pre_selection_scatter ( & left,  Some ( & right) ) . unwrap ( ) ; 
52305276            let  result_arr = result. into_array ( left. len ( ) ) . unwrap ( ) ; 
52315277
52325278            let  expected = create_bool_array ( vec ! [ false ,  false ,  true ,  false ,  false ] ) ; 
@@ -5238,11 +5284,9 @@ mod tests {
52385284            // Right: [T, F, F, T, F] 
52395285            let  left =
52405286                create_bool_array ( vec ! [ false ,  true ,  true ,  false ,  true ,  true ,  true ] ) ; 
5241-             let  right = ColumnarValue :: Array ( Arc :: new ( create_bool_array ( vec ! [ 
5242-                 true ,  false ,  false ,  true ,  false , 
5243-             ] ) ) ) ; 
5287+             let  right = create_bool_array ( vec ! [ true ,  false ,  false ,  true ,  false ] ) ; 
52445288
5245-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5289+             let  result = pre_selection_scatter ( & left,  Some ( & right) ) . unwrap ( ) ; 
52465290            let  result_arr = result. into_array ( left. len ( ) ) . unwrap ( ) ; 
52475291
52485292            let  expected =
@@ -5254,9 +5298,9 @@ mod tests {
52545298            // Left: [T, F, F] 
52555299            // Right: [F] 
52565300            let  left = create_bool_array ( vec ! [ true ,  false ,  false ] ) ; 
5257-             let  right = ColumnarValue :: Array ( Arc :: new ( create_bool_array ( vec ! [ false ] ) ) ) ; 
5301+             let  right = create_bool_array ( vec ! [ false ] ) ; 
52585302
5259-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5303+             let  result = pre_selection_scatter ( & left,  Some ( & right) ) . unwrap ( ) ; 
52605304            let  result_arr = result. into_array ( left. len ( ) ) . unwrap ( ) ; 
52615305
52625306            let  expected = create_bool_array ( vec ! [ false ,  false ,  false ] ) ; 
@@ -5267,9 +5311,9 @@ mod tests {
52675311            // Left: [F, F, T] 
52685312            // Right: [F] 
52695313            let  left = create_bool_array ( vec ! [ false ,  false ,  true ] ) ; 
5270-             let  right = ColumnarValue :: Array ( Arc :: new ( create_bool_array ( vec ! [ false ] ) ) ) ; 
5314+             let  right = create_bool_array ( vec ! [ false ] ) ; 
52715315
5272-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5316+             let  result = pre_selection_scatter ( & left,  Some ( & right) ) . unwrap ( ) ; 
52735317            let  result_arr = result. into_array ( left. len ( ) ) . unwrap ( ) ; 
52745318
52755319            let  expected = create_bool_array ( vec ! [ false ,  false ,  false ] ) ; 
@@ -5280,10 +5324,9 @@ mod tests {
52805324            // Left: [F, T, F, T] 
52815325            // Right: [None, Some(false)] (with null at first position) 
52825326            let  left = create_bool_array ( vec ! [ false ,  true ,  false ,  true ] ) ; 
5283-             let  right_arr = BooleanArray :: from ( vec ! [ None ,  Some ( false ) ] ) ; 
5284-             let  right = ColumnarValue :: Array ( Arc :: new ( right_arr) ) ; 
5327+             let  right = BooleanArray :: from ( vec ! [ None ,  Some ( false ) ] ) ; 
52855328
5286-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5329+             let  result = pre_selection_scatter ( & left,  Some ( & right) ) . unwrap ( ) ; 
52875330            let  result_arr = result. into_array ( left. len ( ) ) . unwrap ( ) ; 
52885331
52895332            let  expected = BooleanArray :: from ( vec ! [ 
@@ -5294,16 +5337,30 @@ mod tests {
52945337            ] ) ; 
52955338            assert_eq ! ( & expected,  result_arr. as_boolean( ) ) ; 
52965339        } 
5297-         // Test scalar right handling 
5298-         { 
5299-             // Left: [T, F, T] 
5300-             // Right: Scalar true 
5301-             let  left = create_bool_array ( vec ! [ true ,  false ,  true ] ) ; 
5302-             let  right = ColumnarValue :: Scalar ( ScalarValue :: Boolean ( Some ( true ) ) ) ; 
5340+     } 
53035341
5304-             let  result = pre_selection_scatter ( & left,  right) . unwrap ( ) ; 
5305-             assert ! ( matches!( result,  ColumnarValue :: Scalar ( _) ) ) ; 
5306-         } 
5342+     #[ test]  
5343+     fn  test_and_true_preselection_returns_lhs ( )  { 
5344+         let  schema =
5345+             Arc :: new ( Schema :: new ( vec ! [ Field :: new( "c" ,  DataType :: Boolean ,  false ) ] ) ) ; 
5346+         let  c_array = Arc :: new ( BooleanArray :: from ( vec ! [ false ,  true ,  false ,  false ,  false ] ) ) 
5347+             as  ArrayRef ; 
5348+         let  batch = RecordBatch :: try_new ( Arc :: clone ( & schema) ,  vec ! [ Arc :: clone( & c_array) ] ) 
5349+             . unwrap ( ) ; 
5350+ 
5351+         let  expr = logical2physical ( & logical_col ( "c" ) . and ( expr_lit ( true ) ) ,  & schema) ; 
5352+ 
5353+         let  result = expr. evaluate ( & batch) . unwrap ( ) ; 
5354+         let  ColumnarValue :: Array ( result_arr)  = result else  { 
5355+             panic ! ( "Expected ColumnarValue::Array" ) ; 
5356+         } ; 
5357+ 
5358+         let  expected:  Vec < _ >  = c_array. as_boolean ( ) . iter ( ) . collect ( ) ; 
5359+         let  actual:  Vec < _ >  = result_arr. as_boolean ( ) . iter ( ) . collect ( ) ; 
5360+         assert_eq ! ( 
5361+             expected,  actual, 
5362+             "AND with TRUE must equal LHS even with PreSelection" 
5363+         ) ; 
53075364    } 
53085365
53095366    #[ test]  
0 commit comments