Skip to main content

datatypes/vectors/
operations.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15mod cast;
16mod filter;
17mod take;
18
19use std::sync::Arc;
20
21use crate::error::{self, Result};
22use crate::types::LogicalPrimitiveType;
23use crate::vectors::{
24    BinaryVector, BooleanVector, ConcreteDataType, Decimal128Vector, ListVector, NullVector,
25    PrimitiveVector, StringVector, UInt32Vector, Vector, VectorRef,
26};
27
28/// Vector compute operations.
29pub trait VectorOp {
30    /// Filters the vector, returns elements matching the `filter` (i.e. where the values are true).
31    ///
32    /// Note that the nulls of `filter` are interpreted as `false` will lead to these elements being masked out.
33    fn filter(&self, filter: &BooleanVector) -> Result<VectorRef>;
34
35    /// Cast vector to the provided data type and return a new vector with type to_type, if possible.
36    ///
37    /// TODO(dennis) describe behaviors in details.
38    fn cast(&self, to_type: &ConcreteDataType) -> Result<VectorRef>;
39
40    /// Take elements from the vector by the given indices.
41    ///
42    /// # Panics
43    /// Panics if an index is out of bounds.
44    fn take(&self, indices: &UInt32Vector) -> Result<VectorRef>;
45}
46
47macro_rules! impl_scalar_vector_op {
48    ($($VectorType: ident),+) => {$(
49        impl VectorOp for $VectorType {
50            fn filter(&self, filter: &BooleanVector) -> Result<VectorRef> {
51                filter::filter_non_constant!(self, $VectorType, filter)
52            }
53
54            fn cast(&self, to_type: &ConcreteDataType) -> Result<VectorRef> {
55                if let Some(vector) = self.as_any().downcast_ref::<BinaryVector>() {
56                    match to_type {
57                        ConcreteDataType::Json(_) => {
58                            let json_vector = vector.convert_binary_to_json()?;
59                            return Ok(Arc::new(json_vector) as VectorRef);
60                        }
61                        ConcreteDataType::Vector(d) => {
62                            let vector = vector.convert_binary_to_vector(d.dim)?;
63                            return Ok(Arc::new(vector) as VectorRef);
64                        }
65                        _ => {}
66                    }
67                }
68                cast::cast_non_constant!(self, to_type)
69            }
70
71            fn take(&self, indices: &UInt32Vector) -> Result<VectorRef> {
72                take::take_indices!(self, $VectorType, indices)
73            }
74        }
75    )+};
76}
77
78impl_scalar_vector_op!(BinaryVector, BooleanVector, StringVector);
79
80impl VectorOp for ListVector {
81    fn filter(&self, filter: &BooleanVector) -> Result<VectorRef> {
82        filter::filter_non_constant!(self, ListVector, filter)
83    }
84
85    fn cast(&self, to_type: &ConcreteDataType) -> Result<VectorRef> {
86        cast::cast_non_constant!(self, to_type)
87    }
88
89    fn take(&self, indices: &UInt32Vector) -> Result<VectorRef> {
90        take::take_indices!(self, ListVector, indices)
91    }
92}
93
94impl VectorOp for Decimal128Vector {
95    fn filter(&self, filter: &BooleanVector) -> Result<VectorRef> {
96        filter::filter_non_constant!(self, Decimal128Vector, filter)
97    }
98
99    fn cast(&self, to_type: &ConcreteDataType) -> Result<VectorRef> {
100        cast::cast_non_constant!(self, to_type)
101    }
102
103    fn take(&self, indices: &UInt32Vector) -> Result<VectorRef> {
104        take::take_indices!(self, Decimal128Vector, indices)
105    }
106}
107
108impl<T: LogicalPrimitiveType> VectorOp for PrimitiveVector<T> {
109    fn filter(&self, filter: &BooleanVector) -> Result<VectorRef> {
110        filter::filter_non_constant!(self, PrimitiveVector<T>, filter)
111    }
112
113    fn cast(&self, to_type: &ConcreteDataType) -> Result<VectorRef> {
114        cast::cast_non_constant!(self, to_type)
115    }
116
117    fn take(&self, indices: &UInt32Vector) -> Result<VectorRef> {
118        take::take_indices!(self, PrimitiveVector<T>, indices)
119    }
120}
121
122impl VectorOp for NullVector {
123    fn filter(&self, filter: &BooleanVector) -> Result<VectorRef> {
124        filter::filter_non_constant!(self, NullVector, filter)
125    }
126    fn cast(&self, _to_type: &ConcreteDataType) -> Result<VectorRef> {
127        // TODO(dennis): impl it when NullVector has other datatype.
128        error::UnsupportedOperationSnafu {
129            op: "cast",
130            vector_type: self.vector_type_name(),
131        }
132        .fail()
133    }
134
135    fn take(&self, indices: &UInt32Vector) -> Result<VectorRef> {
136        take::take_indices!(self, NullVector, indices)
137    }
138}