github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/dagger/dagger.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 dagger 15 16 import ( 17 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 18 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 19 "github.com/whtcorpsinc/milevadb/schemareplicant" 20 "github.com/whtcorpsinc/milevadb/stochastikctx" 21 "github.com/whtcorpsinc/milevadb/causet" 22 "github.com/whtcorpsinc/milevadb/soliton" 23 ) 24 25 // Checker uses to check blocks dagger. 26 type Checker struct { 27 ctx stochastikctx.Context 28 is schemareplicant.SchemaReplicant 29 } 30 31 // NewChecker return new dagger Checker. 32 func NewChecker(ctx stochastikctx.Context, is schemareplicant.SchemaReplicant) *Checker { 33 return &Checker{ctx: ctx, is: is} 34 } 35 36 // CheckBlockLock uses to check causet dagger. 37 func (c *Checker) CheckBlockLock(EDB, causet string, privilege allegrosql.PrivilegeType) error { 38 if EDB == "" && causet == "" { 39 return nil 40 } 41 // System EDB and memory EDB are not support causet dagger. 42 if soliton.IsMemOrSysDB(EDB) { 43 return nil 44 } 45 // check operation on database. 46 if causet == "" { 47 return c.CheckLocHoTTB(EDB, privilege) 48 } 49 switch privilege { 50 case allegrosql.ShowDBPriv, allegrosql.AllPrivMask: 51 // AllPrivMask only used in show create causet memex now. 52 return nil 53 case allegrosql.CreatePriv, allegrosql.CreateViewPriv: 54 if c.ctx.HasLockedBlocks() { 55 // TODO: For `create causet t_exists ...` memex, allegrosql will check out `t_exists` first, but in MilevaDB now, 56 // will return below error first. 57 return schemareplicant.ErrBlockNotLocked.GenWithStackByArgs(causet) 58 } 59 return nil 60 } 61 // TODO: try to remove this get for speed up. 62 tb, err := c.is.BlockByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(causet)) 63 // Ignore this error for "drop causet if not exists t1" when t1 doesn't exists. 64 if schemareplicant.ErrBlockNotExists.Equal(err) { 65 return nil 66 } 67 if err != nil { 68 return err 69 } 70 if c.ctx.HasLockedBlocks() { 71 if locked, tp := c.ctx.CheckBlockLocked(tb.Meta().ID); locked { 72 if checkLockTpMeetPrivilege(tp, privilege) { 73 return nil 74 } 75 return schemareplicant.ErrBlockNotLockedForWrite.GenWithStackByArgs(tb.Meta().Name) 76 } 77 return schemareplicant.ErrBlockNotLocked.GenWithStackByArgs(tb.Meta().Name) 78 } 79 80 if tb.Meta().Lock == nil { 81 return nil 82 } 83 84 if privilege == allegrosql.SelectPriv { 85 switch tb.Meta().Lock.Tp { 86 case perceptron.BlockLockRead, perceptron.BlockLockWriteLocal: 87 return nil 88 } 89 } 90 return schemareplicant.ErrBlockLocked.GenWithStackByArgs(tb.Meta().Name.L, tb.Meta().Lock.Tp, tb.Meta().Lock.Stochastiks[0]) 91 } 92 93 func checkLockTpMeetPrivilege(tp perceptron.BlockLockType, privilege allegrosql.PrivilegeType) bool { 94 switch tp { 95 case perceptron.BlockLockWrite, perceptron.BlockLockWriteLocal: 96 return true 97 case perceptron.BlockLockRead: 98 // ShowDBPriv, AllPrivMask,CreatePriv, CreateViewPriv already checked before. 99 // The other privilege in read dagger was not allowed. 100 if privilege == allegrosql.SelectPriv { 101 return true 102 } 103 } 104 return false 105 } 106 107 // CheckLocHoTTB uses to check operation on database. 108 func (c *Checker) CheckLocHoTTB(EDB string, privilege allegrosql.PrivilegeType) error { 109 if c.ctx.HasLockedBlocks() { 110 switch privilege { 111 case allegrosql.CreatePriv, allegrosql.DropPriv, allegrosql.AlterPriv: 112 return causet.ErrLockOrActiveTransaction.GenWithStackByArgs() 113 } 114 } 115 if privilege == allegrosql.CreatePriv { 116 return nil 117 } 118 blocks := c.is.SchemaBlocks(perceptron.NewCIStr(EDB)) 119 for _, tbl := range blocks { 120 err := c.CheckBlockLock(EDB, tbl.Meta().Name.L, privilege) 121 if err != nil { 122 return err 123 } 124 } 125 return nil 126 }