ShiKaiWi commented on code in PR #286:
URL: 
https://github.com/apache/incubator-horaedb-meta/pull/286#discussion_r1446940771


##########
server/coordinator/procedure/ddl/createtable/create_table.go:
##########
@@ -34,37 +34,113 @@ import (
 )
 
 const (
-       eventCreateMetadata = "EventCreateMetadata"
-       eventCreateOnShard  = "EventCreateOnShard"
-       eventFinish         = "EventFinish"
-
-       stateBegin          = "StateBegin"
-       stateCreateMetadata = "StateCreateMetadata"
-       stateCreateOnShard  = "StateCreateOnShard"
-       stateFinish         = "StateFinish"
+       eventCheckTableExists  = "EventCheckTableExists"
+       eventCreateTableAssign = "EventCreateTableAssign"
+       eventCreateMetadata    = "EventCreateMetadata"
+       eventCreateOnShard     = "EventCreateOnShard"
+       eventFinish            = "EventFinish"
+
+       stateBegin             = "StateBegin"
+       stateCheckTableExists  = "StateCheckTableExists"
+       stateCreateTableAssign = "StateCreateTableAssign"
+       stateCreateMetadata    = "StateCreateMetadata"
+       stateCreateOnShard     = "StateCreateOnShard"
+       stateFinish            = "StateFinish"
 )
 
 var (
        createTableEvents = fsm.Events{
-               {Name: eventCreateMetadata, Src: []string{stateBegin}, Dst: 
stateCreateMetadata},
+               {Name: eventCheckTableExists, Src: []string{stateBegin}, Dst: 
stateCheckTableExists},
+               {Name: eventCreateTableAssign, Src: 
[]string{stateCheckTableExists}, Dst: stateCreateTableAssign},
+               {Name: eventCreateMetadata, Src: 
[]string{stateCreateTableAssign}, Dst: stateCreateMetadata},
                {Name: eventCreateOnShard, Src: []string{stateCreateMetadata}, 
Dst: stateCreateOnShard},
                {Name: eventFinish, Src: []string{stateCreateOnShard}, Dst: 
stateFinish},
        }
        createTableCallbacks = fsm.Callbacks{
-               eventCreateMetadata: createMetadataCallback,
-               eventCreateOnShard:  createOnShard,
-               eventFinish:         createFinish,
+               eventCheckTableExists:  checkTableExists,
+               eventCreateTableAssign: createTableAssign,
+               eventCreateMetadata:    createMetadata,
+               eventCreateOnShard:     createOnShard,
+               eventFinish:            createFinish,
        }
 )
 
-func createMetadataCallback(event *fsm.Event) {
+func checkTableExists(event *fsm.Event) {
        req, err := procedure.GetRequestFromEvent[*callbackRequest](event)
        if err != nil {
                procedure.CancelEventWithLog(event, err, "get request from 
event")
                return
        }
        params := req.p.params
 
+       // Check whether the table metadata already exists.
+       table, exists, err := 
params.ClusterMetadata.GetTable(params.SourceReq.GetSchemaName(), 
params.SourceReq.GetName())
+       if err != nil {
+               procedure.CancelEventWithLog(event, err, "get table metadata")
+               return
+       }
+       if !exists {
+               return
+       }
+
+       // Check whether the table shard mapping already exists.
+       _, exists = params.ClusterMetadata.GetTableShard(req.ctx, table)
+       if exists {
+               procedure.CancelEventWithLog(event, 
metadata.ErrTableAlreadyExists, "table already exists")
+               return
+       }
+}
+
+func createTableAssign(event *fsm.Event) {
+       req, err := procedure.GetRequestFromEvent[*callbackRequest](event)
+       if err != nil {
+               procedure.CancelEventWithLog(event, err, "get request from 
event")
+               return
+       }
+       params := req.p.params
+
+       schemaName := params.SourceReq.GetSchemaName()
+       tableName := params.SourceReq.GetName()
+
+       targetShardID, exists, err := 
params.ClusterMetadata.GetAssignTable(req.ctx, schemaName, tableName)
+       if err != nil {
+               procedure.CancelEventWithLog(event, err, "get table assign", 
zap.String("schemaName", schemaName), zap.String("tableName", tableName))
+               return
+       }
+       if exists {
+               if targetShardID != params.ShardID {

Review Comment:
   How about picking the shard here? After that, such duplicate codes with the 
ones in `factory.go` can be avoided, and there is no such `ShardNotMatch` error.



##########
server/cluster/metadata/topology_manager.go:
##########
@@ -291,6 +307,64 @@ func (m *TopologyManagerImpl) RemoveTable(ctx 
context.Context, shardID storage.S
        return nil
 }
 
+func (m *TopologyManagerImpl) GetTableShard(_ context.Context, table 
storage.Table) (storage.ShardID, bool) {

Review Comment:
   If the fetched result is shard id, how about renaming it as:
   ```suggestion
   func (m *TopologyManagerImpl) GetTableShardID(_ context.Context, table 
storage.Table) (storage.ShardID, bool) {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to