github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/txn/txnimpl/sysblock.go (about) 1 // Copyright 2022 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 "bytes" 19 "fmt" 20 21 "github.com/RoaringBitmap/roaring" 22 pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle" 28 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model" 30 ) 31 32 type txnSysBlock struct { 33 *txnBlock 34 table *txnTable 35 catalog *catalog.Catalog 36 } 37 38 func newSysBlock(table *txnTable, meta *catalog.BlockEntry) *txnSysBlock { 39 blk := &txnSysBlock{ 40 txnBlock: newBlock(table, meta), 41 table: table, 42 catalog: meta.GetSegment().GetTable().GetCatalog(), 43 } 44 return blk 45 } 46 47 func bool2i8(v bool) int8 { 48 if v { 49 return int8(1) 50 } else { 51 return int8(0) 52 } 53 } 54 55 func (blk *txnSysBlock) isSysTable() bool { 56 return isSysTable(blk.table.entry.GetSchema().Name) 57 } 58 59 func (blk *txnSysBlock) GetTotalChanges() int { 60 if blk.isSysTable() { 61 panic("not supported") 62 } 63 return blk.txnBlock.GetTotalChanges() 64 } 65 66 func (blk *txnSysBlock) BatchDedup(pks containers.Vector, invisibility *roaring.Bitmap) (err error) { 67 if blk.isSysTable() { 68 panic("not supported") 69 } 70 return blk.txnBlock.BatchDedup(pks, invisibility) 71 } 72 73 func (blk *txnSysBlock) RangeDelete(start, end uint32, dt handle.DeleteType) (err error) { 74 if blk.isSysTable() { 75 panic("not supported") 76 } 77 return blk.txnBlock.RangeDelete(start, end, dt) 78 } 79 80 func (blk *txnSysBlock) Update(row uint32, col uint16, v any) (err error) { 81 if blk.isSysTable() { 82 panic("not supported") 83 } 84 return blk.txnBlock.Update(row, col, v) 85 } 86 87 func (blk *txnSysBlock) dbRows() int { 88 return blk.catalog.CoarseDBCnt() 89 } 90 91 func (blk *txnSysBlock) tableRows() int { 92 rows := 0 93 fn := func(db *catalog.DBEntry) error { 94 rows += db.CoarseTableCnt() 95 return nil 96 } 97 _ = blk.processDB(fn, true) 98 return rows 99 } 100 101 func (blk *txnSysBlock) processDB(fn func(*catalog.DBEntry) error, ignoreErr bool) (err error) { 102 it := newDBIt(blk.Txn, blk.catalog) 103 for it.linkIt.Valid() { 104 if err = it.GetError(); err != nil && !ignoreErr { 105 break 106 } 107 db := it.GetCurr() 108 if err = fn(db); err != nil && !ignoreErr { 109 break 110 } 111 it.Next() 112 } 113 return 114 } 115 116 func (blk *txnSysBlock) processTable(entry *catalog.DBEntry, fn func(*catalog.TableEntry) error, ignoreErr bool) (err error) { 117 txnDB, err := blk.table.store.getOrSetDB(entry.GetID()) 118 if err != nil { 119 return 120 } 121 it := newRelationIt(txnDB) 122 for it.linkIt.Valid() { 123 if err = it.GetError(); err != nil && !ignoreErr { 124 break 125 } 126 table := it.GetCurr() 127 if err = fn(table); err != nil && !ignoreErr { 128 break 129 } 130 it.Next() 131 } 132 return 133 } 134 135 func (blk *txnSysBlock) columnRows() int { 136 rows := 0 137 fn := func(table *catalog.TableEntry) error { 138 rows += len(table.GetSchema().ColDefs) 139 return nil 140 } 141 dbFn := func(db *catalog.DBEntry) error { 142 _ = blk.processTable(db, fn, true) 143 return nil 144 } 145 _ = blk.processDB(dbFn, true) 146 return rows 147 } 148 149 func (blk *txnSysBlock) Rows() int { 150 if !blk.isSysTable() { 151 return blk.txnBlock.Rows() 152 } 153 if blk.table.GetID() == pkgcatalog.MO_DATABASE_ID { 154 return blk.dbRows() 155 } else if blk.table.GetID() == pkgcatalog.MO_TABLES_ID { 156 return blk.tableRows() 157 } else if blk.table.GetID() == pkgcatalog.MO_COLUMNS_ID { 158 return blk.columnRows() 159 } else { 160 panic("not supported") 161 } 162 } 163 164 func FillColumnRow(table *catalog.TableEntry, attr string, colData containers.Vector) { 165 schema := table.GetSchema() 166 tableID := table.GetID() 167 for i, colDef := range table.GetSchema().ColDefs { 168 switch attr { 169 case pkgcatalog.SystemColAttr_UniqName: 170 colData.Append([]byte(fmt.Sprintf("%d-%s", tableID, colDef.Name))) 171 case pkgcatalog.SystemColAttr_AccID: 172 colData.Append(schema.AcInfo.TenantID) 173 case pkgcatalog.SystemColAttr_Name: 174 colData.Append([]byte(colDef.Name)) 175 case pkgcatalog.SystemColAttr_Num: 176 colData.Append(int32(i + 1)) 177 case pkgcatalog.SystemColAttr_Type: 178 //colData.Append(int32(colDef.Type.Oid)) 179 data, _ := types.Encode(colDef.Type) 180 colData.Append(data) 181 case pkgcatalog.SystemColAttr_DBID: 182 colData.Append(table.GetDB().GetID()) 183 case pkgcatalog.SystemColAttr_DBName: 184 colData.Append([]byte(table.GetDB().GetName())) 185 case pkgcatalog.SystemColAttr_RelID: 186 colData.Append(tableID) 187 case pkgcatalog.SystemColAttr_RelName: 188 colData.Append([]byte(table.GetSchema().Name)) 189 case pkgcatalog.SystemColAttr_ConstraintType: 190 if colDef.Primary { 191 colData.Append([]byte(pkgcatalog.SystemColPKConstraint)) 192 } else { 193 colData.Append([]byte(pkgcatalog.SystemColNoConstraint)) 194 } 195 case pkgcatalog.SystemColAttr_Length: 196 colData.Append(int32(colDef.Type.Width)) 197 case pkgcatalog.SystemColAttr_NullAbility: 198 colData.Append(bool2i8(!colDef.NullAbility)) 199 case pkgcatalog.SystemColAttr_HasExpr: 200 colData.Append(bool2i8(len(colDef.Default) > 0)) // @imlinjunhong says always has Default, expect row_id 201 case pkgcatalog.SystemColAttr_DefaultExpr: 202 colData.Append(colDef.Default) 203 case pkgcatalog.SystemColAttr_IsDropped: 204 colData.Append(int8(0)) 205 case pkgcatalog.SystemColAttr_IsHidden: 206 colData.Append(bool2i8(colDef.Hidden)) 207 case pkgcatalog.SystemColAttr_IsUnsigned: 208 v := int8(0) 209 switch colDef.Type.Oid { 210 case types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64: 211 v = int8(1) 212 } 213 colData.Append(v) 214 case pkgcatalog.SystemColAttr_IsAutoIncrement: 215 colData.Append(bool2i8(colDef.AutoIncrement)) 216 case pkgcatalog.SystemColAttr_Comment: 217 colData.Append([]byte(colDef.Comment)) 218 case pkgcatalog.SystemColAttr_HasUpdate: 219 colData.Append(bool2i8(len(colDef.OnUpdate) > 0)) 220 case pkgcatalog.SystemColAttr_IsClusterBy: 221 colData.Append(bool2i8(colDef.IsClusterBy())) 222 case pkgcatalog.SystemColAttr_Update: 223 colData.Append(colDef.OnUpdate) 224 default: 225 panic("unexpected colname. if add new catalog def, fill it in this switch") 226 } 227 } 228 } 229 func (blk *txnSysBlock) getColumnTableVec(colIdx int) (colData containers.Vector, err error) { 230 col := catalog.SystemColumnSchema.ColDefs[colIdx] 231 colData = containers.MakeVector(col.Type, col.Nullable()) 232 tableFn := func(table *catalog.TableEntry) error { 233 FillColumnRow(table, col.Name, colData) 234 return nil 235 } 236 dbFn := func(db *catalog.DBEntry) error { 237 return blk.processTable(db, tableFn, false) 238 } 239 err = blk.processDB(dbFn, false) 240 if err != nil { 241 return 242 } 243 return 244 } 245 func (blk *txnSysBlock) getColumnTableData(colIdx int) (view *model.ColumnView, err error) { 246 view = model.NewColumnView(blk.Txn.GetStartTS(), colIdx) 247 colData, err := blk.getColumnTableVec(colIdx) 248 view.SetData(colData) 249 return 250 } 251 252 func FillTableRow(table *catalog.TableEntry, attr string, colData containers.Vector, ts types.TS) { 253 schema := table.GetSchema() 254 switch attr { 255 case pkgcatalog.SystemRelAttr_ID: 256 colData.Append(table.GetID()) 257 case pkgcatalog.SystemRelAttr_Name: 258 colData.Append([]byte(schema.Name)) 259 case pkgcatalog.SystemRelAttr_DBName: 260 colData.Append([]byte(table.GetDB().GetName())) 261 case pkgcatalog.SystemRelAttr_DBID: 262 colData.Append(table.GetDB().GetID()) 263 case pkgcatalog.SystemRelAttr_Comment: 264 colData.Append([]byte(table.GetSchema().Comment)) 265 case pkgcatalog.SystemRelAttr_Partition: 266 colData.Append([]byte(table.GetSchema().Partition)) 267 case pkgcatalog.SystemRelAttr_Persistence: 268 colData.Append([]byte(pkgcatalog.SystemPersistRel)) 269 case pkgcatalog.SystemRelAttr_Kind: 270 colData.Append([]byte(table.GetSchema().Relkind)) 271 case pkgcatalog.SystemRelAttr_CreateSQL: 272 colData.Append([]byte(table.GetSchema().Createsql)) 273 case pkgcatalog.SystemRelAttr_ViewDef: 274 colData.Append([]byte(schema.View)) 275 case pkgcatalog.SystemRelAttr_Owner: 276 colData.Append(schema.AcInfo.RoleID) 277 case pkgcatalog.SystemRelAttr_Creator: 278 colData.Append(schema.AcInfo.UserID) 279 case pkgcatalog.SystemRelAttr_CreateAt: 280 colData.Append(schema.AcInfo.CreateAt) 281 case pkgcatalog.SystemRelAttr_AccID: 282 colData.Append(schema.AcInfo.TenantID) 283 case pkgcatalog.SystemRelAttr_Constraint: 284 table.RLock() 285 defer table.RUnlock() 286 if node := table.MVCCChain.GetVisibleNode(ts); node != nil { 287 colData.Append([]byte(node.(*catalog.TableMVCCNode).SchemaConstraints)) 288 } else { 289 colData.Append([]byte("")) 290 } 291 default: 292 panic("unexpected colname. if add new catalog def, fill it in this switch") 293 } 294 } 295 296 func (blk *txnSysBlock) getRelTableVec(ts types.TS, colIdx int) (colData containers.Vector, err error) { 297 colDef := catalog.SystemTableSchema.ColDefs[colIdx] 298 colData = containers.MakeVector(colDef.Type, colDef.Nullable()) 299 tableFn := func(table *catalog.TableEntry) error { 300 FillTableRow(table, colDef.Name, colData, ts) 301 return nil 302 } 303 dbFn := func(db *catalog.DBEntry) error { 304 return blk.processTable(db, tableFn, false) 305 } 306 if err = blk.processDB(dbFn, false); err != nil { 307 return 308 } 309 return 310 } 311 312 func (blk *txnSysBlock) getRelTableData(colIdx int) (view *model.ColumnView, err error) { 313 ts := blk.Txn.GetStartTS() 314 view = model.NewColumnView(ts, colIdx) 315 colData, err := blk.getRelTableVec(ts, colIdx) 316 view.SetData(colData) 317 return 318 } 319 320 func FillDBRow(db *catalog.DBEntry, attr string, colData containers.Vector, _ types.TS) { 321 switch attr { 322 case pkgcatalog.SystemDBAttr_ID: 323 colData.Append(db.GetID()) 324 case pkgcatalog.SystemDBAttr_Name: 325 colData.Append([]byte(db.GetName())) 326 case pkgcatalog.SystemDBAttr_CatalogName: 327 colData.Append([]byte(pkgcatalog.SystemCatalogName)) 328 case pkgcatalog.SystemDBAttr_CreateSQL: 329 colData.Append([]byte(db.GetCreateSql())) 330 case pkgcatalog.SystemDBAttr_Owner: 331 colData.Append(db.GetRoleID()) 332 case pkgcatalog.SystemDBAttr_Creator: 333 colData.Append(db.GetUserID()) 334 case pkgcatalog.SystemDBAttr_CreateAt: 335 colData.Append(db.GetCreateAt()) 336 case pkgcatalog.SystemDBAttr_AccID: 337 colData.Append(db.GetTenantID()) 338 default: 339 panic("unexpected colname. if add new catalog def, fill it in this switch") 340 } 341 } 342 func (blk *txnSysBlock) getDBTableVec(colIdx int) (colData containers.Vector, err error) { 343 colDef := catalog.SystemDBSchema.ColDefs[colIdx] 344 colData = containers.MakeVector(colDef.Type, colDef.Nullable()) 345 fn := func(db *catalog.DBEntry) error { 346 FillDBRow(db, colDef.Name, colData, blk.Txn.GetStartTS()) 347 return nil 348 } 349 if err = blk.processDB(fn, false); err != nil { 350 return 351 } 352 return 353 } 354 func (blk *txnSysBlock) getDBTableData(colIdx int) (view *model.ColumnView, err error) { 355 view = model.NewColumnView(blk.Txn.GetStartTS(), colIdx) 356 colData, err := blk.getDBTableVec(colIdx) 357 view.SetData(colData) 358 return 359 } 360 361 func (blk *txnSysBlock) GetColumnDataById(colIdx int, buffer *bytes.Buffer) (view *model.ColumnView, err error) { 362 if !blk.isSysTable() { 363 return blk.txnBlock.GetColumnDataById(colIdx, buffer) 364 } 365 if blk.table.GetID() == pkgcatalog.MO_DATABASE_ID { 366 return blk.getDBTableData(colIdx) 367 } else if blk.table.GetID() == pkgcatalog.MO_TABLES_ID { 368 return blk.getRelTableData(colIdx) 369 } else if blk.table.GetID() == pkgcatalog.MO_COLUMNS_ID { 370 return blk.getColumnTableData(colIdx) 371 } else { 372 panic("not supported") 373 } 374 } 375 376 func (blk *txnSysBlock) GetColumnDataByName(attr string, buffer *bytes.Buffer) (view *model.ColumnView, err error) { 377 colIdx := blk.entry.GetSchema().GetColIdx(attr) 378 return blk.GetColumnDataById(colIdx, buffer) 379 } 380 381 func (blk *txnSysBlock) GetColumnDataByNames(attrs []string, buffers []*bytes.Buffer) (view *model.BlockView, err error) { 382 if !blk.isSysTable() { 383 return blk.txnBlock.GetColumnDataByNames(attrs, buffers) 384 } 385 view = model.NewBlockView(blk.Txn.GetStartTS()) 386 ts := blk.Txn.GetStartTS() 387 switch blk.table.GetID() { 388 case pkgcatalog.MO_DATABASE_ID: 389 for _, attr := range attrs { 390 colIdx := blk.entry.GetSchema().GetColIdx(attr) 391 vec, err := blk.getDBTableVec(colIdx) 392 view.SetData(colIdx, vec) 393 if err != nil { 394 return view, err 395 } 396 } 397 case pkgcatalog.MO_TABLES_ID: 398 for _, attr := range attrs { 399 colIdx := blk.entry.GetSchema().GetColIdx(attr) 400 vec, err := blk.getRelTableVec(ts, colIdx) 401 view.SetData(colIdx, vec) 402 if err != nil { 403 return view, err 404 } 405 } 406 case pkgcatalog.MO_COLUMNS_ID: 407 for _, attr := range attrs { 408 colIdx := blk.entry.GetSchema().GetColIdx(attr) 409 vec, err := blk.getColumnTableVec(colIdx) 410 view.SetData(colIdx, vec) 411 if err != nil { 412 return view, err 413 } 414 } 415 default: 416 panic("not supported") 417 } 418 return 419 } 420 421 func (blk *txnSysBlock) LogTxnEntry(entry txnif.TxnEntry, readed []*common.ID) (err error) { 422 if !blk.isSysTable() { 423 return blk.txnBlock.LogTxnEntry(entry, readed) 424 } 425 panic("not supported") 426 }