common_meta/ddl/test_util/
create_table.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::collections::HashMap;
16
17use api::v1::column_def::try_as_column_schema;
18use api::v1::meta::Partition;
19use api::v1::{ColumnDataType, ColumnDef, CreateTableExpr, SemanticType};
20use chrono::DateTime;
21use common_catalog::consts::{
22    DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, MITO2_ENGINE, MITO_ENGINE,
23};
24use datatypes::schema::RawSchema;
25use derive_builder::Builder;
26use store_api::storage::TableId;
27use table::metadata::{RawTableInfo, RawTableMeta, TableIdent, TableType};
28use table::requests::TableOptions;
29
30use crate::ddl::test_util::columns::TestColumnDefBuilder;
31use crate::rpc::ddl::CreateTableTask;
32
33#[derive(Default, Builder)]
34#[builder(default)]
35pub struct TestCreateTableExpr {
36    #[builder(setter(into), default = "DEFAULT_CATALOG_NAME.to_string()")]
37    catalog_name: String,
38    #[builder(setter(into), default = "DEFAULT_SCHEMA_NAME.to_string()")]
39    schema_name: String,
40    #[builder(setter(into))]
41    table_name: String,
42    #[builder(setter(into))]
43    desc: String,
44    #[builder(setter(into))]
45    column_defs: Vec<ColumnDef>,
46    #[builder(setter(into))]
47    time_index: String,
48    #[builder(setter(into))]
49    primary_keys: Vec<String>,
50    create_if_not_exists: bool,
51    table_options: HashMap<String, String>,
52    #[builder(setter(into, strip_option))]
53    table_id: Option<TableId>,
54    #[builder(setter(into), default = "MITO2_ENGINE.to_string()")]
55    engine: String,
56}
57
58impl From<TestCreateTableExpr> for CreateTableExpr {
59    fn from(
60        TestCreateTableExpr {
61            catalog_name,
62            schema_name,
63            table_name,
64            desc,
65            column_defs,
66            time_index,
67            primary_keys,
68            create_if_not_exists,
69            table_options,
70            table_id,
71            engine,
72        }: TestCreateTableExpr,
73    ) -> Self {
74        Self {
75            catalog_name,
76            schema_name,
77            table_name,
78            desc,
79            column_defs,
80            time_index,
81            primary_keys,
82            create_if_not_exists,
83            table_options,
84            table_id: table_id.map(|id| api::v1::TableId { id }),
85            engine,
86        }
87    }
88}
89
90/// Builds [RawTableInfo] from [CreateTableExpr].
91pub fn build_raw_table_info_from_expr(expr: &CreateTableExpr) -> RawTableInfo {
92    RawTableInfo {
93        ident: TableIdent {
94            table_id: expr
95                .table_id
96                .as_ref()
97                .map(|table_id| table_id.id)
98                .unwrap_or(0),
99            version: 1,
100        },
101        name: expr.table_name.to_string(),
102        desc: Some(expr.desc.to_string()),
103        catalog_name: expr.catalog_name.to_string(),
104        schema_name: expr.schema_name.to_string(),
105        meta: RawTableMeta {
106            schema: RawSchema {
107                column_schemas: expr
108                    .column_defs
109                    .iter()
110                    .map(|column| try_as_column_schema(column).unwrap())
111                    .collect(),
112                timestamp_index: expr
113                    .column_defs
114                    .iter()
115                    .position(|column| column.semantic_type() == SemanticType::Timestamp),
116                version: 0,
117            },
118            primary_key_indices: expr
119                .primary_keys
120                .iter()
121                .map(|key| {
122                    expr.column_defs
123                        .iter()
124                        .position(|column| &column.name == key)
125                        .unwrap()
126                })
127                .collect(),
128            value_indices: vec![],
129            engine: expr.engine.to_string(),
130            next_column_id: expr.column_defs.len() as u32,
131            region_numbers: vec![],
132            options: TableOptions::try_from_iter(&expr.table_options).unwrap(),
133            created_on: DateTime::default(),
134            partition_key_indices: vec![],
135        },
136        table_type: TableType::Base,
137    }
138}
139
140pub fn test_create_table_task(name: &str, table_id: TableId) -> CreateTableTask {
141    let create_table = TestCreateTableExprBuilder::default()
142        .column_defs([
143            TestColumnDefBuilder::default()
144                .name("ts")
145                .data_type(ColumnDataType::TimestampMillisecond)
146                .semantic_type(SemanticType::Timestamp)
147                .build()
148                .unwrap()
149                .into(),
150            TestColumnDefBuilder::default()
151                .name("host")
152                .data_type(ColumnDataType::String)
153                .semantic_type(SemanticType::Tag)
154                .build()
155                .unwrap()
156                .into(),
157            TestColumnDefBuilder::default()
158                .name("cpu")
159                .data_type(ColumnDataType::Float64)
160                .semantic_type(SemanticType::Field)
161                .build()
162                .unwrap()
163                .into(),
164        ])
165        .table_id(table_id)
166        .time_index("ts")
167        .primary_keys(["host".into()])
168        .table_name(name)
169        .engine(MITO_ENGINE)
170        .build()
171        .unwrap()
172        .into();
173    let table_info = build_raw_table_info_from_expr(&create_table);
174    CreateTableTask {
175        create_table,
176        // Single region
177        partitions: vec![Partition {
178            column_list: vec![],
179            value_list: vec![],
180        }],
181        table_info,
182    }
183}