@@ -16,8 +16,9 @@ use api::v1::region::region_request::Body as PbRegionRequest;
1616use api:: v1:: region:: {
1717 CreateRequest as PbCreateRegionRequest , RegionColumnDef , RegionRequest , RegionRequestHeader ,
1818} ;
19- use api:: v1:: { ColumnDef , SemanticType } ;
19+ use api:: v1:: { ColumnDef , CreateTableExpr , SemanticType } ;
2020use async_trait:: async_trait;
21+ use common_catalog:: consts:: METRIC_ENGINE ;
2122use common_error:: ext:: BoxedError ;
2223use common_procedure:: error:: {
2324 ExternalSnafu , FromJsonSnafu , Result as ProcedureResult , ToJsonSnafu ,
@@ -28,14 +29,15 @@ use common_telemetry::tracing_context::TracingContext;
2829use futures:: future:: join_all;
2930use serde:: { Deserialize , Serialize } ;
3031use snafu:: { ensure, OptionExt , ResultExt } ;
32+ use store_api:: metric_engine_consts:: LOGICAL_TABLE_METADATA_KEY ;
3133use store_api:: storage:: RegionId ;
3234use strum:: AsRefStr ;
3335use table:: engine:: TableReference ;
3436use table:: metadata:: { RawTableInfo , TableId } ;
3537
3638use crate :: ddl:: utils:: { handle_operate_region_error, handle_retry_error, region_storage_path} ;
3739use crate :: ddl:: DdlContext ;
38- use crate :: error:: { self , Result } ;
40+ use crate :: error:: { self , Result , TableInfoNotFoundSnafu } ;
3941use crate :: key:: table_name:: TableNameKey ;
4042use crate :: metrics;
4143use crate :: region_keeper:: OperatingRegionGuard ;
@@ -122,7 +124,7 @@ impl CreateTableProcedure {
122124 Ok ( Status :: executing ( true ) )
123125 }
124126
125- pub fn create_region_request_template ( & self ) -> Result < PbCreateRegionRequest > {
127+ pub fn new_region_request_builder ( & self ) -> Result < CreateRequestBuilder > {
126128 let create_table_expr = & self . creator . data . task . create_table ;
127129
128130 let column_defs = create_table_expr
@@ -172,14 +174,17 @@ impl CreateTableProcedure {
172174 } )
173175 . collect :: < Result < _ > > ( ) ?;
174176
175- Ok ( PbCreateRegionRequest {
177+ let template = PbCreateRegionRequest {
176178 region_id : 0 ,
177179 engine : create_table_expr. engine . to_string ( ) ,
178180 column_defs,
179181 primary_key,
180182 path : String :: new ( ) ,
181183 options : create_table_expr. table_options . clone ( ) ,
182- } )
184+ } ;
185+
186+ let builder = CreateRequestBuilder :: new_template ( self . context . clone ( ) , template) ;
187+ Ok ( builder)
183188 }
184189
185190 pub async fn on_datanode_create_regions ( & mut self ) -> Result < Status > {
@@ -194,7 +199,7 @@ impl CreateTableProcedure {
194199 let schema = & create_table_expr. schema_name ;
195200 let storage_path = region_storage_path ( catalog, schema) ;
196201
197- let request_template = self . create_region_request_template ( ) ?;
202+ let mut request_builder = self . new_region_request_builder ( ) ?;
198203
199204 let leaders = find_leaders ( region_routes) ;
200205 let mut create_region_tasks = Vec :: with_capacity ( leaders. len ( ) ) ;
@@ -203,17 +208,20 @@ impl CreateTableProcedure {
203208 let requester = self . context . datanode_manager . datanode ( & datanode) . await ;
204209
205210 let regions = find_leader_regions ( region_routes, & datanode) ;
206- let requests = regions
207- . iter ( )
208- . map ( |region_number| {
209- let region_id = RegionId :: new ( self . table_id ( ) , * region_number) ;
210-
211- let mut create_region_request = request_template. clone ( ) ;
212- create_region_request. region_id = region_id. as_u64 ( ) ;
213- create_region_request. path = storage_path. clone ( ) ;
214- PbRegionRequest :: Create ( create_region_request)
215- } )
216- . collect :: < Vec < _ > > ( ) ;
211+ let mut requests = Vec :: with_capacity ( regions. len ( ) ) ;
212+ for region_number in regions {
213+ let region_id = RegionId :: new ( self . table_id ( ) , region_number) ;
214+
215+ let create_region_request = request_builder
216+ . build_one (
217+ & self . creator . data . task . create_table ,
218+ region_id,
219+ storage_path. clone ( ) ,
220+ )
221+ . await ?;
222+
223+ requests. push ( PbRegionRequest :: Create ( create_region_request) ) ;
224+ }
217225
218226 for request in requests {
219227 let request = RegionRequest {
@@ -371,3 +379,82 @@ impl CreateTableData {
371379 self . task . table_ref ( )
372380 }
373381}
382+
383+ /// Builder for [PbCreateRegionRequest].
384+ pub struct CreateRequestBuilder {
385+ context : DdlContext ,
386+ template : PbCreateRegionRequest ,
387+ /// Optional. Only for metric engine.
388+ physical_table_id : Option < TableId > ,
389+ }
390+
391+ impl CreateRequestBuilder {
392+ fn new_template ( context : DdlContext , template : PbCreateRegionRequest ) -> Self {
393+ Self {
394+ context,
395+ template,
396+ physical_table_id : None ,
397+ }
398+ }
399+
400+ pub fn template ( & self ) -> & PbCreateRegionRequest {
401+ & self . template
402+ }
403+
404+ async fn build_one (
405+ & mut self ,
406+ create_expr : & CreateTableExpr ,
407+ region_id : RegionId ,
408+ storage_path : String ,
409+ ) -> Result < PbCreateRegionRequest > {
410+ let mut request = self . template . clone ( ) ;
411+
412+ request. region_id = region_id. as_u64 ( ) ;
413+ request. path = storage_path;
414+
415+ if self . template . engine == METRIC_ENGINE {
416+ self . metric_engine_hook ( create_expr, region_id, & mut request)
417+ . await ?;
418+ }
419+
420+ Ok ( request)
421+ }
422+
423+ async fn metric_engine_hook (
424+ & mut self ,
425+ create_expr : & CreateTableExpr ,
426+ region_id : RegionId ,
427+ request : & mut PbCreateRegionRequest ,
428+ ) -> Result < ( ) > {
429+ if let Some ( physical_table_name) = request. options . get ( LOGICAL_TABLE_METADATA_KEY ) {
430+ let table_id = if let Some ( table_id) = self . physical_table_id {
431+ table_id
432+ } else {
433+ let table_name_manager = self . context . table_metadata_manager . table_name_manager ( ) ;
434+ let table_name_key = TableNameKey :: new (
435+ & create_expr. catalog_name ,
436+ & create_expr. schema_name ,
437+ physical_table_name,
438+ ) ;
439+ let table_id = table_name_manager
440+ . get ( table_name_key)
441+ . await ?
442+ . context ( TableInfoNotFoundSnafu {
443+ table_name : physical_table_name,
444+ } ) ?
445+ . table_id ( ) ;
446+ self . physical_table_id = Some ( table_id) ;
447+ table_id
448+ } ;
449+ // Concat physical table's table id and corresponding region number to get
450+ // the physical region id.
451+ let physical_region_id = RegionId :: new ( table_id, region_id. region_number ( ) ) ;
452+ request. options . insert (
453+ LOGICAL_TABLE_METADATA_KEY . to_string ( ) ,
454+ physical_region_id. as_u64 ( ) . to_string ( ) ,
455+ ) ;
456+ }
457+
458+ Ok ( ( ) )
459+ }
460+ }
0 commit comments