tests_fuzz/ir/
insert_expr.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
15use std::fmt::{Debug, Display};
16
17use datatypes::value::Value;
18
19use crate::ir::{Column, Ident};
20
21pub struct InsertIntoExpr {
22    pub table_name: Ident,
23    pub omit_column_list: bool,
24    pub columns: Vec<Column>,
25    pub values_list: Vec<RowValues>,
26}
27
28impl InsertIntoExpr {
29    /// Returns the timestamp column
30    pub fn timestamp_column(&self) -> Option<Column> {
31        self.columns.iter().find(|c| c.is_time_index()).cloned()
32    }
33
34    /// Returns index of the timestamp column
35    pub fn timestamp_column_idx(&self) -> Option<usize> {
36        self.columns
37            .iter()
38            .enumerate()
39            .find_map(|(idx, c)| if c.is_time_index() { Some(idx) } else { None })
40    }
41
42    /// Returns a vector of columns that are primary keys or time indices.
43    pub fn primary_key_columns(&self) -> Vec<Column> {
44        self.columns
45            .iter()
46            .filter(|c| c.is_primary_key() || c.is_time_index())
47            .cloned()
48            .collect::<Vec<_>>()
49    }
50
51    /// Returns the indices of columns that are primary keys or time indices.
52    pub fn primary_key_column_idx(&self) -> Vec<usize> {
53        self.columns
54            .iter()
55            .enumerate()
56            .filter_map(|(i, c)| {
57                if c.is_primary_key() || c.is_time_index() {
58                    Some(i)
59                } else {
60                    None
61                }
62            })
63            .collect::<Vec<_>>()
64    }
65}
66
67pub type RowValues = Vec<RowValue>;
68
69#[derive(PartialEq, PartialOrd, Clone)]
70pub enum RowValue {
71    Value(Value),
72    Default,
73}
74
75impl RowValue {
76    #[allow(clippy::should_implement_trait)]
77    pub fn cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
78        match (self, other) {
79            (RowValue::Value(Value::Null), RowValue::Value(v2)) => v2.partial_cmp(&Value::Null),
80            (RowValue::Value(v1), RowValue::Value(Value::Null)) => Value::Null.partial_cmp(v1),
81            (RowValue::Value(v1), RowValue::Value(v2)) => v1.partial_cmp(v2),
82            _ => panic!("Invalid comparison: {:?} and {:?}", self, other),
83        }
84    }
85}
86
87impl Display for RowValue {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        match self {
90            RowValue::Value(v) => match v {
91                Value::Null => write!(f, "NULL"),
92                v @ (Value::String(_) | Value::Timestamp(_) | Value::Date(_)) => {
93                    write!(f, "'{}'", v)
94                }
95                v => write!(f, "{}", v),
96            },
97            RowValue::Default => write!(f, "DEFAULT"),
98        }
99    }
100}
101
102impl Debug for RowValue {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        match self {
105            RowValue::Value(v) => match v {
106                Value::Null => write!(f, "NULL"),
107                v @ (Value::String(_) | Value::Timestamp(_) | Value::Date(_)) => {
108                    write!(f, "'{}'", v)
109                }
110                v => write!(f, "{}", v),
111            },
112            RowValue::Default => write!(f, "DEFAULT"),
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use common_time::Timestamp;
120    use datatypes::value::Value;
121
122    use crate::ir::insert_expr::RowValue;
123
124    #[test]
125    fn test_value_cmp() {
126        let time_stampe1 =
127            Value::Timestamp(Timestamp::from_str_utc("-39988-01-31 01:21:12.848697+0000").unwrap());
128        let time_stampe2 =
129            Value::Timestamp(Timestamp::from_str_utc("+12970-09-22 08:40:58.392839+0000").unwrap());
130        let v1 = RowValue::Value(time_stampe1);
131        let v2 = RowValue::Value(time_stampe2);
132        assert_eq!(v1.cmp(&v2), Some(std::cmp::Ordering::Less));
133    }
134}