@@ -54,7 +54,7 @@ use arrow::array::{
5454} ;
5555use arrow:: buffer:: { BooleanBuffer , NullBuffer } ;
5656use arrow:: compute:: kernels:: cmp:: eq;
57- use arrow:: compute:: { self , FilterBuilder , and , take} ;
57+ use arrow:: compute:: { self , FilterBuilder , take} ;
5858use arrow:: datatypes:: {
5959 ArrowNativeType , Field , Schema , SchemaBuilder , UInt32Type , UInt64Type ,
6060} ;
@@ -1788,19 +1788,26 @@ pub(super) fn equal_rows_arr(
17881788 let arr_left = take ( first_left. as_ref ( ) , indices_left, None ) ?;
17891789 let arr_right = take ( first_right. as_ref ( ) , indices_right, None ) ?;
17901790
1791- let mut equal : BooleanArray = eq_dyn_null ( & arr_left, & arr_right, null_equality) ?;
1791+ let first_eq = eq_dyn_null ( & arr_left, & arr_right, null_equality) ?;
17921792
1793- // Use map and try_fold to iterate over the remaining pairs of arrays.
1794- // In each iteration, take is used on the pair of arrays and their equality is determined.
1795- // The results are then folded (combined) using the and function to get a final equality result.
1796- equal = iter
1797- . map ( |( left, right) | {
1798- let arr_left = take ( left. as_ref ( ) , indices_left, None ) ?;
1799- let arr_right = take ( right. as_ref ( ) , indices_right, None ) ?;
1800- eq_dyn_null ( arr_left. as_ref ( ) , arr_right. as_ref ( ) , null_equality)
1801- } )
1802- . try_fold ( equal, |acc, equal2| and ( & acc, & equal2?) ) ?;
1793+ // Accumulate equality results using BooleanBuffer bitwise AND, treating null as false.
1794+ // This avoids allocating intermediate BooleanArrays with null handling.
1795+ let to_filter_buf = |arr : & BooleanArray | -> BooleanBuffer {
1796+ match arr. nulls ( ) {
1797+ Some ( nulls) => arr. values ( ) & nulls. inner ( ) ,
1798+ None => arr. values ( ) . clone ( ) ,
1799+ }
1800+ } ;
1801+
1802+ let mut equal_buf = to_filter_buf ( & first_eq) ;
1803+ for ( left, right) in iter {
1804+ let arr_left = take ( left. as_ref ( ) , indices_left, None ) ?;
1805+ let arr_right = take ( right. as_ref ( ) , indices_right, None ) ?;
1806+ let eq_result = eq_dyn_null ( & arr_left, & arr_right, null_equality) ?;
1807+ equal_buf &= & to_filter_buf ( & eq_result) ;
1808+ }
18031809
1810+ let equal = BooleanArray :: new ( equal_buf, None ) ;
18041811 let filter_builder = FilterBuilder :: new ( & equal) . optimize ( ) . build ( ) ;
18051812
18061813 let left_filtered = filter_builder. filter ( indices_left) ?;
0 commit comments