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