common_meta/ddl/
create_table_template.rs1use std::collections::HashMap;
16
17use api::v1::region::{CreateRequest, RegionColumnDef};
18use api::v1::{ColumnDef, CreateTableExpr, SemanticType};
19use snafu::OptionExt;
20use store_api::metric_engine_consts::LOGICAL_TABLE_METADATA_KEY;
21use store_api::storage::{RegionId, RegionNumber};
22use table::metadata::TableId;
23
24use crate::error;
25use crate::error::Result;
26use crate::wal_options_allocator::prepare_wal_options;
27
28pub(crate) fn build_template(create_table_expr: &CreateTableExpr) -> Result<CreateRequest> {
29 let column_defs = create_table_expr
30 .column_defs
31 .iter()
32 .enumerate()
33 .map(|(i, c)| {
34 let semantic_type = if create_table_expr.time_index == c.name {
35 SemanticType::Timestamp
36 } else if create_table_expr.primary_keys.contains(&c.name) {
37 SemanticType::Tag
38 } else {
39 SemanticType::Field
40 };
41
42 RegionColumnDef {
43 column_def: Some(ColumnDef {
44 name: c.name.clone(),
45 data_type: c.data_type,
46 is_nullable: c.is_nullable,
47 default_constraint: c.default_constraint.clone(),
48 semantic_type: semantic_type as i32,
49 comment: String::new(),
50 datatype_extension: c.datatype_extension,
51 options: c.options.clone(),
52 }),
53 column_id: i as u32,
54 }
55 })
56 .collect::<Vec<_>>();
57
58 let primary_key = create_table_expr
59 .primary_keys
60 .iter()
61 .map(|key| {
62 column_defs
63 .iter()
64 .find_map(|c| {
65 c.column_def.as_ref().and_then(|x| {
66 if &x.name == key {
67 Some(c.column_id)
68 } else {
69 None
70 }
71 })
72 })
73 .context(error::PrimaryKeyNotFoundSnafu { key })
74 })
75 .collect::<Result<_>>()?;
76
77 let template = CreateRequest {
78 region_id: 0,
79 engine: create_table_expr.engine.to_string(),
80 column_defs,
81 primary_key,
82 path: String::new(),
83 options: create_table_expr.table_options.clone(),
84 };
85
86 Ok(template)
87}
88
89pub struct CreateRequestBuilder {
91 template: CreateRequest,
92 physical_table_id: Option<TableId>,
94}
95
96impl CreateRequestBuilder {
97 pub(crate) fn new(template: CreateRequest, physical_table_id: Option<TableId>) -> Self {
98 Self {
99 template,
100 physical_table_id,
101 }
102 }
103
104 pub fn template(&self) -> &CreateRequest {
105 &self.template
106 }
107
108 pub(crate) fn build_one(
109 &self,
110 region_id: RegionId,
111 storage_path: String,
112 region_wal_options: &HashMap<RegionNumber, String>,
113 ) -> Result<CreateRequest> {
114 let mut request = self.template.clone();
115
116 request.region_id = region_id.as_u64();
117 request.path = storage_path;
118 prepare_wal_options(&mut request.options, region_id, region_wal_options);
120
121 if let Some(physical_table_id) = self.physical_table_id {
122 let physical_region_id = RegionId::new(physical_table_id, region_id.region_number());
126
127 request.options.insert(
128 LOGICAL_TABLE_METADATA_KEY.to_string(),
129 physical_region_id.as_u64().to_string(),
130 );
131 }
132
133 Ok(request)
134 }
135}