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            column_ids: vec![],
136        },
137        table_type: TableType::Base,
138    }
139}
140
141pub fn test_create_table_task(name: &str, table_id: TableId) -> CreateTableTask {
142    let create_table = TestCreateTableExprBuilder::default()
143        .column_defs([
144            TestColumnDefBuilder::default()
145                .name("ts")
146                .data_type(ColumnDataType::TimestampMillisecond)
147                .semantic_type(SemanticType::Timestamp)
148                .build()
149                .unwrap()
150                .into(),
151            TestColumnDefBuilder::default()
152                .name("host")
153                .data_type(ColumnDataType::String)
154                .semantic_type(SemanticType::Tag)
155                .build()
156                .unwrap()
157                .into(),
158            TestColumnDefBuilder::default()
159                .name("cpu")
160                .data_type(ColumnDataType::Float64)
161                .semantic_type(SemanticType::Field)
162                .build()
163                .unwrap()
164                .into(),
165        ])
166        .table_id(table_id)
167        .time_index("ts")
168        .primary_keys(["host".into()])
169        .table_name(name)
170        .engine(MITO_ENGINE)
171        .build()
172        .unwrap()
173        .into();
174    let table_info = build_raw_table_info_from_expr(&create_table);
175    CreateTableTask {
176        create_table,
177        // Single region
178        partitions: vec![Partition {
179            column_list: vec![],
180            value_list: vec![],
181        }],
182        table_info,
183    }
184}