Skip to content

Commit 386b167

Browse files
committed
introduce from for struct
Signed-off-by: jayzhan211 <jayzhan211@gmail.com>
1 parent 1d78b68 commit 386b167

2 files changed

Lines changed: 44 additions & 17 deletions

File tree

datafusion/common/src/scalar.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use arrow::{
4848
};
4949
use arrow_array::types::ArrowTimestampType;
5050
use arrow_array::{ArrowNativeTypeOp, Scalar};
51-
use arrow_buffer::Buffer;
51+
use arrow_buffer::{Buffer, NullBuffer};
5252

5353
/// A dynamically typed, nullable single value, (the single-valued counter-part
5454
/// to arrow's [`Array`])
@@ -1793,11 +1793,6 @@ impl ScalarValue {
17931793
Arc::new(array_into_large_list_array(values))
17941794
}
17951795

1796-
pub fn new_struct(fields: Fields, arrays: Vec<ArrayRef>) -> Self {
1797-
// TODO: ensure single element per column
1798-
ScalarValue::Struct(Arc::new(StructArray::new(fields, arrays, None)))
1799-
}
1800-
18011796
/// Converts a scalar value into an array of `size` rows.
18021797
///
18031798
/// # Errors
@@ -2718,6 +2713,23 @@ impl From<String> for ScalarValue {
27182713
}
27192714
}
27202715

2716+
// Wrapper for ScalarValue::Struct that checks the length of the arrays, without nulls
2717+
impl From<(Fields, Vec<ArrayRef>)> for ScalarValue {
2718+
fn from((fields, arrays): (Fields, Vec<ArrayRef>)) -> Self {
2719+
Self::from((fields, arrays, None))
2720+
}
2721+
}
2722+
2723+
// Wrapper for ScalarValue::Struct that checks the length of the arrays
2724+
impl From<(Fields, Vec<ArrayRef>, Option<NullBuffer>)> for ScalarValue {
2725+
fn from((fields, arrays, nulls): (Fields, Vec<ArrayRef>, Option<NullBuffer>)) -> Self {
2726+
for arr in arrays.iter() {
2727+
assert_eq!(arr.len(), 1);
2728+
}
2729+
Self::Struct(Arc::new(StructArray::new(fields, arrays, nulls)))
2730+
}
2731+
}
2732+
27212733
macro_rules! impl_try_from {
27222734
($SCALAR:ident, $NATIVE:ident) => {
27232735
impl TryFrom<ScalarValue> for $NATIVE {
@@ -3204,9 +3216,9 @@ mod tests {
32043216
use crate::cast::{as_string_array, as_uint32_array, as_uint64_array};
32053217

32063218
#[test]
3207-
fn new_struct() {
3208-
let boolean = Arc::new(BooleanArray::from(vec![false, false, true, true]));
3209-
let int = Arc::new(Int32Array::from(vec![42, 28, 19, 31]));
3219+
fn test_scalar_value_from_for_struct() {
3220+
let boolean = Arc::new(BooleanArray::from(vec![false]));
3221+
let int = Arc::new(Int32Array::from(vec![42]));
32103222

32113223
let expected = StructArray::from(vec![
32123224
(
@@ -3224,12 +3236,27 @@ mod tests {
32243236
Field::new("b", DataType::Boolean, false),
32253237
Field::new("c", DataType::Int32, false),
32263238
]);
3227-
let sv = ScalarValue::new_struct(fields, arrays);
3239+
let sv = ScalarValue::from((fields, arrays));
32283240
let struct_arr = sv.to_array().unwrap();
32293241
let actual = as_struct_array(&struct_arr).unwrap();
32303242
assert_eq!(actual, &expected);
32313243
}
32323244

3245+
#[test]
3246+
#[should_panic(expected = "assertion `left == right` failed")]
3247+
fn test_scalar_value_from_for_struct_should_panic() {
3248+
let fields = Fields::from(vec![
3249+
Field::new("bool", DataType::Boolean, false),
3250+
Field::new("i32", DataType::Int32, false),
3251+
]);
3252+
3253+
let arrays = vec![
3254+
Arc::new(BooleanArray::from(vec![false, true, false, false])) as ArrayRef,
3255+
Arc::new(Int32Array::from(vec![42, 28, 19, 31]))];
3256+
3257+
let _ = ScalarValue::from((fields, arrays));
3258+
}
3259+
32333260
#[test]
32343261
fn test_to_array_of_size_for_nested() {
32353262
// Struct

datafusion/proto/tests/cases/roundtrip_logical_plan.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ use datafusion_proto::bytes::{
6262
logical_plan_from_bytes, logical_plan_from_bytes_with_extension_codec,
6363
logical_plan_to_bytes, logical_plan_to_bytes_with_extension_codec,
6464
};
65+
use datafusion_proto::logical_plan::from_proto;
6566
use datafusion_proto::logical_plan::LogicalExtensionCodec;
66-
use datafusion_proto::logical_plan::{from_proto, to_proto};
6767
use datafusion_proto::protobuf;
6868

6969
#[cfg(feature = "json")]
@@ -877,19 +877,19 @@ fn round_trip_scalar_values() {
877877
ScalarValue::Binary(None),
878878
ScalarValue::LargeBinary(Some(b"bar".to_vec())),
879879
ScalarValue::LargeBinary(None),
880-
ScalarValue::new_struct(
881-
Fields::from(vec![
880+
ScalarValue::from((
881+
vec![
882882
Field::new("a", DataType::Int32, true),
883883
Field::new("b", DataType::Boolean, false),
884-
]),
884+
].into(),
885885
vec![
886886
Arc::new(Int32Array::from(vec![Some(23)])) as ArrayRef,
887887
Arc::new(BooleanArray::from(vec![Some(false)])) as ArrayRef,
888888
],
889-
),
889+
)),
890890
ScalarValue::try_from(&DataType::Struct(Fields::from(vec![
891891
Field::new("a", DataType::Int32, true),
892-
Field::new("a", DataType::Boolean, false),
892+
Field::new("b", DataType::Boolean, false),
893893
])))
894894
.unwrap(),
895895
ScalarValue::FixedSizeBinary(b"bar".to_vec().len() as i32, Some(b"bar".to_vec())),
@@ -1824,4 +1824,4 @@ fn roundtrip_window() {
18241824
roundtrip_expr_test(test_expr4, ctx.clone());
18251825
roundtrip_expr_test(test_expr5, ctx.clone());
18261826
roundtrip_expr_test(test_expr6, ctx);
1827-
}
1827+
}

0 commit comments

Comments
 (0)