diff --git a/src/datatypes2/src/data_type.rs b/src/datatypes2/src/data_type.rs index 723cf3d5d0e5..456312a1d76c 100644 --- a/src/datatypes2/src/data_type.rs +++ b/src/datatypes2/src/data_type.rs @@ -21,8 +21,8 @@ use serde::{Deserialize, Serialize}; use crate::error::{self, Error, Result}; use crate::type_id::LogicalTypeId; use crate::types::{ - BinaryType, BooleanType, Float32Type, Float64Type, Int16Type, Int32Type, Int64Type, Int8Type, - UInt16Type, UInt32Type, UInt64Type, UInt8Type, + BinaryType, BooleanType, DateType, Float32Type, Float64Type, Int16Type, Int32Type, Int64Type, + Int8Type, UInt16Type, UInt32Type, UInt64Type, UInt8Type, }; use crate::value::Value; use crate::vectors::MutableVector; @@ -45,17 +45,19 @@ pub enum ConcreteDataType { Float32(Float32Type), Float64(Float64Type), - // String types + // String types: Binary(BinaryType), // String(StringType), - // Date(DateType), + // Date types: + Date(DateType), // DateTime(DateTimeType), // Timestamp(TimestampType), // List(ListType), } +// TODO(yingwen): Consider moving these methods to the DataType trait. impl ConcreteDataType { // pub fn is_float(&self) -> bool { // matches!( @@ -143,17 +145,17 @@ impl TryFrom<&ArrowDataType> for ConcreteDataType { let concrete_type = match dt { // ArrowDataType::Null => Self::null_datatype(), ArrowDataType::Boolean => Self::boolean_datatype(), - // ArrowDataType::UInt8 => Self::uint8_datatype(), - // ArrowDataType::UInt16 => Self::uint16_datatype(), - // ArrowDataType::UInt32 => Self::uint32_datatype(), - // ArrowDataType::UInt64 => Self::uint64_datatype(), - // ArrowDataType::Int8 => Self::int8_datatype(), - // ArrowDataType::Int16 => Self::int16_datatype(), - // ArrowDataType::Int32 => Self::int32_datatype(), - // ArrowDataType::Int64 => Self::int64_datatype(), - // ArrowDataType::Float32 => Self::float32_datatype(), - // ArrowDataType::Float64 => Self::float64_datatype(), - // ArrowDataType::Date32 => Self::date_datatype(), + ArrowDataType::UInt8 => Self::uint8_datatype(), + ArrowDataType::UInt16 => Self::uint16_datatype(), + ArrowDataType::UInt32 => Self::uint32_datatype(), + ArrowDataType::UInt64 => Self::uint64_datatype(), + ArrowDataType::Int8 => Self::int8_datatype(), + ArrowDataType::Int16 => Self::int16_datatype(), + ArrowDataType::Int32 => Self::int32_datatype(), + ArrowDataType::Int64 => Self::int64_datatype(), + ArrowDataType::Float32 => Self::float32_datatype(), + ArrowDataType::Float64 => Self::float64_datatype(), + ArrowDataType::Date32 => Self::date_datatype(), // ArrowDataType::Date64 => Self::datetime_datatype(), // ArrowDataType::Timestamp(u, _) => ConcreteDataType::from_arrow_time_unit(u), ArrowDataType::Binary | ArrowDataType::LargeBinary => Self::binary_datatype(), @@ -187,12 +189,10 @@ macro_rules! impl_new_concrete_type_functions { } } -// impl_new_concrete_type_functions!( -// Null, Boolean, UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64, -// Binary, String, Date, DateTime -// ); - -impl_new_concrete_type_functions!(Boolean, Binary); +impl_new_concrete_type_functions!( + Boolean, UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64, Binary, + Date +); // impl ConcreteDataType { // pub fn list_datatype(inner_type: ConcreteDataType) -> ConcreteDataType { @@ -246,135 +246,134 @@ pub trait DataType: std::fmt::Debug + Send + Sync { pub type DataTypeRef = Arc; -// #[cfg(test)] -// mod tests { -// use arrow::datatypes::Field; - -// use super::*; +// TODO(yingwen): Pass all tests. +#[cfg(test)] +mod tests { + use super::*; -// #[test] -// fn test_concrete_type_as_datatype_trait() { -// let concrete_type = ConcreteDataType::boolean_datatype(); + #[test] + fn test_concrete_type_as_datatype_trait() { + let concrete_type = ConcreteDataType::boolean_datatype(); -// assert_eq!("Boolean", concrete_type.name()); -// assert_eq!(Value::Boolean(false), concrete_type.default_value()); -// assert_eq!(LogicalTypeId::Boolean, concrete_type.logical_type_id()); -// assert_eq!(ArrowDataType::Boolean, concrete_type.as_arrow_type()); -// } + assert_eq!("Boolean", concrete_type.name()); + assert_eq!(Value::Boolean(false), concrete_type.default_value()); + assert_eq!(LogicalTypeId::Boolean, concrete_type.logical_type_id()); + assert_eq!(ArrowDataType::Boolean, concrete_type.as_arrow_type()); + } -// #[test] -// fn test_from_arrow_type() { -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Null), -// ConcreteDataType::Null(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Boolean), -// ConcreteDataType::Boolean(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Binary), -// ConcreteDataType::Binary(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::LargeBinary), -// ConcreteDataType::Binary(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Int8), -// ConcreteDataType::Int8(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Int16), -// ConcreteDataType::Int16(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Int32), -// ConcreteDataType::Int32(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Int64), -// ConcreteDataType::Int64(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::UInt8), -// ConcreteDataType::UInt8(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::UInt16), -// ConcreteDataType::UInt16(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::UInt32), -// ConcreteDataType::UInt32(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::UInt64), -// ConcreteDataType::UInt64(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Float32), -// ConcreteDataType::Float32(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Float64), -// ConcreteDataType::Float64(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8), -// ConcreteDataType::String(_) -// )); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8), -// ConcreteDataType::String(_) -// )); -// assert_eq!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::List(Box::new(Field::new( -// "item", -// ArrowDataType::Int32, -// true, -// )))), -// ConcreteDataType::List(ListType::new(ConcreteDataType::int32_datatype())) -// ); -// assert!(matches!( -// ConcreteDataType::from_arrow_type(&ArrowDataType::Date32), -// ConcreteDataType::Date(_) -// )); -// } + #[test] + fn test_from_arrow_type() { + // assert!(matches!( + // ConcreteDataType::from_arrow_type(&ArrowDataType::Null), + // ConcreteDataType::Null(_) + // )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Boolean), + ConcreteDataType::Boolean(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Binary), + ConcreteDataType::Binary(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::LargeBinary), + ConcreteDataType::Binary(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Int8), + ConcreteDataType::Int8(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Int16), + ConcreteDataType::Int16(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Int32), + ConcreteDataType::Int32(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Int64), + ConcreteDataType::Int64(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::UInt8), + ConcreteDataType::UInt8(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::UInt16), + ConcreteDataType::UInt16(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::UInt32), + ConcreteDataType::UInt32(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::UInt64), + ConcreteDataType::UInt64(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Float32), + ConcreteDataType::Float32(_) + )); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Float64), + ConcreteDataType::Float64(_) + )); + // assert!(matches!( + // ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8), + // ConcreteDataType::String(_) + // )); + // assert!(matches!( + // ConcreteDataType::from_arrow_type(&ArrowDataType::Utf8), + // ConcreteDataType::String(_) + // )); + // assert_eq!( + // ConcreteDataType::from_arrow_type(&ArrowDataType::List(Box::new(Field::new( + // "item", + // ArrowDataType::Int32, + // true, + // )))), + // ConcreteDataType::List(ListType::new(ConcreteDataType::int32_datatype())) + // ); + assert!(matches!( + ConcreteDataType::from_arrow_type(&ArrowDataType::Date32), + ConcreteDataType::Date(_) + )); + } -// #[test] -// fn test_from_arrow_timestamp() { -// assert_eq!( -// ConcreteDataType::timestamp_millis_datatype(), -// ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Millisecond) -// ); -// assert_eq!( -// ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond), -// ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Microsecond) -// ); -// assert_eq!( -// ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond), -// ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Nanosecond) -// ); -// assert_eq!( -// ConcreteDataType::timestamp_datatype(TimeUnit::Second), -// ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Second) -// ); -// } + // #[test] + // fn test_from_arrow_timestamp() { + // assert_eq!( + // ConcreteDataType::timestamp_millis_datatype(), + // ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Millisecond) + // ); + // assert_eq!( + // ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond), + // ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Microsecond) + // ); + // assert_eq!( + // ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond), + // ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Nanosecond) + // ); + // assert_eq!( + // ConcreteDataType::timestamp_datatype(TimeUnit::Second), + // ConcreteDataType::from_arrow_time_unit(&arrow::datatypes::TimeUnit::Second) + // ); + // } -// #[test] -// fn test_is_timestamp() { -// assert!(ConcreteDataType::timestamp_millis_datatype().is_timestamp()); -// assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Second).is_timestamp()); -// assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond).is_timestamp()); -// assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond).is_timestamp()); -// assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond).is_timestamp()); -// assert!(ConcreteDataType::int64_datatype().is_timestamp()); -// } + // #[test] + // fn test_is_timestamp() { + // assert!(ConcreteDataType::timestamp_millis_datatype().is_timestamp()); + // assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Second).is_timestamp()); + // assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond).is_timestamp()); + // assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond).is_timestamp()); + // assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond).is_timestamp()); + // assert!(ConcreteDataType::int64_datatype().is_timestamp()); + // } -// #[test] -// fn test_is_null() { -// assert!(ConcreteDataType::null_datatype().is_null()); -// assert!(!ConcreteDataType::int32_datatype().is_null()); -// } -// } + // #[test] + // fn test_is_null() { + // assert!(ConcreteDataType::null_datatype().is_null()); + // assert!(!ConcreteDataType::int32_datatype().is_null()); + // } +} diff --git a/src/datatypes2/src/scalars.rs b/src/datatypes2/src/scalars.rs index 59ddb8b1cf6f..37e70671d7bc 100644 --- a/src/datatypes2/src/scalars.rs +++ b/src/datatypes2/src/scalars.rs @@ -14,11 +14,15 @@ use std::any::Any; +use common_time::Date; + use crate::types::{ Float32Type, Float64Type, Int16Type, Int32Type, Int64Type, Int8Type, UInt16Type, UInt32Type, UInt64Type, UInt8Type, }; -use crate::vectors::{BinaryVector, BooleanVector, MutableVector, PrimitiveVector, Vector}; +use crate::vectors::{ + BinaryVector, BooleanVector, DateVector, MutableVector, PrimitiveVector, Vector, +}; fn get_iter_capacity>(iter: &I) -> usize { match iter.size_hint() { @@ -251,27 +255,26 @@ impl<'a> ScalarRef<'a> for &'a [u8] { } } -// impl Scalar for Date { -// type VectorType = DateVector; -// type RefType<'a> = Date; +impl Scalar for Date { + type VectorType = DateVector; + type RefType<'a> = Date; -// fn as_scalar_ref(&self) -> Self::RefType<'_> { -// *self -// } + fn as_scalar_ref(&self) -> Self::RefType<'_> { + *self + } -// fn upcast_gat<'short, 'long: 'short>(long: Self::RefType<'long>) -> Self::RefType<'short> { -// long -// } -// } + fn upcast_gat<'short, 'long: 'short>(long: Self::RefType<'long>) -> Self::RefType<'short> { + long + } +} -// impl<'a> ScalarRef<'a> for Date { -// type VectorType = DateVector; -// type ScalarType = Date; +impl<'a> ScalarRef<'a> for Date { + type ScalarType = Date; -// fn to_owned_scalar(&self) -> Self::ScalarType { -// *self -// } -// } + fn to_owned_scalar(&self) -> Self::ScalarType { + *self + } +} // impl Scalar for DateTime { // type VectorType = DateTimeVector; @@ -287,7 +290,6 @@ impl<'a> ScalarRef<'a> for &'a [u8] { // } // impl<'a> ScalarRef<'a> for DateTime { -// type VectorType = DateTimeVector; // type ScalarType = DateTime; // fn to_owned_scalar(&self) -> Self::ScalarType { @@ -309,7 +311,6 @@ impl<'a> ScalarRef<'a> for &'a [u8] { // } // impl<'a> ScalarRef<'a> for Timestamp { -// type VectorType = TimestampVector; // type ScalarType = Timestamp; // fn to_owned_scalar(&self) -> Self::ScalarType { @@ -331,7 +332,6 @@ impl<'a> ScalarRef<'a> for &'a [u8] { // } // impl<'a> ScalarRef<'a> for ListValueRef<'a> { -// type VectorType = ListVector; // type ScalarType = ListValue; // fn to_owned_scalar(&self) -> Self::ScalarType { @@ -393,24 +393,24 @@ mod tests { assert_vector_eq(&expect, &vector); } - // #[test] - // fn test_build_date_vector() { - // let expect: Vec> = vec![ - // Some(Date::new(0)), - // Some(Date::new(-1)), - // None, - // Some(Date::new(1)), - // ]; - // let vector: DateVector = build_vector_from_slice(&expect); - // assert_vector_eq(&expect, &vector); - // } + #[test] + fn test_build_date_vector() { + let expect: Vec> = vec![ + Some(Date::new(0)), + Some(Date::new(-1)), + None, + Some(Date::new(1)), + ]; + let vector: DateVector = build_vector_from_slice(&expect); + assert_vector_eq(&expect, &vector); + } - // #[test] - // fn test_date_scalar() { - // let date = Date::new(1); - // assert_eq!(date, date.as_scalar_ref()); - // assert_eq!(date, date.to_owned_scalar()); - // } + #[test] + fn test_date_scalar() { + let date = Date::new(1); + assert_eq!(date, date.as_scalar_ref()); + assert_eq!(date, date.to_owned_scalar()); + } // #[test] // fn test_datetime_scalar() { diff --git a/src/datatypes2/src/types.rs b/src/datatypes2/src/types.rs index 99598016d87a..656870753d52 100644 --- a/src/datatypes2/src/types.rs +++ b/src/datatypes2/src/types.rs @@ -14,10 +14,12 @@ mod binary_type; mod boolean_type; +mod date_type; mod primitive_type; pub use binary_type::BinaryType; pub use boolean_type::BooleanType; +pub use date_type::DateType; pub use primitive_type::{ Float32Type, Float64Type, Int16Type, Int32Type, Int64Type, Int8Type, LogicalPrimitiveType, NativeType, UInt16Type, UInt32Type, UInt64Type, UInt8Type, WrapperType, diff --git a/src/datatypes2/src/types/date_type.rs b/src/datatypes2/src/types/date_type.rs new file mode 100644 index 000000000000..f147d955f0af --- /dev/null +++ b/src/datatypes2/src/types/date_type.rs @@ -0,0 +1,86 @@ +// Copyright 2022 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use arrow::datatypes::{DataType as ArrowDataType, Date32Type}; +use common_time::Date; +use serde::{Deserialize, Serialize}; +use snafu::OptionExt; + +use crate::data_type::{ConcreteDataType, DataType}; +use crate::error::{self, Result}; +use crate::scalars::ScalarVectorBuilder; +use crate::type_id::LogicalTypeId; +use crate::types::LogicalPrimitiveType; +use crate::value::{Value, ValueRef}; +use crate::vectors::{DateVector, DateVectorBuilder, MutableVector, Vector}; + +/// Data type for Date (YYYY-MM-DD). +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct DateType; + +impl DataType for DateType { + fn name(&self) -> &str { + "Date" + } + + fn logical_type_id(&self) -> LogicalTypeId { + LogicalTypeId::Date + } + + fn default_value(&self) -> Value { + Value::Date(Default::default()) + } + + fn as_arrow_type(&self) -> ArrowDataType { + ArrowDataType::Date32 + } + + fn create_mutable_vector(&self, capacity: usize) -> Box { + Box::new(DateVectorBuilder::with_capacity(capacity)) + } +} + +impl LogicalPrimitiveType for DateType { + type ArrowPrimitive = Date32Type; + type Native = i32; + type Wrapper = Date; + + fn build_data_type() -> ConcreteDataType { + ConcreteDataType::date_datatype() + } + + fn type_name() -> &'static str { + "Date" + } + + fn cast_vector(vector: &dyn Vector) -> Result<&DateVector> { + vector + .as_any() + .downcast_ref::() + .with_context(|| error::CastTypeSnafu { + msg: format!("Failed to cast {} to DateVector", vector.vector_type_name(),), + }) + } + + fn cast_value_ref(value: ValueRef) -> Result> { + match value { + ValueRef::Null => Ok(None), + ValueRef::Date(v) => Ok(Some(v)), + other => error::CastTypeSnafu { + msg: format!("Failed to cast value {:?} to Date", other,), + } + .fail(), + } + } +} diff --git a/src/datatypes2/src/types/primitive_type.rs b/src/datatypes2/src/types/primitive_type.rs index 579434d76dde..6f98de14ca4a 100644 --- a/src/datatypes2/src/types/primitive_type.rs +++ b/src/datatypes2/src/types/primitive_type.rs @@ -15,6 +15,7 @@ use std::cmp::Ordering; use arrow::datatypes::{ArrowNativeType, ArrowPrimitiveType, DataType as ArrowDataType}; +use common_time::Date; use num::NumCast; use serde::{Deserialize, Serialize}; use snafu::OptionExt; @@ -23,6 +24,7 @@ use crate::data_type::{ConcreteDataType, DataType}; use crate::error::{self, Result}; use crate::scalars::{Scalar, ScalarRef, ScalarVectorBuilder}; use crate::type_id::LogicalTypeId; +use crate::types::DateType; use crate::value::{Value, ValueRef}; use crate::vectors::{MutableVector, PrimitiveVector, PrimitiveVectorBuilder, Vector}; @@ -69,6 +71,62 @@ pub trait WrapperType: fn into_native(self) -> Self::Native; } +/// Trait bridging the logical primitive type with [ArrowPrimitiveType]. +pub trait LogicalPrimitiveType: 'static + Sized { + /// Arrow primitive type of this logical type. + type ArrowPrimitive: ArrowPrimitiveType; + /// Native (physical) type of this logical type. + type Native: NativeType; + /// Wrapper type that the vector returns. + type Wrapper: WrapperType + + for<'a> Scalar, RefType<'a> = Self::Wrapper> + + for<'a> ScalarRef<'a, ScalarType = Self::Wrapper>; + + /// Construct the data type struct. + fn build_data_type() -> ConcreteDataType; + + /// Return the name of the type. + fn type_name() -> &'static str; + + /// Dynamic cast the vector to the concrete vector type. + fn cast_vector(vector: &dyn Vector) -> Result<&PrimitiveVector>; + + /// Cast value ref to the primitive type. + fn cast_value_ref(value: ValueRef) -> Result>; +} + +/// A new type for [WrapperType], complement the `Ord` feature for it. Wrapping non ordered +/// primitive types like `f32` and `f64` in `OrdPrimitive` can make them be used in places that +/// require `Ord`. For example, in `Median` or `Percentile` UDAFs. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct OrdPrimitive(pub T); + +impl OrdPrimitive { + pub fn as_primitive(&self) -> T { + self.0 + } +} + +impl Eq for OrdPrimitive {} + +impl PartialOrd for OrdPrimitive { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for OrdPrimitive { + fn cmp(&self, other: &Self) -> Ordering { + Into::::into(self.0).cmp(&Into::::into(other.0)) + } +} + +impl From> for Value { + fn from(p: OrdPrimitive) -> Self { + p.0.into() + } +} + macro_rules! impl_wrapper { ($Type: ident, $LogicalType: ident) => { impl WrapperType for $Type { @@ -97,34 +155,23 @@ impl_wrapper!(i64, Int64Type); impl_wrapper!(f32, Float32Type); impl_wrapper!(f64, Float64Type); -/// Trait bridging the logical primitive type with [ArrowPrimitiveType]. -pub trait LogicalPrimitiveType: 'static + Sized { - /// Arrow primitive type of this logical type. - type ArrowPrimitive: ArrowPrimitiveType; - /// Native (physical) type of this logical type. - type Native: NativeType; - /// Wrapper type that the vector returns. - type Wrapper: WrapperType - + for<'a> Scalar, RefType<'a> = Self::Wrapper> - + for<'a> ScalarRef<'a, ScalarType = Self::Wrapper>; - - /// Construct the data type struct. - fn build_data_type() -> ConcreteDataType; - - /// Return the name of the type. - fn type_name() -> &'static str; +impl WrapperType for Date { + type LogicalType = DateType; + type Native = i32; - /// Dynamic cast the vector to the concrete vector type. - fn cast_vector(vector: &dyn Vector) -> Result<&PrimitiveVector>; + fn from_native(value: i32) -> Self { + Date::new(value) + } - /// Cast value ref to the primitive type. - fn cast_value_ref(value: ValueRef) -> Result>; + fn into_native(self) -> i32 { + self.val() + } } macro_rules! define_logical_primitive_type { ($Native: ident, $TypeId: ident, $DataType: ident) => { #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] - pub struct $DataType {} + pub struct $DataType; impl LogicalPrimitiveType for $DataType { type ArrowPrimitive = arrow::datatypes::$DataType; @@ -203,38 +250,6 @@ define_logical_primitive_type!(i64, Int64, Int64Type); define_logical_primitive_type!(f32, Float32, Float32Type); define_logical_primitive_type!(f64, Float64, Float64Type); -/// A new type for [WrapperType], complement the `Ord` feature for it. Wrapping non ordered -/// primitive types like `f32` and `f64` in `OrdPrimitive` can make them be used in places that -/// require `Ord`. For example, in `Median` or `Percentile` UDAFs. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct OrdPrimitive(pub T); - -impl OrdPrimitive { - pub fn as_primitive(&self) -> T { - self.0 - } -} - -impl Eq for OrdPrimitive {} - -impl PartialOrd for OrdPrimitive { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for OrdPrimitive { - fn cmp(&self, other: &Self) -> Ordering { - Into::::into(self.0).cmp(&Into::::into(other.0)) - } -} - -impl From> for Value { - fn from(p: OrdPrimitive) -> Self { - p.0.into() - } -} - #[cfg(test)] mod tests { use std::collections::BinaryHeap; diff --git a/src/datatypes2/src/value.rs b/src/datatypes2/src/value.rs index 6e2d9b325aa2..7b27921b99a5 100644 --- a/src/datatypes2/src/value.rs +++ b/src/datatypes2/src/value.rs @@ -110,32 +110,28 @@ impl Value { /// # Panics /// Panics if the data type is not supported. pub fn data_type(&self) -> ConcreteDataType { + // TODO(yingwen): Implement this once all data types are implemented. match self { + // Value::Null => ConcreteDataType::null_datatype(), Value::Boolean(_) => ConcreteDataType::boolean_datatype(), + Value::UInt8(_) => ConcreteDataType::uint8_datatype(), + Value::UInt16(_) => ConcreteDataType::uint16_datatype(), + Value::UInt32(_) => ConcreteDataType::uint32_datatype(), + Value::UInt64(_) => ConcreteDataType::uint64_datatype(), + Value::Int8(_) => ConcreteDataType::int8_datatype(), + Value::Int16(_) => ConcreteDataType::int16_datatype(), + Value::Int32(_) => ConcreteDataType::int32_datatype(), + Value::Int64(_) => ConcreteDataType::int64_datatype(), + Value::Float32(_) => ConcreteDataType::float32_datatype(), + Value::Float64(_) => ConcreteDataType::float64_datatype(), + // Value::String(_) => ConcreteDataType::string_datatype(), Value::Binary(_) => ConcreteDataType::binary_datatype(), - _ => unimplemented!(), + // Value::List(list) => ConcreteDataType::list_datatype(list.datatype().clone()), + Value::Date(_) => ConcreteDataType::date_datatype(), + // Value::DateTime(_) => ConcreteDataType::datetime_datatype(), + // Value::Timestamp(v) => ConcreteDataType::timestamp_datatype(v.unit()), + _ => todo!(), } - - // match self { - // Value::Null => ConcreteDataType::null_datatype(), - // Value::Boolean(_) => ConcreteDataType::boolean_datatype(), - // Value::UInt8(_) => ConcreteDataType::uint8_datatype(), - // Value::UInt16(_) => ConcreteDataType::uint16_datatype(), - // Value::UInt32(_) => ConcreteDataType::uint32_datatype(), - // Value::UInt64(_) => ConcreteDataType::uint64_datatype(), - // Value::Int8(_) => ConcreteDataType::int8_datatype(), - // Value::Int16(_) => ConcreteDataType::int16_datatype(), - // Value::Int32(_) => ConcreteDataType::int32_datatype(), - // Value::Int64(_) => ConcreteDataType::int64_datatype(), - // Value::Float32(_) => ConcreteDataType::float32_datatype(), - // Value::Float64(_) => ConcreteDataType::float64_datatype(), - // Value::String(_) => ConcreteDataType::string_datatype(), - // Value::Binary(_) => ConcreteDataType::binary_datatype(), - // Value::List(list) => ConcreteDataType::list_datatype(list.datatype().clone()), - // Value::Date(_) => ConcreteDataType::date_datatype(), - // Value::DateTime(_) => ConcreteDataType::datetime_datatype(), - // Value::Timestamp(v) => ConcreteDataType::timestamp_datatype(v.unit()), - // } } /// Returns true if this is a null value. @@ -283,6 +279,9 @@ impl_value_from!(Float32, f32); impl_value_from!(Float64, f64); impl_value_from!(String, StringBytes); impl_value_from!(Binary, Bytes); +impl_value_from!(Date, Date); +impl_value_from!(DateTime, DateTime); +impl_value_from!(Timestamp, Timestamp); impl From for Value { fn from(string: String) -> Value { @@ -302,12 +301,6 @@ impl From> for Value { } } -impl From for Value { - fn from(v: Timestamp) -> Self { - Value::Timestamp(v) - } -} - impl From<&[u8]> for Value { fn from(bytes: &[u8]) -> Value { Value::Binary(bytes.into()) @@ -343,6 +336,7 @@ impl TryFrom for serde_json::Value { } } +// TODO(yingwen): Consider removing the `datatype` field from `ListValue`. /// List value. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ListValue { @@ -396,61 +390,61 @@ impl Ord for ListValue { impl TryFrom for Value { type Error = error::Error; - fn try_from(_v: ScalarValue) -> Result { - // let v = match v { - // ScalarValue::Boolean(b) => Value::from(b), - // ScalarValue::Float32(f) => Value::from(f), - // ScalarValue::Float64(f) => Value::from(f), - // ScalarValue::Int8(i) => Value::from(i), - // ScalarValue::Int16(i) => Value::from(i), - // ScalarValue::Int32(i) => Value::from(i), - // ScalarValue::Int64(i) => Value::from(i), - // ScalarValue::UInt8(u) => Value::from(u), - // ScalarValue::UInt16(u) => Value::from(u), - // ScalarValue::UInt32(u) => Value::from(u), - // ScalarValue::UInt64(u) => Value::from(u), - // ScalarValue::Utf8(s) | ScalarValue::LargeUtf8(s) => { - // Value::from(s.map(StringBytes::from)) - // } - // ScalarValue::Binary(b) | ScalarValue::LargeBinary(b) => Value::from(b.map(Bytes::from)), - // ScalarValue::List(vs, t) => { - // let items = if let Some(vs) = vs { - // let vs = vs - // .into_iter() - // .map(ScalarValue::try_into) - // .collect::>()?; - // Some(Box::new(vs)) - // } else { - // None - // }; - // let datatype = t.as_ref().try_into()?; - // Value::List(ListValue::new(items, datatype)) - // } - // ScalarValue::Date32(d) => d.map(|x| Value::Date(Date::new(x))).unwrap_or(Value::Null), - // ScalarValue::Date64(d) => d - // .map(|x| Value::DateTime(DateTime::new(x))) - // .unwrap_or(Value::Null), - // ScalarValue::TimestampSecond(t, _) => t - // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Second))) - // .unwrap_or(Value::Null), - // ScalarValue::TimestampMillisecond(t, _) => t - // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Millisecond))) - // .unwrap_or(Value::Null), - // ScalarValue::TimestampMicrosecond(t, _) => t - // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Microsecond))) - // .unwrap_or(Value::Null), - // ScalarValue::TimestampNanosecond(t, _) => t - // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Nanosecond))) - // .unwrap_or(Value::Null), - // _ => { - // return error::UnsupportedArrowTypeSnafu { - // arrow_type: v.get_datatype(), - // } - // .fail() - // } - // }; - // Ok(v) - unimplemented!() + // TODO(yingwen): Implement it. + fn try_from(v: ScalarValue) -> Result { + let v = match v { + ScalarValue::Boolean(b) => Value::from(b), + ScalarValue::Float32(f) => Value::from(f), + ScalarValue::Float64(f) => Value::from(f), + ScalarValue::Int8(i) => Value::from(i), + ScalarValue::Int16(i) => Value::from(i), + ScalarValue::Int32(i) => Value::from(i), + ScalarValue::Int64(i) => Value::from(i), + ScalarValue::UInt8(u) => Value::from(u), + ScalarValue::UInt16(u) => Value::from(u), + ScalarValue::UInt32(u) => Value::from(u), + ScalarValue::UInt64(u) => Value::from(u), + // ScalarValue::Utf8(s) | ScalarValue::LargeUtf8(s) => { + // Value::from(s.map(StringBytes::from)) + // } + ScalarValue::Binary(b) | ScalarValue::LargeBinary(b) => Value::from(b.map(Bytes::from)), + // ScalarValue::List(vs, t) => { + // let items = if let Some(vs) = vs { + // let vs = vs + // .into_iter() + // .map(ScalarValue::try_into) + // .collect::>()?; + // Some(Box::new(vs)) + // } else { + // None + // }; + // let datatype = t.as_ref().try_into()?; + // Value::List(ListValue::new(items, datatype)) + // } + ScalarValue::Date32(d) => d.map(|x| Value::Date(Date::new(x))).unwrap_or(Value::Null), + // ScalarValue::Date64(d) => d + // .map(|x| Value::DateTime(DateTime::new(x))) + // .unwrap_or(Value::Null), + // ScalarValue::TimestampSecond(t, _) => t + // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Second))) + // .unwrap_or(Value::Null), + // ScalarValue::TimestampMillisecond(t, _) => t + // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Millisecond))) + // .unwrap_or(Value::Null), + // ScalarValue::TimestampMicrosecond(t, _) => t + // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Microsecond))) + // .unwrap_or(Value::Null), + // ScalarValue::TimestampNanosecond(t, _) => t + // .map(|x| Value::Timestamp(Timestamp::new(x, TimeUnit::Nanosecond))) + // .unwrap_or(Value::Null), + _ => { + return error::UnsupportedArrowTypeSnafu { + arrow_type: v.get_datatype(), + } + .fail() + } + }; + Ok(v) } } @@ -583,6 +577,9 @@ impl_value_ref_from!(Int32, i32); impl_value_ref_from!(Int64, i64); impl_value_ref_from!(Float32, f32); impl_value_ref_from!(Float64, f64); +impl_value_ref_from!(Date, Date); +impl_value_ref_from!(DateTime, DateTime); +impl_value_ref_from!(Timestamp, Timestamp); impl<'a> From<&'a str> for ValueRef<'a> { fn from(string: &'a str) -> ValueRef<'a> { @@ -647,648 +644,595 @@ impl<'a> PartialOrd for ListValueRef<'a> { } } -// #[cfg(test)] -// mod tests { -// use arrow::datatypes::DataType as ArrowDataType; -// use num_traits::Float; - -// use super::*; - -// #[test] -// fn test_try_from_scalar_value() { -// assert_eq!( -// Value::Boolean(true), -// ScalarValue::Boolean(Some(true)).try_into().unwrap() -// ); -// assert_eq!( -// Value::Boolean(false), -// ScalarValue::Boolean(Some(false)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Boolean(None).try_into().unwrap()); - -// assert_eq!( -// Value::Float32(1.0f32.into()), -// ScalarValue::Float32(Some(1.0f32)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Float32(None).try_into().unwrap()); - -// assert_eq!( -// Value::Float64(2.0f64.into()), -// ScalarValue::Float64(Some(2.0f64)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Float64(None).try_into().unwrap()); - -// assert_eq!( -// Value::Int8(i8::MAX), -// ScalarValue::Int8(Some(i8::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Int8(None).try_into().unwrap()); - -// assert_eq!( -// Value::Int16(i16::MAX), -// ScalarValue::Int16(Some(i16::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Int16(None).try_into().unwrap()); - -// assert_eq!( -// Value::Int32(i32::MAX), -// ScalarValue::Int32(Some(i32::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Int32(None).try_into().unwrap()); - -// assert_eq!( -// Value::Int64(i64::MAX), -// ScalarValue::Int64(Some(i64::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Int64(None).try_into().unwrap()); - -// assert_eq!( -// Value::UInt8(u8::MAX), -// ScalarValue::UInt8(Some(u8::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::UInt8(None).try_into().unwrap()); - -// assert_eq!( -// Value::UInt16(u16::MAX), -// ScalarValue::UInt16(Some(u16::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::UInt16(None).try_into().unwrap()); - -// assert_eq!( -// Value::UInt32(u32::MAX), -// ScalarValue::UInt32(Some(u32::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::UInt32(None).try_into().unwrap()); - -// assert_eq!( -// Value::UInt64(u64::MAX), -// ScalarValue::UInt64(Some(u64::MAX)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::UInt64(None).try_into().unwrap()); - -// assert_eq!( -// Value::from("hello"), -// ScalarValue::Utf8(Some("hello".to_string())) -// .try_into() -// .unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Utf8(None).try_into().unwrap()); - -// assert_eq!( -// Value::from("large_hello"), -// ScalarValue::LargeUtf8(Some("large_hello".to_string())) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::LargeUtf8(None).try_into().unwrap() -// ); - -// assert_eq!( -// Value::from("world".as_bytes()), -// ScalarValue::Binary(Some("world".as_bytes().to_vec())) -// .try_into() -// .unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Binary(None).try_into().unwrap()); - -// assert_eq!( -// Value::from("large_world".as_bytes()), -// ScalarValue::LargeBinary(Some("large_world".as_bytes().to_vec())) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::LargeBinary(None).try_into().unwrap() -// ); - -// assert_eq!( -// Value::List(ListValue::new( -// Some(Box::new(vec![Value::Int32(1), Value::Null])), -// ConcreteDataType::int32_datatype() -// )), -// ScalarValue::List( -// Some(Box::new(vec![ -// ScalarValue::Int32(Some(1)), -// ScalarValue::Int32(None) -// ])), -// Box::new(ArrowDataType::Int32) -// ) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::List(ListValue::new(None, ConcreteDataType::uint32_datatype())), -// ScalarValue::List(None, Box::new(ArrowDataType::UInt32)) -// .try_into() -// .unwrap() -// ); - -// assert_eq!( -// Value::Date(Date::new(123)), -// ScalarValue::Date32(Some(123)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Date32(None).try_into().unwrap()); - -// assert_eq!( -// Value::DateTime(DateTime::new(456)), -// ScalarValue::Date64(Some(456)).try_into().unwrap() -// ); -// assert_eq!(Value::Null, ScalarValue::Date64(None).try_into().unwrap()); - -// assert_eq!( -// Value::Timestamp(Timestamp::new(1, TimeUnit::Second)), -// ScalarValue::TimestampSecond(Some(1), None) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::TimestampSecond(None, None).try_into().unwrap() -// ); - -// assert_eq!( -// Value::Timestamp(Timestamp::new(1, TimeUnit::Millisecond)), -// ScalarValue::TimestampMillisecond(Some(1), None) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::TimestampMillisecond(None, None) -// .try_into() -// .unwrap() -// ); - -// assert_eq!( -// Value::Timestamp(Timestamp::new(1, TimeUnit::Microsecond)), -// ScalarValue::TimestampMicrosecond(Some(1), None) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::TimestampMicrosecond(None, None) -// .try_into() -// .unwrap() -// ); - -// assert_eq!( -// Value::Timestamp(Timestamp::new(1, TimeUnit::Nanosecond)), -// ScalarValue::TimestampNanosecond(Some(1), None) -// .try_into() -// .unwrap() -// ); -// assert_eq!( -// Value::Null, -// ScalarValue::TimestampNanosecond(None, None) -// .try_into() -// .unwrap() -// ); - -// let result: Result = ScalarValue::Decimal128(Some(1), 0, 0).try_into(); -// result -// .unwrap_err() -// .to_string() -// .contains("Unsupported arrow data type, type: Decimal(0, 0)"); -// } - -// #[test] -// fn test_value_from_inner() { -// assert_eq!(Value::Boolean(true), Value::from(true)); -// assert_eq!(Value::Boolean(false), Value::from(false)); - -// assert_eq!(Value::UInt8(u8::MIN), Value::from(u8::MIN)); -// assert_eq!(Value::UInt8(u8::MAX), Value::from(u8::MAX)); - -// assert_eq!(Value::UInt16(u16::MIN), Value::from(u16::MIN)); -// assert_eq!(Value::UInt16(u16::MAX), Value::from(u16::MAX)); - -// assert_eq!(Value::UInt32(u32::MIN), Value::from(u32::MIN)); -// assert_eq!(Value::UInt32(u32::MAX), Value::from(u32::MAX)); - -// assert_eq!(Value::UInt64(u64::MIN), Value::from(u64::MIN)); -// assert_eq!(Value::UInt64(u64::MAX), Value::from(u64::MAX)); - -// assert_eq!(Value::Int8(i8::MIN), Value::from(i8::MIN)); -// assert_eq!(Value::Int8(i8::MAX), Value::from(i8::MAX)); - -// assert_eq!(Value::Int16(i16::MIN), Value::from(i16::MIN)); -// assert_eq!(Value::Int16(i16::MAX), Value::from(i16::MAX)); - -// assert_eq!(Value::Int32(i32::MIN), Value::from(i32::MIN)); -// assert_eq!(Value::Int32(i32::MAX), Value::from(i32::MAX)); - -// assert_eq!(Value::Int64(i64::MIN), Value::from(i64::MIN)); -// assert_eq!(Value::Int64(i64::MAX), Value::from(i64::MAX)); - -// assert_eq!( -// Value::Float32(OrderedFloat(f32::MIN)), -// Value::from(f32::MIN) -// ); -// assert_eq!( -// Value::Float32(OrderedFloat(f32::MAX)), -// Value::from(f32::MAX) -// ); - -// assert_eq!( -// Value::Float64(OrderedFloat(f64::MIN)), -// Value::from(f64::MIN) -// ); -// assert_eq!( -// Value::Float64(OrderedFloat(f64::MAX)), -// Value::from(f64::MAX) -// ); - -// let string_bytes = StringBytes::from("hello"); -// assert_eq!( -// Value::String(string_bytes.clone()), -// Value::from(string_bytes) -// ); - -// let bytes = Bytes::from(b"world".as_slice()); -// assert_eq!(Value::Binary(bytes.clone()), Value::from(bytes)); -// } - -// fn check_type_and_value(data_type: &ConcreteDataType, value: &Value) { -// assert_eq!(*data_type, value.data_type()); -// assert_eq!(data_type.logical_type_id(), value.logical_type_id()); -// } - -// #[test] -// fn test_value_datatype() { -// check_type_and_value(&ConcreteDataType::boolean_datatype(), &Value::Boolean(true)); -// check_type_and_value(&ConcreteDataType::uint8_datatype(), &Value::UInt8(u8::MIN)); -// check_type_and_value( -// &ConcreteDataType::uint16_datatype(), -// &Value::UInt16(u16::MIN), -// ); -// check_type_and_value( -// &ConcreteDataType::uint16_datatype(), -// &Value::UInt16(u16::MAX), -// ); -// check_type_and_value( -// &ConcreteDataType::uint32_datatype(), -// &Value::UInt32(u32::MIN), -// ); -// check_type_and_value( -// &ConcreteDataType::uint64_datatype(), -// &Value::UInt64(u64::MIN), -// ); -// check_type_and_value(&ConcreteDataType::int8_datatype(), &Value::Int8(i8::MIN)); -// check_type_and_value(&ConcreteDataType::int16_datatype(), &Value::Int16(i16::MIN)); -// check_type_and_value(&ConcreteDataType::int32_datatype(), &Value::Int32(i32::MIN)); -// check_type_and_value(&ConcreteDataType::int64_datatype(), &Value::Int64(i64::MIN)); -// check_type_and_value( -// &ConcreteDataType::float32_datatype(), -// &Value::Float32(OrderedFloat(f32::MIN)), -// ); -// check_type_and_value( -// &ConcreteDataType::float64_datatype(), -// &Value::Float64(OrderedFloat(f64::MIN)), -// ); -// check_type_and_value( -// &ConcreteDataType::string_datatype(), -// &Value::String(StringBytes::from("hello")), -// ); -// check_type_and_value( -// &ConcreteDataType::binary_datatype(), -// &Value::Binary(Bytes::from(b"world".as_slice())), -// ); -// check_type_and_value( -// &ConcreteDataType::list_datatype(ConcreteDataType::int32_datatype()), -// &Value::List(ListValue::new( -// Some(Box::new(vec![Value::Int32(10)])), -// ConcreteDataType::int32_datatype(), -// )), -// ); -// check_type_and_value( -// &ConcreteDataType::date_datatype(), -// &Value::Date(Date::new(1)), -// ); -// check_type_and_value( -// &ConcreteDataType::datetime_datatype(), -// &Value::DateTime(DateTime::new(1)), -// ); -// check_type_and_value( -// &ConcreteDataType::timestamp_millis_datatype(), -// &Value::Timestamp(Timestamp::from_millis(1)), -// ); -// } - -// #[test] -// fn test_value_from_string() { -// let hello = "hello".to_string(); -// assert_eq!( -// Value::String(StringBytes::from(hello.clone())), -// Value::from(hello) -// ); - -// let world = "world"; -// assert_eq!(Value::String(StringBytes::from(world)), Value::from(world)); -// } - -// #[test] -// fn test_value_from_bytes() { -// let hello = b"hello".to_vec(); -// assert_eq!( -// Value::Binary(Bytes::from(hello.clone())), -// Value::from(hello) -// ); - -// let world: &[u8] = b"world"; -// assert_eq!(Value::Binary(Bytes::from(world)), Value::from(world)); -// } - -// fn to_json(value: Value) -> serde_json::Value { -// value.try_into().unwrap() -// } - -// #[test] -// fn test_to_json_value() { -// assert_eq!(serde_json::Value::Null, to_json(Value::Null)); -// assert_eq!(serde_json::Value::Bool(true), to_json(Value::Boolean(true))); -// assert_eq!( -// serde_json::Value::Number(20u8.into()), -// to_json(Value::UInt8(20)) -// ); -// assert_eq!( -// serde_json::Value::Number(20i8.into()), -// to_json(Value::Int8(20)) -// ); -// assert_eq!( -// serde_json::Value::Number(2000u16.into()), -// to_json(Value::UInt16(2000)) -// ); -// assert_eq!( -// serde_json::Value::Number(2000i16.into()), -// to_json(Value::Int16(2000)) -// ); -// assert_eq!( -// serde_json::Value::Number(3000u32.into()), -// to_json(Value::UInt32(3000)) -// ); -// assert_eq!( -// serde_json::Value::Number(3000i32.into()), -// to_json(Value::Int32(3000)) -// ); -// assert_eq!( -// serde_json::Value::Number(4000u64.into()), -// to_json(Value::UInt64(4000)) -// ); -// assert_eq!( -// serde_json::Value::Number(4000i64.into()), -// to_json(Value::Int64(4000)) -// ); -// assert_eq!( -// serde_json::Value::from(125.0f32), -// to_json(Value::Float32(125.0.into())) -// ); -// assert_eq!( -// serde_json::Value::from(125.0f64), -// to_json(Value::Float64(125.0.into())) -// ); -// assert_eq!( -// serde_json::Value::String(String::from("hello")), -// to_json(Value::String(StringBytes::from("hello"))) -// ); -// assert_eq!( -// serde_json::Value::from(b"world".as_slice()), -// to_json(Value::Binary(Bytes::from(b"world".as_slice()))) -// ); -// assert_eq!( -// serde_json::Value::Number(5000i32.into()), -// to_json(Value::Date(Date::new(5000))) -// ); -// assert_eq!( -// serde_json::Value::Number(5000i64.into()), -// to_json(Value::DateTime(DateTime::new(5000))) -// ); - -// assert_eq!( -// serde_json::Value::Number(1.into()), -// to_json(Value::Timestamp(Timestamp::from_millis(1))) -// ); - -// let json_value: serde_json::Value = -// serde_json::from_str(r#"{"items":[{"Int32":123}],"datatype":{"Int32":{}}}"#).unwrap(); -// assert_eq!( -// json_value, -// to_json(Value::List(ListValue { -// items: Some(Box::new(vec![Value::Int32(123)])), -// datatype: ConcreteDataType::int32_datatype(), -// })) -// ); -// } - -// #[test] -// fn test_null_value() { -// assert!(Value::Null.is_null()); -// assert!(!Value::Boolean(true).is_null()); -// assert!(Value::Null < Value::Boolean(false)); -// assert!(Value::Boolean(true) > Value::Null); -// assert!(Value::Null < Value::Int32(10)); -// assert!(Value::Int32(10) > Value::Null); -// } - -// #[test] -// fn test_null_value_ref() { -// assert!(ValueRef::Null.is_null()); -// assert!(!ValueRef::Boolean(true).is_null()); -// assert!(ValueRef::Null < ValueRef::Boolean(false)); -// assert!(ValueRef::Boolean(true) > ValueRef::Null); -// assert!(ValueRef::Null < ValueRef::Int32(10)); -// assert!(ValueRef::Int32(10) > ValueRef::Null); -// } - -// #[test] -// fn test_as_value_ref() { -// macro_rules! check_as_value_ref { -// ($Variant: ident, $data: expr) => { -// let value = Value::$Variant($data); -// let value_ref = value.as_value_ref(); -// let expect_ref = ValueRef::$Variant($data); - -// assert_eq!(expect_ref, value_ref); -// }; -// } - -// assert_eq!(ValueRef::Null, Value::Null.as_value_ref()); -// check_as_value_ref!(Boolean, true); -// check_as_value_ref!(UInt8, 123); -// check_as_value_ref!(UInt16, 123); -// check_as_value_ref!(UInt32, 123); -// check_as_value_ref!(UInt64, 123); -// check_as_value_ref!(Int8, -12); -// check_as_value_ref!(Int16, -12); -// check_as_value_ref!(Int32, -12); -// check_as_value_ref!(Int64, -12); -// check_as_value_ref!(Float32, OrderedF32::from(16.0)); -// check_as_value_ref!(Float64, OrderedF64::from(16.0)); -// check_as_value_ref!(Timestamp, Timestamp::from_millis(1)); - -// assert_eq!( -// ValueRef::String("hello"), -// Value::String("hello".into()).as_value_ref() -// ); -// assert_eq!( -// ValueRef::Binary(b"hello"), -// Value::Binary("hello".as_bytes().into()).as_value_ref() -// ); - -// check_as_value_ref!(Date, Date::new(103)); -// check_as_value_ref!(DateTime, DateTime::new(1034)); - -// let list = ListValue { -// items: None, -// datatype: ConcreteDataType::int32_datatype(), -// }; -// assert_eq!( -// ValueRef::List(ListValueRef::Ref { val: &list }), -// Value::List(list.clone()).as_value_ref() -// ); -// } - -// #[test] -// fn test_value_ref_as() { -// macro_rules! check_as_null { -// ($method: ident) => { -// assert_eq!(None, ValueRef::Null.$method().unwrap()); -// }; -// } - -// check_as_null!(as_binary); -// check_as_null!(as_string); -// check_as_null!(as_boolean); -// check_as_null!(as_date); -// check_as_null!(as_datetime); -// check_as_null!(as_list); - -// macro_rules! check_as_correct { -// ($data: expr, $Variant: ident, $method: ident) => { -// assert_eq!(Some($data), ValueRef::$Variant($data).$method().unwrap()); -// }; -// } - -// check_as_correct!("hello", String, as_string); -// check_as_correct!("hello".as_bytes(), Binary, as_binary); -// check_as_correct!(true, Boolean, as_boolean); -// check_as_correct!(Date::new(123), Date, as_date); -// check_as_correct!(DateTime::new(12), DateTime, as_datetime); -// let list = ListValue { -// items: None, -// datatype: ConcreteDataType::int32_datatype(), -// }; -// check_as_correct!(ListValueRef::Ref { val: &list }, List, as_list); - -// let wrong_value = ValueRef::Int32(12345); -// assert!(wrong_value.as_binary().is_err()); -// assert!(wrong_value.as_string().is_err()); -// assert!(wrong_value.as_boolean().is_err()); -// assert!(wrong_value.as_date().is_err()); -// assert!(wrong_value.as_datetime().is_err()); -// assert!(wrong_value.as_list().is_err()); -// } - -// #[test] -// fn test_into_value_ref() { -// macro_rules! check_into_value_ref { -// ($Variant: ident, $data: expr, $PrimitiveType: ident, $Wrapper: ident) => { -// let data: $PrimitiveType = $data; -// assert_eq!( -// ValueRef::$Variant($Wrapper::from(data)), -// data.into_value_ref() -// ); -// assert_eq!( -// ValueRef::$Variant($Wrapper::from(data)), -// ValueRef::from(data) -// ); -// assert_eq!( -// ValueRef::$Variant($Wrapper::from(data)), -// Some(data).into_value_ref() -// ); -// assert_eq!( -// ValueRef::$Variant($Wrapper::from(data)), -// ValueRef::from(Some(data)) -// ); -// let x: Option<$PrimitiveType> = None; -// assert_eq!(ValueRef::Null, x.into_value_ref()); -// assert_eq!(ValueRef::Null, x.into()); -// }; -// } - -// macro_rules! check_primitive_into_value_ref { -// ($Variant: ident, $data: expr, $PrimitiveType: ident) => { -// check_into_value_ref!($Variant, $data, $PrimitiveType, $PrimitiveType) -// }; -// } - -// check_primitive_into_value_ref!(Boolean, true, bool); -// check_primitive_into_value_ref!(UInt8, 10, u8); -// check_primitive_into_value_ref!(UInt16, 20, u16); -// check_primitive_into_value_ref!(UInt32, 30, u32); -// check_primitive_into_value_ref!(UInt64, 40, u64); -// check_primitive_into_value_ref!(Int8, -10, i8); -// check_primitive_into_value_ref!(Int16, -20, i16); -// check_primitive_into_value_ref!(Int32, -30, i32); -// check_primitive_into_value_ref!(Int64, -40, i64); -// check_into_value_ref!(Float32, 10.0, f32, OrderedF32); -// check_into_value_ref!(Float64, 10.0, f64, OrderedF64); - -// let hello = "hello"; -// assert_eq!( -// ValueRef::Binary(hello.as_bytes()), -// ValueRef::from(hello.as_bytes()) -// ); -// assert_eq!(ValueRef::String(hello), ValueRef::from(hello)); -// } - -// #[test] -// fn test_display() { -// assert_eq!(Value::Null.to_string(), "Null"); -// assert_eq!(Value::UInt8(8).to_string(), "8"); -// assert_eq!(Value::UInt16(16).to_string(), "16"); -// assert_eq!(Value::UInt32(32).to_string(), "32"); -// assert_eq!(Value::UInt64(64).to_string(), "64"); -// assert_eq!(Value::Int8(-8).to_string(), "-8"); -// assert_eq!(Value::Int16(-16).to_string(), "-16"); -// assert_eq!(Value::Int32(-32).to_string(), "-32"); -// assert_eq!(Value::Int64(-64).to_string(), "-64"); -// assert_eq!(Value::Float32((-32.123).into()).to_string(), "-32.123"); -// assert_eq!(Value::Float64((-64.123).into()).to_string(), "-64.123"); -// assert_eq!(Value::Float64(OrderedF64::infinity()).to_string(), "inf"); -// assert_eq!(Value::Float64(OrderedF64::nan()).to_string(), "NaN"); -// assert_eq!(Value::String(StringBytes::from("123")).to_string(), "123"); -// assert_eq!( -// Value::Binary(Bytes::from(vec![1, 2, 3])).to_string(), -// "010203" -// ); -// assert_eq!(Value::Date(Date::new(0)).to_string(), "1970-01-01"); -// assert_eq!( -// Value::DateTime(DateTime::new(0)).to_string(), -// "1970-01-01 00:00:00" -// ); -// assert_eq!( -// Value::Timestamp(Timestamp::new(1000, TimeUnit::Millisecond)).to_string(), -// "1970-01-01 00:00:01+0000" -// ); -// assert_eq!( -// Value::List(ListValue::new( -// Some(Box::new(vec![Value::Int8(1), Value::Int8(2)])), -// ConcreteDataType::int8_datatype(), -// )) -// .to_string(), -// "Int8[1, 2]" -// ); -// assert_eq!( -// Value::List(ListValue::new( -// Some(Box::new(vec![])), -// ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond), -// )) -// .to_string(), -// "Timestamp[]" -// ); -// } -// } +// TODO(yingwen): Pass all tests. +#[cfg(test)] +mod tests { + use num_traits::Float; + + use super::*; + + #[test] + fn test_try_from_scalar_value() { + assert_eq!( + Value::Boolean(true), + ScalarValue::Boolean(Some(true)).try_into().unwrap() + ); + assert_eq!( + Value::Boolean(false), + ScalarValue::Boolean(Some(false)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Boolean(None).try_into().unwrap()); + + assert_eq!( + Value::Float32(1.0f32.into()), + ScalarValue::Float32(Some(1.0f32)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Float32(None).try_into().unwrap()); + + assert_eq!( + Value::Float64(2.0f64.into()), + ScalarValue::Float64(Some(2.0f64)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Float64(None).try_into().unwrap()); + + assert_eq!( + Value::Int8(i8::MAX), + ScalarValue::Int8(Some(i8::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Int8(None).try_into().unwrap()); + + assert_eq!( + Value::Int16(i16::MAX), + ScalarValue::Int16(Some(i16::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Int16(None).try_into().unwrap()); + + assert_eq!( + Value::Int32(i32::MAX), + ScalarValue::Int32(Some(i32::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Int32(None).try_into().unwrap()); + + assert_eq!( + Value::Int64(i64::MAX), + ScalarValue::Int64(Some(i64::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Int64(None).try_into().unwrap()); + + assert_eq!( + Value::UInt8(u8::MAX), + ScalarValue::UInt8(Some(u8::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::UInt8(None).try_into().unwrap()); + + assert_eq!( + Value::UInt16(u16::MAX), + ScalarValue::UInt16(Some(u16::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::UInt16(None).try_into().unwrap()); + + assert_eq!( + Value::UInt32(u32::MAX), + ScalarValue::UInt32(Some(u32::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::UInt32(None).try_into().unwrap()); + + assert_eq!( + Value::UInt64(u64::MAX), + ScalarValue::UInt64(Some(u64::MAX)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::UInt64(None).try_into().unwrap()); + + // assert_eq!( + // Value::from("hello"), + // ScalarValue::Utf8(Some("hello".to_string())) + // .try_into() + // .unwrap() + // ); + // assert_eq!(Value::Null, ScalarValue::Utf8(None).try_into().unwrap()); + + // assert_eq!( + // Value::from("large_hello"), + // ScalarValue::LargeUtf8(Some("large_hello".to_string())) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::Null, + // ScalarValue::LargeUtf8(None).try_into().unwrap() + // ); + + assert_eq!( + Value::from("world".as_bytes()), + ScalarValue::Binary(Some("world".as_bytes().to_vec())) + .try_into() + .unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Binary(None).try_into().unwrap()); + + assert_eq!( + Value::from("large_world".as_bytes()), + ScalarValue::LargeBinary(Some("large_world".as_bytes().to_vec())) + .try_into() + .unwrap() + ); + assert_eq!( + Value::Null, + ScalarValue::LargeBinary(None).try_into().unwrap() + ); + + // assert_eq!( + // Value::List(ListValue::new( + // Some(Box::new(vec![Value::Int32(1), Value::Null])), + // ConcreteDataType::int32_datatype() + // )), + // ScalarValue::List( + // Some(Box::new(vec![ + // ScalarValue::Int32(Some(1)), + // ScalarValue::Int32(None) + // ])), + // Box::new(ArrowDataType::Int32) + // ) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::List(ListValue::new(None, ConcreteDataType::uint32_datatype())), + // ScalarValue::List(None, Box::new(ArrowDataType::UInt32)) + // .try_into() + // .unwrap() + // ); + + assert_eq!( + Value::Date(Date::new(123)), + ScalarValue::Date32(Some(123)).try_into().unwrap() + ); + assert_eq!(Value::Null, ScalarValue::Date32(None).try_into().unwrap()); + + // assert_eq!( + // Value::DateTime(DateTime::new(456)), + // ScalarValue::Date64(Some(456)).try_into().unwrap() + // ); + // assert_eq!(Value::Null, ScalarValue::Date64(None).try_into().unwrap()); + + // assert_eq!( + // Value::Timestamp(Timestamp::new(1, TimeUnit::Second)), + // ScalarValue::TimestampSecond(Some(1), None) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::Null, + // ScalarValue::TimestampSecond(None, None).try_into().unwrap() + // ); + + // assert_eq!( + // Value::Timestamp(Timestamp::new(1, TimeUnit::Millisecond)), + // ScalarValue::TimestampMillisecond(Some(1), None) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::Null, + // ScalarValue::TimestampMillisecond(None, None) + // .try_into() + // .unwrap() + // ); + + // assert_eq!( + // Value::Timestamp(Timestamp::new(1, TimeUnit::Microsecond)), + // ScalarValue::TimestampMicrosecond(Some(1), None) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::Null, + // ScalarValue::TimestampMicrosecond(None, None) + // .try_into() + // .unwrap() + // ); + + // assert_eq!( + // Value::Timestamp(Timestamp::new(1, TimeUnit::Nanosecond)), + // ScalarValue::TimestampNanosecond(Some(1), None) + // .try_into() + // .unwrap() + // ); + // assert_eq!( + // Value::Null, + // ScalarValue::TimestampNanosecond(None, None) + // .try_into() + // .unwrap() + // ); + + let result: Result = ScalarValue::Decimal128(Some(1), 0, 0).try_into(); + result + .unwrap_err() + .to_string() + .contains("Unsupported arrow data type, type: Decimal(0, 0)"); + } + + #[test] + fn test_value_from_inner() { + assert_eq!(Value::Boolean(true), Value::from(true)); + assert_eq!(Value::Boolean(false), Value::from(false)); + + assert_eq!(Value::UInt8(u8::MIN), Value::from(u8::MIN)); + assert_eq!(Value::UInt8(u8::MAX), Value::from(u8::MAX)); + + assert_eq!(Value::UInt16(u16::MIN), Value::from(u16::MIN)); + assert_eq!(Value::UInt16(u16::MAX), Value::from(u16::MAX)); + + assert_eq!(Value::UInt32(u32::MIN), Value::from(u32::MIN)); + assert_eq!(Value::UInt32(u32::MAX), Value::from(u32::MAX)); + + assert_eq!(Value::UInt64(u64::MIN), Value::from(u64::MIN)); + assert_eq!(Value::UInt64(u64::MAX), Value::from(u64::MAX)); + + assert_eq!(Value::Int8(i8::MIN), Value::from(i8::MIN)); + assert_eq!(Value::Int8(i8::MAX), Value::from(i8::MAX)); + + assert_eq!(Value::Int16(i16::MIN), Value::from(i16::MIN)); + assert_eq!(Value::Int16(i16::MAX), Value::from(i16::MAX)); + + assert_eq!(Value::Int32(i32::MIN), Value::from(i32::MIN)); + assert_eq!(Value::Int32(i32::MAX), Value::from(i32::MAX)); + + assert_eq!(Value::Int64(i64::MIN), Value::from(i64::MIN)); + assert_eq!(Value::Int64(i64::MAX), Value::from(i64::MAX)); + + assert_eq!( + Value::Float32(OrderedFloat(f32::MIN)), + Value::from(f32::MIN) + ); + assert_eq!( + Value::Float32(OrderedFloat(f32::MAX)), + Value::from(f32::MAX) + ); + + assert_eq!( + Value::Float64(OrderedFloat(f64::MIN)), + Value::from(f64::MIN) + ); + assert_eq!( + Value::Float64(OrderedFloat(f64::MAX)), + Value::from(f64::MAX) + ); + + let string_bytes = StringBytes::from("hello"); + assert_eq!( + Value::String(string_bytes.clone()), + Value::from(string_bytes) + ); + + let bytes = Bytes::from(b"world".as_slice()); + assert_eq!(Value::Binary(bytes.clone()), Value::from(bytes)); + } + + fn check_type_and_value(data_type: &ConcreteDataType, value: &Value) { + assert_eq!(*data_type, value.data_type()); + assert_eq!(data_type.logical_type_id(), value.logical_type_id()); + } + + #[test] + fn test_value_datatype() { + check_type_and_value(&ConcreteDataType::boolean_datatype(), &Value::Boolean(true)); + check_type_and_value(&ConcreteDataType::uint8_datatype(), &Value::UInt8(u8::MIN)); + check_type_and_value( + &ConcreteDataType::uint16_datatype(), + &Value::UInt16(u16::MIN), + ); + check_type_and_value( + &ConcreteDataType::uint16_datatype(), + &Value::UInt16(u16::MAX), + ); + check_type_and_value( + &ConcreteDataType::uint32_datatype(), + &Value::UInt32(u32::MIN), + ); + check_type_and_value( + &ConcreteDataType::uint64_datatype(), + &Value::UInt64(u64::MIN), + ); + check_type_and_value(&ConcreteDataType::int8_datatype(), &Value::Int8(i8::MIN)); + check_type_and_value(&ConcreteDataType::int16_datatype(), &Value::Int16(i16::MIN)); + check_type_and_value(&ConcreteDataType::int32_datatype(), &Value::Int32(i32::MIN)); + check_type_and_value(&ConcreteDataType::int64_datatype(), &Value::Int64(i64::MIN)); + check_type_and_value( + &ConcreteDataType::float32_datatype(), + &Value::Float32(OrderedFloat(f32::MIN)), + ); + check_type_and_value( + &ConcreteDataType::float64_datatype(), + &Value::Float64(OrderedFloat(f64::MIN)), + ); + // check_type_and_value( + // &ConcreteDataType::string_datatype(), + // &Value::String(StringBytes::from("hello")), + // ); + check_type_and_value( + &ConcreteDataType::binary_datatype(), + &Value::Binary(Bytes::from(b"world".as_slice())), + ); + // check_type_and_value( + // &ConcreteDataType::list_datatype(ConcreteDataType::int32_datatype()), + // &Value::List(ListValue::new( + // Some(Box::new(vec![Value::Int32(10)])), + // ConcreteDataType::int32_datatype(), + // )), + // ); + check_type_and_value( + &ConcreteDataType::date_datatype(), + &Value::Date(Date::new(1)), + ); + // check_type_and_value( + // &ConcreteDataType::datetime_datatype(), + // &Value::DateTime(DateTime::new(1)), + // ); + // check_type_and_value( + // &ConcreteDataType::timestamp_millis_datatype(), + // &Value::Timestamp(Timestamp::from_millis(1)), + // ); + } + + #[test] + fn test_value_from_string() { + let hello = "hello".to_string(); + assert_eq!( + Value::String(StringBytes::from(hello.clone())), + Value::from(hello) + ); + + let world = "world"; + assert_eq!(Value::String(StringBytes::from(world)), Value::from(world)); + } + + #[test] + fn test_value_from_bytes() { + let hello = b"hello".to_vec(); + assert_eq!( + Value::Binary(Bytes::from(hello.clone())), + Value::from(hello) + ); + + let world: &[u8] = b"world"; + assert_eq!(Value::Binary(Bytes::from(world)), Value::from(world)); + } + + fn to_json(value: Value) -> serde_json::Value { + value.try_into().unwrap() + } + + #[test] + fn test_to_json_value() { + assert_eq!(serde_json::Value::Null, to_json(Value::Null)); + assert_eq!(serde_json::Value::Bool(true), to_json(Value::Boolean(true))); + assert_eq!( + serde_json::Value::Number(20u8.into()), + to_json(Value::UInt8(20)) + ); + assert_eq!( + serde_json::Value::Number(20i8.into()), + to_json(Value::Int8(20)) + ); + assert_eq!( + serde_json::Value::Number(2000u16.into()), + to_json(Value::UInt16(2000)) + ); + assert_eq!( + serde_json::Value::Number(2000i16.into()), + to_json(Value::Int16(2000)) + ); + assert_eq!( + serde_json::Value::Number(3000u32.into()), + to_json(Value::UInt32(3000)) + ); + assert_eq!( + serde_json::Value::Number(3000i32.into()), + to_json(Value::Int32(3000)) + ); + assert_eq!( + serde_json::Value::Number(4000u64.into()), + to_json(Value::UInt64(4000)) + ); + assert_eq!( + serde_json::Value::Number(4000i64.into()), + to_json(Value::Int64(4000)) + ); + assert_eq!( + serde_json::Value::from(125.0f32), + to_json(Value::Float32(125.0.into())) + ); + assert_eq!( + serde_json::Value::from(125.0f64), + to_json(Value::Float64(125.0.into())) + ); + assert_eq!( + serde_json::Value::String(String::from("hello")), + to_json(Value::String(StringBytes::from("hello"))) + ); + assert_eq!( + serde_json::Value::from(b"world".as_slice()), + to_json(Value::Binary(Bytes::from(b"world".as_slice()))) + ); + assert_eq!( + serde_json::Value::Number(5000i32.into()), + to_json(Value::Date(Date::new(5000))) + ); + assert_eq!( + serde_json::Value::Number(5000i64.into()), + to_json(Value::DateTime(DateTime::new(5000))) + ); + + assert_eq!( + serde_json::Value::Number(1.into()), + to_json(Value::Timestamp(Timestamp::from_millis(1))) + ); + + // let json_value: serde_json::Value = + // serde_json::from_str(r#"{"items":[{"Int32":123}],"datatype":{"Int32":{}}}"#).unwrap(); + // assert_eq!( + // json_value, + // to_json(Value::List(ListValue { + // items: Some(Box::new(vec![Value::Int32(123)])), + // datatype: ConcreteDataType::int32_datatype(), + // })) + // ); + } + + #[test] + fn test_null_value() { + assert!(Value::Null.is_null()); + assert!(!Value::Boolean(true).is_null()); + assert!(Value::Null < Value::Boolean(false)); + assert!(Value::Boolean(true) > Value::Null); + assert!(Value::Null < Value::Int32(10)); + assert!(Value::Int32(10) > Value::Null); + } + + #[test] + fn test_null_value_ref() { + assert!(ValueRef::Null.is_null()); + assert!(!ValueRef::Boolean(true).is_null()); + assert!(ValueRef::Null < ValueRef::Boolean(false)); + assert!(ValueRef::Boolean(true) > ValueRef::Null); + assert!(ValueRef::Null < ValueRef::Int32(10)); + assert!(ValueRef::Int32(10) > ValueRef::Null); + } + + #[test] + fn test_as_value_ref() { + macro_rules! check_as_value_ref { + ($Variant: ident, $data: expr) => { + let value = Value::$Variant($data); + let value_ref = value.as_value_ref(); + let expect_ref = ValueRef::$Variant($data); + + assert_eq!(expect_ref, value_ref); + }; + } + + assert_eq!(ValueRef::Null, Value::Null.as_value_ref()); + check_as_value_ref!(Boolean, true); + check_as_value_ref!(UInt8, 123); + check_as_value_ref!(UInt16, 123); + check_as_value_ref!(UInt32, 123); + check_as_value_ref!(UInt64, 123); + check_as_value_ref!(Int8, -12); + check_as_value_ref!(Int16, -12); + check_as_value_ref!(Int32, -12); + check_as_value_ref!(Int64, -12); + check_as_value_ref!(Float32, OrderedF32::from(16.0)); + check_as_value_ref!(Float64, OrderedF64::from(16.0)); + check_as_value_ref!(Timestamp, Timestamp::from_millis(1)); + + assert_eq!( + ValueRef::String("hello"), + Value::String("hello".into()).as_value_ref() + ); + assert_eq!( + ValueRef::Binary(b"hello"), + Value::Binary("hello".as_bytes().into()).as_value_ref() + ); + + check_as_value_ref!(Date, Date::new(103)); + check_as_value_ref!(DateTime, DateTime::new(1034)); + + let list = ListValue { + items: None, + datatype: ConcreteDataType::int32_datatype(), + }; + assert_eq!( + ValueRef::List(ListValueRef::Ref { val: &list }), + Value::List(list.clone()).as_value_ref() + ); + } + + #[test] + fn test_value_ref_as() { + macro_rules! check_as_null { + ($method: ident) => { + assert_eq!(None, ValueRef::Null.$method().unwrap()); + }; + } + + check_as_null!(as_binary); + check_as_null!(as_string); + check_as_null!(as_boolean); + check_as_null!(as_date); + check_as_null!(as_datetime); + check_as_null!(as_list); + + macro_rules! check_as_correct { + ($data: expr, $Variant: ident, $method: ident) => { + assert_eq!(Some($data), ValueRef::$Variant($data).$method().unwrap()); + }; + } + + check_as_correct!("hello", String, as_string); + check_as_correct!("hello".as_bytes(), Binary, as_binary); + check_as_correct!(true, Boolean, as_boolean); + check_as_correct!(Date::new(123), Date, as_date); + check_as_correct!(DateTime::new(12), DateTime, as_datetime); + let list = ListValue { + items: None, + datatype: ConcreteDataType::int32_datatype(), + }; + check_as_correct!(ListValueRef::Ref { val: &list }, List, as_list); + + let wrong_value = ValueRef::Int32(12345); + assert!(wrong_value.as_binary().is_err()); + assert!(wrong_value.as_string().is_err()); + assert!(wrong_value.as_boolean().is_err()); + assert!(wrong_value.as_date().is_err()); + assert!(wrong_value.as_datetime().is_err()); + assert!(wrong_value.as_list().is_err()); + } + + #[test] + fn test_display() { + // assert_eq!(Value::Null.to_string(), "Null"); + assert_eq!(Value::UInt8(8).to_string(), "8"); + assert_eq!(Value::UInt16(16).to_string(), "16"); + assert_eq!(Value::UInt32(32).to_string(), "32"); + assert_eq!(Value::UInt64(64).to_string(), "64"); + assert_eq!(Value::Int8(-8).to_string(), "-8"); + assert_eq!(Value::Int16(-16).to_string(), "-16"); + assert_eq!(Value::Int32(-32).to_string(), "-32"); + assert_eq!(Value::Int64(-64).to_string(), "-64"); + assert_eq!(Value::Float32((-32.123).into()).to_string(), "-32.123"); + assert_eq!(Value::Float64((-64.123).into()).to_string(), "-64.123"); + assert_eq!(Value::Float64(OrderedF64::infinity()).to_string(), "inf"); + assert_eq!(Value::Float64(OrderedF64::nan()).to_string(), "NaN"); + assert_eq!(Value::String(StringBytes::from("123")).to_string(), "123"); + assert_eq!( + Value::Binary(Bytes::from(vec![1, 2, 3])).to_string(), + "010203" + ); + assert_eq!(Value::Date(Date::new(0)).to_string(), "1970-01-01"); + assert_eq!( + Value::DateTime(DateTime::new(0)).to_string(), + "1970-01-01 00:00:00" + ); + // assert_eq!( + // Value::Timestamp(Timestamp::new(1000, TimeUnit::Millisecond)).to_string(), + // "1970-01-01 00:00:01+0000" + // ); + assert_eq!( + Value::List(ListValue::new( + Some(Box::new(vec![Value::Int8(1), Value::Int8(2)])), + ConcreteDataType::int8_datatype(), + )) + .to_string(), + "Int8[1, 2]" + ); + // assert_eq!( + // Value::List(ListValue::new( + // Some(Box::new(vec![])), + // ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond), + // )) + // .to_string(), + // "Timestamp[]" + // ); + } +} diff --git a/src/datatypes2/src/vectors.rs b/src/datatypes2/src/vectors.rs index d7d08c795d52..05a47caa9853 100644 --- a/src/datatypes2/src/vectors.rs +++ b/src/datatypes2/src/vectors.rs @@ -28,6 +28,7 @@ use crate::vectors::operations::VectorOp; pub mod binary; pub mod boolean; +pub mod date; mod eq; mod helper; pub mod operations; @@ -35,6 +36,7 @@ pub mod primitive; pub use binary::*; pub use boolean::*; +pub use date::*; pub use helper::Helper; pub use primitive::*; diff --git a/src/datatypes2/src/vectors/date.rs b/src/datatypes2/src/vectors/date.rs new file mode 100644 index 000000000000..b610b0caa0dc --- /dev/null +++ b/src/datatypes2/src/vectors/date.rs @@ -0,0 +1,92 @@ +// Copyright 2022 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::types::DateType; +use crate::vectors::{PrimitiveVector, PrimitiveVectorBuilder}; + +// Vector for [`Date`](common_time::Date). +pub type DateVector = PrimitiveVector; +// Builder to build DateVector. +pub type DateVectorBuilder = PrimitiveVectorBuilder; + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use arrow::array::Array; + use common_time::date::Date; + + use super::*; + use crate::data_type::DataType; + use crate::scalars::{ScalarVector, ScalarVectorBuilder}; + use crate::types::DateType; + use crate::value::{Value, ValueRef}; + use crate::vectors::{Vector, VectorRef}; + + #[test] + fn test_build_date_vector() { + let mut builder = DateVectorBuilder::with_capacity(4); + builder.push(Some(Date::new(1))); + builder.push(None); + builder.push(Some(Date::new(-1))); + let vector = builder.finish(); + assert_eq!(3, vector.len()); + assert_eq!(Value::Date(Date::new(1)), vector.get(0)); + assert_eq!(ValueRef::Date(Date::new(1)), vector.get_ref(0)); + assert_eq!(Some(Date::new(1)), vector.get_data(0)); + assert_eq!(None, vector.get_data(1)); + assert_eq!(Value::Null, vector.get(1)); + assert_eq!(ValueRef::Null, vector.get_ref(1)); + assert_eq!(Some(Date::new(-1)), vector.get_data(2)); + let mut iter = vector.iter_data(); + assert_eq!(Some(Date::new(1)), iter.next().unwrap()); + assert_eq!(None, iter.next().unwrap()); + assert_eq!(Some(Date::new(-1)), iter.next().unwrap()); + } + + #[test] + fn test_date_scalar() { + let vector = DateVector::from_slice(&[1, 2]); + assert_eq!(2, vector.len()); + assert_eq!(Some(Date::new(1)), vector.get_data(0)); + assert_eq!(Some(Date::new(2)), vector.get_data(1)); + } + + #[test] + fn test_date_vector_builder() { + let input = DateVector::from_slice(&[1, 2, 3]); + + let mut builder = DateType::default().create_mutable_vector(3); + builder + .push_value_ref(ValueRef::Date(Date::new(5))) + .unwrap(); + assert!(builder.push_value_ref(ValueRef::Int32(123)).is_err()); + builder.extend_slice_of(&input, 1, 2).unwrap(); + assert!(builder + .extend_slice_of(&crate::vectors::Int32Vector::from_slice(&[13]), 0, 1) + .is_err()); + let vector = builder.to_vector(); + + let expect: VectorRef = Arc::new(DateVector::from_slice(&[5, 2, 3])); + assert_eq!(expect, vector); + } + + #[test] + fn test_date_from_arrow() { + let vector = DateVector::from_slice(&[1, 2]); + let arrow = vector.as_arrow().slice(0, vector.len()); + let vector2 = DateVector::try_from_arrow_array(&arrow).unwrap(); + assert_eq!(vector, vector2); + } +} diff --git a/src/datatypes2/src/vectors/eq.rs b/src/datatypes2/src/vectors/eq.rs index 111805fbcabe..fa1f01a099df 100644 --- a/src/datatypes2/src/vectors/eq.rs +++ b/src/datatypes2/src/vectors/eq.rs @@ -15,7 +15,7 @@ use std::sync::Arc; use crate::data_type::DataType; -use crate::vectors::{BinaryVector, BooleanVector, PrimitiveVector, Vector}; +use crate::vectors::{BinaryVector, BooleanVector, DateVector, PrimitiveVector, Vector}; use crate::with_match_primitive_type_id; impl Eq for dyn Vector + '_ {} @@ -72,7 +72,7 @@ fn equal(lhs: &dyn Vector, rhs: &dyn Vector) -> bool { Boolean(_) => is_vector_eq!(BooleanVector, lhs, rhs), Binary(_) => is_vector_eq!(BinaryVector, lhs, rhs), // String(_) => is_vector_eq!(StringVector, lhs, rhs), - // Date(_) => is_vector_eq!(DateVector, lhs, rhs), + Date(_) => is_vector_eq!(DateVector, lhs, rhs), // DateTime(_) => is_vector_eq!(DateTimeVector, lhs, rhs), // Timestamp(_) => is_vector_eq!(TimestampVector, lhs, rhs), // List(_) => is_vector_eq!(ListVector, lhs, rhs), diff --git a/src/datatypes2/src/vectors/operations.rs b/src/datatypes2/src/vectors/operations.rs index eb637d712a54..8f8a497cd885 100644 --- a/src/datatypes2/src/vectors/operations.rs +++ b/src/datatypes2/src/vectors/operations.rs @@ -20,7 +20,6 @@ use common_base::BitVec; use crate::error::Result; use crate::types::LogicalPrimitiveType; -// use crate::types::PrimitiveElement; use crate::vectors::{BinaryVector, BooleanVector, PrimitiveVector, Vector, VectorRef}; /// Vector compute operations. diff --git a/src/datatypes2/src/vectors/operations/filter.rs b/src/datatypes2/src/vectors/operations/filter.rs index 112abc21dae5..588af96d2a47 100644 --- a/src/datatypes2/src/vectors/operations/filter.rs +++ b/src/datatypes2/src/vectors/operations/filter.rs @@ -100,28 +100,28 @@ mod tests { // assert_eq!(expect, out); // } - // macro_rules! impl_filter_date_like_test { - // ($VectorType: ident, $ValueType: ident, $method: ident) => {{ - // use std::sync::Arc; - - // use common_time::$ValueType; - // use $crate::vectors::{$VectorType, VectorRef}; - - // let v = $VectorType::from_iterator((0..5).map($ValueType::$method)); - // let filter = BooleanVector::from_slice(&[false, true, false, true, true]); - // let out = v.filter(&filter).unwrap(); - - // let expect: VectorRef = Arc::new($VectorType::from_iterator( - // [1, 3, 4].into_iter().map($ValueType::$method), - // )); - // assert_eq!(expect, out); - // }}; - // } + macro_rules! impl_filter_date_like_test { + ($VectorType: ident, $ValueType: ident, $method: ident) => {{ + use std::sync::Arc; + + use common_time::$ValueType; + use $crate::vectors::{$VectorType, VectorRef}; + + let v = $VectorType::from_iterator((0..5).map($ValueType::$method)); + let filter = BooleanVector::from_slice(&[false, true, false, true, true]); + let out = v.filter(&filter).unwrap(); + + let expect: VectorRef = Arc::new($VectorType::from_iterator( + [1, 3, 4].into_iter().map($ValueType::$method), + )); + assert_eq!(expect, out); + }}; + } - // #[test] - // fn test_filter_date_like() { - // impl_filter_date_like_test!(DateVector, Date, new); - // impl_filter_date_like_test!(DateTimeVector, DateTime, new); - // impl_filter_date_like_test!(TimestampVector, Timestamp, from_millis); - // } + #[test] + fn test_filter_date_like() { + impl_filter_date_like_test!(DateVector, Date, new); + // impl_filter_date_like_test!(DateTimeVector, DateTime, new); + // impl_filter_date_like_test!(TimestampVector, Timestamp, from_millis); + } } diff --git a/src/datatypes2/src/vectors/operations/find_unique.rs b/src/datatypes2/src/vectors/operations/find_unique.rs index 79a363d3e917..e717cf80bed3 100644 --- a/src/datatypes2/src/vectors/operations/find_unique.rs +++ b/src/datatypes2/src/vectors/operations/find_unique.rs @@ -336,23 +336,23 @@ mod tests { // check_bitmap(&expect, &selected); // } - // macro_rules! impl_find_unique_date_like_test { - // ($VectorType: ident, $ValueType: ident, $method: ident) => {{ - // use common_time::$ValueType; - // use $crate::vectors::$VectorType; - - // let v = $VectorType::from_iterator([8, 8, 9, 10].into_iter().map($ValueType::$method)); - // let mut selected = BitVec::repeat(false, 4); - // v.find_unique(&mut selected, None); - // let expect = vec![true, false, true, true]; - // check_bitmap(&expect, &selected); - // }}; - // } + macro_rules! impl_find_unique_date_like_test { + ($VectorType: ident, $ValueType: ident, $method: ident) => {{ + use common_time::$ValueType; + use $crate::vectors::$VectorType; + + let v = $VectorType::from_iterator([8, 8, 9, 10].into_iter().map($ValueType::$method)); + let mut selected = BitVec::repeat(false, 4); + v.find_unique(&mut selected, None); + let expect = vec![true, false, true, true]; + check_bitmap(&expect, &selected); + }}; + } - // #[test] - // fn test_find_unique_date_like() { - // impl_find_unique_date_like_test!(DateVector, Date, new); - // impl_find_unique_date_like_test!(DateTimeVector, DateTime, new); - // impl_find_unique_date_like_test!(TimestampVector, Timestamp, from_millis); - // } + #[test] + fn test_find_unique_date_like() { + impl_find_unique_date_like_test!(DateVector, Date, new); + // impl_find_unique_date_like_test!(DateTimeVector, DateTime, new); + // impl_find_unique_date_like_test!(TimestampVector, Timestamp, from_millis); + } } diff --git a/src/datatypes2/src/vectors/operations/replicate.rs b/src/datatypes2/src/vectors/operations/replicate.rs index f0c14e241832..81dc4d700371 100644 --- a/src/datatypes2/src/vectors/operations/replicate.rs +++ b/src/datatypes2/src/vectors/operations/replicate.rs @@ -118,30 +118,30 @@ mod tests { // assert_eq!(5, v.len()); // } - // macro_rules! impl_replicate_date_like_test { - // ($VectorType: ident, $ValueType: ident, $method: ident) => {{ - // use common_time::$ValueType; - // use $crate::vectors::$VectorType; - - // let v = $VectorType::from_iterator((0..5).map($ValueType::$method)); - // let offsets = [0, 1, 2, 3, 4]; - - // let v = v.replicate(&offsets); - // assert_eq!(4, v.len()); - - // for i in 0..4 { - // assert_eq!( - // Value::$ValueType($ValueType::$method((i as i32 + 1).into())), - // v.get(i) - // ); - // } - // }}; - // } + macro_rules! impl_replicate_date_like_test { + ($VectorType: ident, $ValueType: ident, $method: ident) => {{ + use common_time::$ValueType; + use $crate::vectors::$VectorType; + + let v = $VectorType::from_iterator((0..5).map($ValueType::$method)); + let offsets = [0, 1, 2, 3, 4]; + + let v = v.replicate(&offsets); + assert_eq!(4, v.len()); + + for i in 0..4 { + assert_eq!( + Value::$ValueType($ValueType::$method((i as i32 + 1).into())), + v.get(i) + ); + } + }}; + } - // #[test] - // fn test_replicate_date_like() { - // impl_replicate_date_like_test!(DateVector, Date, new); - // impl_replicate_date_like_test!(DateTimeVector, DateTime, new); - // impl_replicate_date_like_test!(TimestampVector, Timestamp, from_millis); - // } + #[test] + fn test_replicate_date_like() { + impl_replicate_date_like_test!(DateVector, Date, new); + // impl_replicate_date_like_test!(DateTimeVector, DateTime, new); + // impl_replicate_date_like_test!(TimestampVector, Timestamp, from_millis); + } }