diff --git a/datafusion/common/src/scalar/mod.rs b/datafusion/common/src/scalar/mod.rs index dfba88556f18..f020e0407332 100644 --- a/datafusion/common/src/scalar/mod.rs +++ b/datafusion/common/src/scalar/mod.rs @@ -3264,9 +3264,8 @@ impl fmt::Display for ScalarValue { columns .iter() .zip(fields.iter()) - .enumerate() - .map(|(index, (column, field))| { - if nulls.is_some_and(|b| b.is_null(index)) { + .map(|(column, field)| { + if nulls.is_some_and(|b| b.is_null(0)) { format!("{}:NULL", field.name()) } else if let DataType::Struct(_) = field.data_type() { let sv = ScalarValue::Struct(Arc::new( @@ -3466,7 +3465,7 @@ mod tests { use arrow::buffer::OffsetBuffer; use arrow::compute::{is_null, kernels}; use arrow::util::pretty::pretty_format_columns; - use arrow_buffer::Buffer; + use arrow_buffer::{Buffer, NullBuffer}; use arrow_schema::Fields; use chrono::NaiveDate; use rand::Rng; @@ -6040,6 +6039,43 @@ mod tests { assert_batches_eq!(&expected, &[batch]); } + #[test] + fn test_null_bug() { + let field_a = Field::new("a", DataType::Int32, true); + let field_b = Field::new("b", DataType::Int32, true); + let fields = Fields::from(vec![field_a, field_b]); + + let array_a = Arc::new(Int32Array::from_iter_values([1])); + let array_b = Arc::new(Int32Array::from_iter_values([2])); + let arrays: Vec = vec![array_a, array_b]; + + let mut not_nulls = BooleanBufferBuilder::new(1); + not_nulls.append(true); + let not_nulls = not_nulls.finish(); + let not_nulls = Some(NullBuffer::new(not_nulls)); + + let ar = unsafe { StructArray::new_unchecked(fields, arrays, not_nulls) }; + let s = ScalarValue::Struct(Arc::new(ar)); + + assert_eq!(s.to_string(), "{a:1,b:2}"); + assert_eq!(format!("{s:?}"), r#"Struct({a:1,b:2})"#); + + let ScalarValue::Struct(arr) = s else { + panic!("Expected struct"); + }; + + //verify compared to arrow display + let batch = RecordBatch::try_from_iter(vec![("s", arr as _)]).unwrap(); + let expected = [ + "+--------------+", + "| s |", + "+--------------+", + "| {a: 1, b: 2} |", + "+--------------+", + ]; + assert_batches_eq!(&expected, &[batch]); + } + #[test] fn test_struct_display_null() { let fields = vec![Field::new("a", DataType::Int32, false)]; diff --git a/datafusion/wasmtest/src/lib.rs b/datafusion/wasmtest/src/lib.rs index a74cce72ac64..a4a803b6545f 100644 --- a/datafusion/wasmtest/src/lib.rs +++ b/datafusion/wasmtest/src/lib.rs @@ -88,12 +88,14 @@ mod test { wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + #[allow(dead_code)] #[wasm_bindgen_test] fn datafusion_test() { basic_exprs(); basic_parse(); } + #[allow(dead_code)] #[wasm_bindgen_test] async fn basic_execute() { let sql = "SELECT 2 + 2;";