Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Spark `xxhash64` hashes the raw bits of a NaN instead of the canonical NaN

Aperta Adatta ai principianti
#25,913 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@mrhard9090 ci sta già lavorando.

Dal 2/10/2026.

  • #25899 di @mrhard9090 — chiusa senza merge
  • #25971 di @mrhard9090 — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
84/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
rust, spark
Ambito
data

Direzione di ricerca

Inizia in datafusion/spark/src/function/hash/utils.rs, alla macro hash_array_primitive_float!, e confronta la gestione esistente di -0.0 con la riproduzione di NaN dell'issue. Aggiungi un caso di regressione usando NaNs con bit di segno e payload diversi; il lavoro è completato quando ogni NaN produce lo stesso hash del NaN canonico, mentre -0.0 mantiene il comportamento compatibile con Spark.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug
Describe the bug

datafusion-spark's xxhash64 hashes a Float32 or Float64 NaN by its raw bits. Spark hashes floats through Float.floatToIntBits and Double.doubleToLongBits, which return the canonical NaN (0x7fc00000, 0x7ff8000000000000) for every NaN, so in Spark all NaNs hash alike. A NaN with the sign bit set, or with another payload, therefore gets a different hash from datafusion-spark than from Spark.

Such NaNs are common: negating a NaN sets its sign bit, and on x86-64 every NaN that arithmetic produces at run time, such as 0.0 / 0.0, has the sign bit set.

The float path is hash_array_primitive_float! in datafusion/spark/src/function/hash/utils.rs. It hashes 0 for -0.0, as Spark does, and otherwise the bytes of the value as they are.

To Reproduce
let values: ArrayRef = Arc::new(Float64Array::from(vec![
    f64::NAN,                              // 0x7ff8000000000000, the canonical NaN
    f64::from_bits(0xfff8_0000_0000_0000), // the same with the sign bit set, which -f64::NAN gives
    f64::from_bits(0x7ff0_0000_0000_0001), // a NaN with another payload
]));
let args = ScalarFunctionArgs {
    args: vec![ColumnarValue::Array(Arc::clone(&values))],
    arg_fields: vec![Arc::new(Field::new("v", DataType::Float64, true))],
    number_rows: values.len(),
    return_field: Arc::new(Field::new("r", DataType::Int64, false)),
    config_options: Arc::new(ConfigOptions::default()),
};
let hashes = SparkXxhash64::new()
    .invoke_with_args(args)?
    .into_array(values.len())?;

hashes is [-3127944061524951246, 9200374361256412029, 5729085064965309005]. Float32 behaves the same way: f32::NAN hashes to 2692338816207849720 and the NaN with the sign bit set (0xffc00000) to 4760557555880201639.

Expected behavior

Every NaN hashes like the canonical NaN. In Spark, when d is NaN, xxhash64(d) and xxhash64(-d) both return -3127944061524951246.

Canonicalizing NaN next to the existing -0.0 check in hash_array_primitive_float! would match Spark.

Additional context

Comet found this while fixing the same gap in its own kernel (apache/datafusion-comet#6413), which keeps float arguments off SparkXxhash64 until it is fixed.

Lingua principale
Rust
Stelle
9.4k
Fork
2.5k
Merge medio
3g 18h
PR unite (30g)
381

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di apache/datafusion

Tutte le issue di apache/datafusion

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.