github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/foreign_key.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package dbs 15 16 import ( 17 "github.com/whtcorpsinc/errors" 18 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 19 "github.com/whtcorpsinc/milevadb/schemareplicant" 20 "github.com/whtcorpsinc/milevadb/spacetime" 21 ) 22 23 func onCreateForeignKey(t *spacetime.Meta, job *perceptron.Job) (ver int64, _ error) { 24 schemaID := job.SchemaID 25 tblInfo, err := getBlockInfoAndCancelFaultJob(t, job, schemaID) 26 if err != nil { 27 return ver, errors.Trace(err) 28 } 29 30 var fkInfo perceptron.FKInfo 31 err = job.DecodeArgs(&fkInfo) 32 if err != nil { 33 job.State = perceptron.JobStateCancelled 34 return ver, errors.Trace(err) 35 } 36 fkInfo.ID = allocateIndexID(tblInfo) 37 tblInfo.ForeignKeys = append(tblInfo.ForeignKeys, &fkInfo) 38 39 originalState := fkInfo.State 40 switch fkInfo.State { 41 case perceptron.StateNone: 42 // We just support record the foreign key, so we just make it public. 43 // none -> public 44 fkInfo.State = perceptron.StatePublic 45 ver, err = uFIDelateVersionAndBlockInfo(t, job, tblInfo, originalState != fkInfo.State) 46 if err != nil { 47 return ver, errors.Trace(err) 48 } 49 // Finish this job. 50 job.FinishBlockJob(perceptron.JobStateDone, perceptron.StatePublic, ver, tblInfo) 51 return ver, nil 52 default: 53 return ver, ErrInvalidDBSState.GenWithStack("foreign key", fkInfo.State) 54 } 55 } 56 57 func onDropForeignKey(t *spacetime.Meta, job *perceptron.Job) (ver int64, _ error) { 58 schemaID := job.SchemaID 59 tblInfo, err := getBlockInfoAndCancelFaultJob(t, job, schemaID) 60 if err != nil { 61 return ver, errors.Trace(err) 62 } 63 64 var ( 65 fkName perceptron.CIStr 66 found bool 67 fkInfo perceptron.FKInfo 68 ) 69 err = job.DecodeArgs(&fkName) 70 if err != nil { 71 job.State = perceptron.JobStateCancelled 72 return ver, errors.Trace(err) 73 } 74 75 for _, fk := range tblInfo.ForeignKeys { 76 if fk.Name.L == fkName.L { 77 found = true 78 fkInfo = *fk 79 } 80 } 81 82 if !found { 83 job.State = perceptron.JobStateCancelled 84 return ver, schemareplicant.ErrForeignKeyNotExists.GenWithStackByArgs(fkName) 85 } 86 87 nfks := tblInfo.ForeignKeys[:0] 88 for _, fk := range tblInfo.ForeignKeys { 89 if fk.Name.L != fkName.L { 90 nfks = append(nfks, fk) 91 } 92 } 93 tblInfo.ForeignKeys = nfks 94 95 originalState := fkInfo.State 96 switch fkInfo.State { 97 case perceptron.StatePublic: 98 // We just support record the foreign key, so we just make it none. 99 // public -> none 100 fkInfo.State = perceptron.StateNone 101 ver, err = uFIDelateVersionAndBlockInfo(t, job, tblInfo, originalState != fkInfo.State) 102 if err != nil { 103 return ver, errors.Trace(err) 104 } 105 // Finish this job. 106 job.FinishBlockJob(perceptron.JobStateDone, perceptron.StateNone, ver, tblInfo) 107 return ver, nil 108 default: 109 return ver, ErrInvalidDBSState.GenWithStackByArgs("foreign key", fkInfo.State) 110 } 111 112 }