github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/txn/txnimpl/database.go (about) 1 // Copyright 2021 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package txnimpl 16 17 import ( 18 "sync" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 27 ) 28 29 type txnDBIt struct { 30 *sync.RWMutex 31 txn txnif.AsyncTxn 32 linkIt *common.GenericSortedDListIt[*catalog.DBEntry] 33 itered bool // linkIt has no dummy head, use this to avoid duplicate filter logic for the very first entry 34 curr *catalog.DBEntry 35 err error 36 } 37 38 func newDBIt(txn txnif.AsyncTxn, c *catalog.Catalog) *txnDBIt { 39 it := &txnDBIt{ 40 RWMutex: c.RWMutex, 41 txn: txn, 42 linkIt: c.MakeDBIt(true), 43 } 44 it.Next() 45 return it 46 } 47 48 func (it *txnDBIt) Close() error { return nil } 49 func (it *txnDBIt) GetError() error { return it.err } 50 func (it *txnDBIt) Valid() bool { 51 if it.err != nil { 52 return false 53 } 54 return it.linkIt.Valid() 55 } 56 57 func (it *txnDBIt) Next() { 58 var err error 59 var valid bool 60 for { 61 if it.itered { 62 it.linkIt.Next() 63 } 64 node := it.linkIt.Get() 65 it.itered = true 66 if node == nil { 67 it.curr = nil 68 break 69 } 70 curr := node.GetPayload() 71 curr.RLock() 72 if curr.GetTenantID() == it.txn.GetTenantID() || isSysSharedDB(curr.GetName()) { 73 valid, err = curr.IsVisible(it.txn.GetStartTS(), curr.RWMutex) 74 } 75 curr.RUnlock() 76 if err != nil { 77 it.err = err 78 break 79 } 80 if valid { 81 it.curr = curr 82 break 83 } 84 } 85 } 86 87 func (it *txnDBIt) GetCurr() *catalog.DBEntry { return it.curr } 88 89 type txnDatabase struct { 90 *txnbase.TxnDatabase 91 txnDB *txnDB 92 } 93 94 func newDatabase(db *txnDB) *txnDatabase { 95 dbase := &txnDatabase{ 96 TxnDatabase: &txnbase.TxnDatabase{ 97 Txn: db.store.txn, 98 }, 99 txnDB: db, 100 } 101 return dbase 102 103 } 104 func (db *txnDatabase) GetID() uint64 { return db.txnDB.entry.GetID() } 105 func (db *txnDatabase) GetName() string { return db.txnDB.entry.GetName() } 106 func (db *txnDatabase) String() string { return db.txnDB.entry.String() } 107 108 func (db *txnDatabase) CreateRelation(def any) (rel handle.Relation, err error) { 109 return db.Txn.GetStore().CreateRelation(db.txnDB.entry.ID, def) 110 } 111 112 func (db *txnDatabase) CreateRelationWithID(def any, tableId uint64) (rel handle.Relation, err error) { 113 return db.Txn.GetStore().CreateRelationWithTableId(db.txnDB.entry.ID, tableId, def) 114 } 115 116 func (db *txnDatabase) DropRelationByName(name string) (rel handle.Relation, err error) { 117 return db.Txn.GetStore().DropRelationByName(db.txnDB.entry.ID, name) 118 } 119 120 func (db *txnDatabase) DropRelationByID(id uint64) (rel handle.Relation, err error) { 121 return db.Txn.GetStore().DropRelationByID(db.txnDB.entry.ID, id) 122 } 123 124 func (db *txnDatabase) TruncateByName(name string) (rel handle.Relation, err error) { 125 newTableId := db.txnDB.entry.GetCatalog().IDAlloctor.NextTable() 126 127 oldRel, err := db.DropRelationByName(name) 128 if err != nil { 129 err = moerr.NewInternalErrorNoCtx("%v: truncate %s error", err, name) 130 return 131 } 132 meta := oldRel.GetMeta().(*catalog.TableEntry) 133 schema := meta.GetSchema().Clone() 134 latest := meta.MVCCChain.GetLatestCommittedNode() 135 if latest != nil { 136 schema.Constraint = []byte(latest.(*catalog.TableMVCCNode).SchemaConstraints) 137 } 138 db.Txn.BindAccessInfo(schema.AcInfo.TenantID, schema.AcInfo.UserID, schema.AcInfo.RoleID) 139 rel, err = db.CreateRelationWithID(schema, newTableId) 140 if err != nil { 141 err = moerr.NewInternalErrorNoCtx("%v: truncate %s error", err, name) 142 } 143 return 144 } 145 146 func (db *txnDatabase) TruncateWithID(name string, newTableId uint64) (rel handle.Relation, err error) { 147 148 oldRel, err := db.DropRelationByName(name) 149 if err != nil { 150 err = moerr.NewInternalErrorNoCtx("%v: truncate %s error", err, name) 151 return 152 } 153 meta := oldRel.GetMeta().(*catalog.TableEntry) 154 schema := meta.GetSchema().Clone() 155 latest := meta.MVCCChain.GetLatestCommittedNode() 156 if latest != nil { 157 schema.Constraint = []byte(latest.(*catalog.TableMVCCNode).SchemaConstraints) 158 } 159 db.Txn.BindAccessInfo(schema.AcInfo.TenantID, schema.AcInfo.UserID, schema.AcInfo.RoleID) 160 rel, err = db.CreateRelationWithID(schema, newTableId) 161 if err != nil { 162 err = moerr.NewInternalErrorNoCtx("%v: truncate %s error", err, name) 163 } 164 return 165 } 166 167 func (db *txnDatabase) TruncateByID(id uint64, newTableId uint64) (rel handle.Relation, err error) { 168 169 oldRel, err := db.DropRelationByID(id) 170 if err != nil { 171 err = moerr.NewInternalErrorNoCtx("%v: truncate %d error", err, id) 172 return 173 } 174 meta := oldRel.GetMeta().(*catalog.TableEntry) 175 schema := meta.GetSchema().Clone() 176 latest := meta.MVCCChain.GetLatestCommittedNode() 177 if latest != nil { 178 schema.Constraint = []byte(latest.(*catalog.TableMVCCNode).SchemaConstraints) 179 } 180 db.Txn.BindAccessInfo(schema.AcInfo.TenantID, schema.AcInfo.UserID, schema.AcInfo.RoleID) 181 rel, err = db.CreateRelationWithID(schema, newTableId) 182 if err != nil { 183 err = moerr.NewInternalErrorNoCtx("%v: truncate %d error", err, id) 184 } 185 return 186 } 187 188 func (db *txnDatabase) GetRelationByName(name string) (rel handle.Relation, err error) { 189 return db.Txn.GetStore().GetRelationByName(db.txnDB.entry.ID, name) 190 } 191 192 func (db *txnDatabase) GetRelationByID(id uint64) (rel handle.Relation, err error) { 193 return db.Txn.GetStore().GetRelationByID(db.txnDB.entry.ID, id) 194 } 195 196 func (db *txnDatabase) UnsafeGetRelation(id uint64) (rel handle.Relation, err error) { 197 return db.Txn.GetStore().UnsafeGetRelation(db.txnDB.entry.ID, id) 198 } 199 200 func (db *txnDatabase) MakeRelationIt() (it handle.RelationIt) { 201 return newRelationIt(db.txnDB) 202 } 203 204 func (db *txnDatabase) RelationCnt() int64 { return 0 } 205 func (db *txnDatabase) Relations() (rels []handle.Relation) { return } 206 func (db *txnDatabase) Close() error { return nil } 207 func (db *txnDatabase) GetMeta() any { return db.txnDB.entry }