diff --git a/datafusion/proto/proto/datafusion.proto b/datafusion/proto/proto/datafusion.proto index baabc04cfff7..0e499ee48ffc 100644 --- a/datafusion/proto/proto/datafusion.proto +++ b/datafusion/proto/proto/datafusion.proto @@ -726,6 +726,12 @@ message ScalarTimestampValue { string timezone = 5; } +message ScalarDictionaryValue { + ArrowType index_type = 1; + ScalarValue value = 2; +} + + message ScalarValue{ oneof value { bool bool_value = 1; @@ -752,6 +758,7 @@ message ScalarValue{ int32 interval_yearmonth_value = 24; int64 interval_daytime_value = 25; ScalarTimestampValue timestamp_value = 26; + ScalarDictionaryValue dictionary_value = 27; } } diff --git a/datafusion/proto/src/from_proto.rs b/datafusion/proto/src/from_proto.rs index 8c0124b9906b..95bfeb819a0c 100644 --- a/datafusion/proto/src/from_proto.rs +++ b/datafusion/proto/src/from_proto.rs @@ -776,6 +776,22 @@ impl TryFrom<&protobuf::ScalarValue> for ScalarValue { } } } + Value::DictionaryValue(v) => { + let index_type: DataType = v + .index_type + .as_ref() + .ok_or_else(|| Error::required("index_type"))? + .try_into()?; + + let value: Self = v + .value + .as_ref() + .ok_or_else(|| Error::required("value"))? + .as_ref() + .try_into()?; + + Self::Dictionary(Box::new(index_type), Box::new(value)) + } }) } } diff --git a/datafusion/proto/src/lib.rs b/datafusion/proto/src/lib.rs index ce2678025a88..4a1e782f3be1 100644 --- a/datafusion/proto/src/lib.rs +++ b/datafusion/proto/src/lib.rs @@ -451,11 +451,22 @@ mod roundtrip_tests { true, )), ), + ScalarValue::Dictionary( + Box::new(DataType::Int32), + Box::new(ScalarValue::Utf8(Some("foo".into()))), + ), + ScalarValue::Dictionary( + Box::new(DataType::Int32), + Box::new(ScalarValue::Utf8(None)), + ), ]; for test_case in should_pass.into_iter() { - let proto: super::protobuf::ScalarValue = (&test_case).try_into().unwrap(); - let _roundtrip: ScalarValue = (&proto).try_into().unwrap(); + let proto: super::protobuf::ScalarValue = (&test_case) + .try_into() + .expect("failed conversion to protobuf"); + let _roundtrip: ScalarValue = + (&proto).try_into().expect("failed conversion to protobuf"); } } diff --git a/datafusion/proto/src/to_proto.rs b/datafusion/proto/src/to_proto.rs index 43d649029f8d..ed0b5ec0871c 100644 --- a/datafusion/proto/src/to_proto.rs +++ b/datafusion/proto/src/to_proto.rs @@ -1176,12 +1176,46 @@ impl TryFrom<&ScalarValue> for protobuf::ScalarValue { Value::IntervalDaytimeValue(*s) }) } - ScalarValue::Null => protobuf::ScalarValue { + datafusion::scalar::ScalarValue::Null => protobuf::ScalarValue { value: Some(Value::NullValue(PrimitiveScalarType::Null as i32)), }, - _ => { + + datafusion::scalar::ScalarValue::Binary(_) => { + // not yet implemented (TODO file ticket) + return Err(Error::invalid_scalar_value(val)); + } + + datafusion::scalar::ScalarValue::LargeBinary(_) => { + // not yet implemented (TODO file ticket) + return Err(Error::invalid_scalar_value(val)); + } + + datafusion::scalar::ScalarValue::Time64(_) => { + // not yet implemented (TODO file ticket) + return Err(Error::invalid_scalar_value(val)); + } + + datafusion::scalar::ScalarValue::IntervalMonthDayNano(_) => { + // not yet implemented (TODO file ticket) return Err(Error::invalid_scalar_value(val)); } + + datafusion::scalar::ScalarValue::Struct(_, _) => { + // not yet implemented (TODO file ticket) + return Err(Error::invalid_scalar_value(val)); + } + + datafusion::scalar::ScalarValue::Dictionary(index_type, val) => { + let value: protobuf::ScalarValue = val.as_ref().try_into()?; + protobuf::ScalarValue { + value: Some(Value::DictionaryValue(Box::new( + protobuf::ScalarDictionaryValue { + index_type: Some(index_type.as_ref().try_into()?), + value: Some(Box::new(value)), + }, + ))), + } + } }; Ok(scalar_val)