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  }