common_meta/ddl/create_logical_tables/
metadata.rs1use std::collections::HashSet;
16use std::sync::Arc;
17
18use datatypes::prelude::ConcreteDataType;
19use datatypes::schema::{ColumnSchema, Schema};
20use snafu::OptionExt;
21use store_api::metric_engine_consts::is_metric_engine_internal_column;
22
23use crate::ddl::create_logical_tables::CreateLogicalTablesProcedure;
24use crate::error::Result;
25use crate::key::table_route::TableRouteValue;
26
27impl CreateLogicalTablesProcedure {
28 pub(crate) async fn fill_physical_table_info(&mut self) -> Result<()> {
29 let physical_region_numbers = self
30 .context
31 .table_metadata_manager
32 .table_route_manager()
33 .get_physical_table_route(self.data.physical_table_id)
34 .await
35 .map(|(_, route)| TableRouteValue::Physical(route).region_numbers())?;
36
37 self.data.physical_region_numbers = physical_region_numbers;
38
39 let physical_table_info = self
41 .context
42 .table_metadata_manager
43 .table_info_manager()
44 .get(self.data.physical_table_id)
45 .await?
46 .with_context(|| crate::error::TableInfoNotFoundSnafu {
47 table: format!("physical table {}", self.data.physical_table_id),
48 })?;
49
50 let physical_partition_columns: Vec<String> = physical_table_info
51 .table_info
52 .meta
53 .partition_key_indices
54 .iter()
55 .map(|&idx| {
56 physical_table_info.table_info.meta.schema.column_schemas()[idx]
57 .name
58 .clone()
59 })
60 .collect();
61
62 self.data.physical_partition_columns = physical_partition_columns;
63
64 Ok(())
65 }
66
67 pub(crate) fn merge_partition_columns_into_logical_tables(&mut self) -> Result<()> {
68 let partition_columns = &self.data.physical_partition_columns;
69
70 if partition_columns.is_empty() {
72 return Ok(());
73 }
74
75 for task in &mut self.data.tasks {
76 let column_schemas = task.table_info.meta.schema.column_schemas();
78 let existing_column_names: HashSet<_> =
79 column_schemas.iter().map(|c| &c.name).collect();
80
81 let mut new_columns = Vec::new();
82 let mut new_primary_key_indices = task.table_info.meta.primary_key_indices.clone();
83
84 for partition_column in partition_columns {
86 if is_metric_engine_internal_column(partition_column) {
91 continue;
92 }
93
94 if !existing_column_names.contains(partition_column) {
95 let new_column_index = column_schemas.len() + new_columns.len();
96
97 let column_schema = ColumnSchema::new(
99 partition_column.clone(),
100 ConcreteDataType::string_datatype(),
101 true,
102 );
103 new_columns.push(column_schema);
104
105 new_primary_key_indices.push(new_column_index);
107 }
108 }
109
110 if !new_columns.is_empty() {
112 let mut updated_columns = column_schemas.to_vec();
113 updated_columns.extend(new_columns);
114
115 let new_schema = Arc::new(Schema::new(updated_columns));
117
118 task.table_info.meta.schema = new_schema;
120 task.table_info.meta.primary_key_indices = new_primary_key_indices;
121 }
122 }
123
124 Ok(())
125 }
126
127 pub(crate) async fn allocate_table_ids(&mut self) -> Result<()> {
128 for (task, table_id) in self
129 .data
130 .tasks
131 .iter_mut()
132 .zip(self.data.table_ids_already_exists.iter())
133 {
134 let table_id = if let Some(table_id) = table_id {
135 *table_id
136 } else {
137 self.context
138 .table_metadata_allocator
139 .allocate_table_id(&task.create_table.table_id)
140 .await?
141 };
142 task.set_table_id(table_id);
143
144 task.sort_columns();
146 }
147
148 Ok(())
149 }
150}