diff --git a/src/datatypes/src/type_id.rs b/src/datatypes/src/type_id.rs index d439366edb..73c676a749 100644 --- a/src/datatypes/src/type_id.rs +++ b/src/datatypes/src/type_id.rs @@ -66,7 +66,7 @@ impl LogicalTypeId { LogicalTypeId::List => { ConcreteDataType::list_datatype(ConcreteDataType::null_datatype()) } - LogicalTypeId::Geometry => todo!(), + LogicalTypeId::Geometry => ConcreteDataType::geometry_datatype(), } } } diff --git a/src/datatypes/src/types/geometry.rs b/src/datatypes/src/types/geometry.rs index 3d45c102a1..bcb41ce55d 100644 --- a/src/datatypes/src/types/geometry.rs +++ b/src/datatypes/src/types/geometry.rs @@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::data_type::DataType; use crate::prelude::{DataTypeRef, LogicalTypeId, Value}; +use crate::value::GeometryValue; +use crate::vectors::geometry::GeometryVectorBuilder; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum GeometryType { @@ -18,14 +20,20 @@ impl DataType for GeometryType { } fn default_value(&self) -> crate::value::Value { - todo!() + match self { + GeometryType::Point => GeometryValue::new_point(0.0, 0.0).to_value(), + } } fn as_arrow_type(&self) -> arrow::datatypes::DataType { - unimplemented!() + unreachable!() } fn create_mutable_vector(&self, capacity: usize) -> Box { - todo!() + match self { + GeometryType::Point => Box::new( + GeometryVectorBuilder::with_capacity_point_vector_builder(capacity), + ), + } } } diff --git a/src/datatypes/src/value.rs b/src/datatypes/src/value.rs index 608bc43994..0c06cc4f07 100644 --- a/src/datatypes/src/value.rs +++ b/src/datatypes/src/value.rs @@ -315,9 +315,19 @@ pub enum GeometryValue { Point(Point), } +impl GeometryValue { + pub fn new_point(x: f64, y: f64) -> Self { + let point = Point::::new(x.into(), y.into()); + GeometryValue::Point(point) + } + pub fn to_value(self) -> Value { + Value::Geometry(self) + } +} + impl Default for GeometryValue { fn default() -> Self { - todo!() + unimplemented!() //lack of type info } } /// Reference to [Value]. diff --git a/src/datatypes/src/vectors.rs b/src/datatypes/src/vectors.rs index 3f7e18baee..b47c510463 100644 --- a/src/datatypes/src/vectors.rs +++ b/src/datatypes/src/vectors.rs @@ -5,7 +5,7 @@ pub mod constant; pub mod date; pub mod datetime; mod eq; -mod geometry; +pub mod geometry; mod helper; mod list; pub mod mutable; @@ -18,10 +18,10 @@ mod timestamp; pub mod all { //! All vector types. pub use crate::vectors::{ - BinaryVector, BooleanVector, ConstantVector, DateTimeVector, DateVector, Float32Vector, - Float64Vector, Int16Vector, Int32Vector, Int64Vector, Int8Vector, ListVector, NullVector, - PrimitiveVector, StringVector, TimestampVector, UInt16Vector, UInt32Vector, UInt64Vector, - UInt8Vector,geometry::GeometryVector + geometry::GeometryVector, BinaryVector, BooleanVector, ConstantVector, DateTimeVector, + DateVector, Float32Vector, Float64Vector, Int16Vector, Int32Vector, Int64Vector, + Int8Vector, ListVector, NullVector, PrimitiveVector, StringVector, TimestampVector, + UInt16Vector, UInt32Vector, UInt64Vector, UInt8Vector, }; } diff --git a/src/datatypes/src/vectors/geometry.rs b/src/datatypes/src/vectors/geometry.rs index 4e10fd0196..181a4e70ce 100644 --- a/src/datatypes/src/vectors/geometry.rs +++ b/src/datatypes/src/vectors/geometry.rs @@ -86,14 +86,9 @@ impl Vector for GeometryVector { } fn get_ref(&self, index: usize) -> crate::value::ValueRef { - match self { - GeometryVector::PointVector(vector) => { - if vector.is_null(index) { - return ValueRef::Null; - } - } + if self.is_null(index) { + return ValueRef::Null; } - ValueRef::Geometry(GeometryValueRef::Indexed { vector: self, idx: index, @@ -140,7 +135,9 @@ impl<'a> Iterator for GeometryVectorIter<'a> { if self.vector.len() <= pos { return None; } - + if self.vector.is_null(pos) { + return Some(None); + } Some(Some(GeometryValueRef::Indexed { vector: self.vector, idx: pos, @@ -152,6 +149,15 @@ pub enum GeometryVectorBuilder { PointVectorBuilder(PointVectorBuilder), } +impl GeometryVectorBuilder { + pub fn new_point_vector_builder() -> Self { + Self::PointVectorBuilder(PointVectorBuilder::new()) + } + pub fn with_capacity_point_vector_builder(capacity: usize) -> Self { + Self::PointVectorBuilder(PointVectorBuilder::with_capacity(capacity)) + } +} + impl MutableVector for GeometryVectorBuilder { fn data_type(&self) -> crate::data_type::ConcreteDataType { ConcreteDataType::geometry_datatype() @@ -239,3 +245,48 @@ impl Serializable for GeometryVector { todo!() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_geometry_vector() { + let mut builder = GeometryVectorBuilder::with_capacity_point_vector_builder(0); + + let value = GeometryValue::new_point(2.0, 1.0); + + builder.push(Some(GeometryValueRef::Ref { val: &value })); + builder.push(None); + assert_eq!(builder.len(), 2); + + let vector = builder.finish(); + assert_eq!(vector.len(), 2); + + assert!(vector.get(1).is_null()); + assert!(vector.get_data(1).is_none()); + + assert_eq!(vector.get(0), value.to_value()); + assert_eq!(vector.get_data(0).unwrap().to_owned_scalar(), value); + + assert_eq!(vector.data_type(), ConcreteDataType::geometry_datatype()); + + let iter = vector.iter_data(); + let mut cnt: usize = 0; + + for i in iter { + assert_eq!(i, vector.get_data(cnt)); + cnt = cnt + 1; + } + assert_eq!(cnt, vector.len()); + + //slice + + //extend_slice_of + + //memory_size + + + + } +} diff --git a/src/datatypes/src/vectors/geometry/point.rs b/src/datatypes/src/vectors/geometry/point.rs index 7fb4e78378..df7847412a 100644 --- a/src/datatypes/src/vectors/geometry/point.rs +++ b/src/datatypes/src/vectors/geometry/point.rs @@ -35,6 +35,9 @@ impl PointVector { } pub fn get(&self, index: usize) -> Value { + if self.array.is_null(index) { + return Value::Null; + } let ref_x_array = self .array .values() @@ -44,14 +47,6 @@ impl PointVector { .downcast_ref::>() .unwrap(); - let validity = ref_x_array.validity(); - - if let Some(bm) = validity { - if !bm.get_bit(index) { - return Value::Null; - } - } - let ref_y_array = self .array .values() @@ -61,13 +56,8 @@ impl PointVector { .downcast_ref::>() .unwrap(); - let (x, y) = (ref_x_array.value(index), ref_x_array.value(index)); - let geo_value = GeometryValue::Point(Point::::new(x.into(), y.into())); - Value::Geometry(geo_value) - } - - pub fn is_null(&self, index: usize) -> bool { - self.get(index).is_null() + let (x, y) = (ref_x_array.value(index), ref_y_array.value(index)); + GeometryValue::new_point(x, y).to_value() } } @@ -78,6 +68,20 @@ pub struct PointVectorBuilder { } impl PointVectorBuilder { + pub fn new() -> Self { + Self { + array_x: Float64Vec::new(), + array_y: Float64Vec::new(), + } + } + + pub fn with_capacity(capacity: usize) -> Self { + Self { + array_x: Float64Vec::with_capacity(capacity), + array_y: Float64Vec::with_capacity(capacity), + } + } + pub fn push(&mut self, value: Option) { match value { Some(val) => match val { @@ -98,9 +102,8 @@ impl PointVectorBuilder { Field::new("x", Float64, true), Field::new("y", Float64, true), ]; - - let array = StructArray::new(DataType::Struct(fields), vec![x, y], None); - //how to get validity of struct? + let validity = x.validity().map(|validity| validity.clone()); + let array = StructArray::new(DataType::Struct(fields), vec![x, y], validity); PointVector { array } }