@@ -1395,24 +1395,55 @@ fn fsl_values_row_number(list_size: i32, array_len: usize) -> Result<Int32Array>
13951395/// semantics, which treats `-0.0` and `+0.0` as distinct. SQL semantics
13961396/// (PostgreSQL / IEEE 754 equality) require them to compare equal, so
13971397/// callers normalize before invoking those kernels.
1398+ ///
1399+ /// The common case — no `-0.0` present — is allocation-free: a single
1400+ /// read-only scan of the underlying buffer (auto-vectorizable to an
1401+ /// OR-reduction) decides whether to fall through to the rewriting path.
1402+ /// Only arrays that actually contain `-0.0` pay for a new buffer.
13981403pub fn normalize_float_zero ( array : & ArrayRef ) -> ArrayRef {
13991404 use arrow:: array:: { Float16Array , Float32Array , Float64Array } ;
14001405 use arrow:: datatypes:: { Float16Type , Float32Type , Float64Type } ;
1406+ // -0.0 has only the sign bit set; no other finite or NaN value shares
1407+ // this bit pattern, so a strict-equality scan reliably gates the rewrite.
1408+ const NEG_ZERO_F16_BITS : u16 = half:: f16:: NEG_ZERO . to_bits ( ) ;
1409+ const NEG_ZERO_F32_BITS : u32 = ( -0.0_f32 ) . to_bits ( ) ;
1410+ const NEG_ZERO_F64_BITS : u64 = ( -0.0_f64 ) . to_bits ( ) ;
14011411 match array. data_type ( ) {
14021412 DataType :: Float32 => {
14031413 let arr: & Float32Array = array. as_primitive :: < Float32Type > ( ) ;
1414+ if !arr
1415+ . values ( )
1416+ . iter ( )
1417+ . any ( |v| v. to_bits ( ) == NEG_ZERO_F32_BITS )
1418+ {
1419+ return Arc :: clone ( array) ;
1420+ }
14041421 let normalized: Float32Array =
14051422 arr. unary ( |v| if v. to_bits ( ) << 1 == 0 { 0.0_f32 } else { v } ) ;
14061423 Arc :: new ( normalized)
14071424 }
14081425 DataType :: Float64 => {
14091426 let arr: & Float64Array = array. as_primitive :: < Float64Type > ( ) ;
1427+ if !arr
1428+ . values ( )
1429+ . iter ( )
1430+ . any ( |v| v. to_bits ( ) == NEG_ZERO_F64_BITS )
1431+ {
1432+ return Arc :: clone ( array) ;
1433+ }
14101434 let normalized: Float64Array =
14111435 arr. unary ( |v| if v. to_bits ( ) << 1 == 0 { 0.0_f64 } else { v } ) ;
14121436 Arc :: new ( normalized)
14131437 }
14141438 DataType :: Float16 => {
14151439 let arr: & Float16Array = array. as_primitive :: < Float16Type > ( ) ;
1440+ if !arr
1441+ . values ( )
1442+ . iter ( )
1443+ . any ( |v| v. to_bits ( ) == NEG_ZERO_F16_BITS )
1444+ {
1445+ return Arc :: clone ( array) ;
1446+ }
14161447 let normalized: Float16Array = arr. unary ( |v| {
14171448 if v. to_bits ( ) << 1 == 0 {
14181449 half:: f16:: from_bits ( 0 )
0 commit comments