github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/disttae/cache/catalog.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 cache 16 17 import ( 18 "fmt" 19 "math" 20 "sort" 21 "sync" 22 23 plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan" 24 "github.com/matrixorigin/matrixone/pkg/sql/util" 25 26 "github.com/matrixorigin/matrixone/pkg/catalog" 27 "github.com/matrixorigin/matrixone/pkg/compress" 28 "github.com/matrixorigin/matrixone/pkg/container/batch" 29 "github.com/matrixorigin/matrixone/pkg/container/types" 30 "github.com/matrixorigin/matrixone/pkg/container/vector" 31 "github.com/matrixorigin/matrixone/pkg/logutil" 32 "github.com/matrixorigin/matrixone/pkg/pb/plan" 33 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 34 "github.com/matrixorigin/matrixone/pkg/vm/engine" 35 "github.com/tidwall/btree" 36 ) 37 38 func NewCatalog() *CatalogCache { 39 return &CatalogCache{ 40 tables: &tableCache{ 41 data: btree.NewBTreeG(tableItemLess), 42 rowidIndex: btree.NewBTreeG(tableItemRowidLess), 43 tableGuard: newTableGuard(), 44 }, 45 databases: &databaseCache{ 46 data: btree.NewBTreeG(databaseItemLess), 47 rowidIndex: btree.NewBTreeG(databaseItemRowidLess), 48 }, 49 mu: struct { 50 sync.Mutex 51 start types.TS 52 end types.TS 53 }{start: types.MaxTs()}, 54 } 55 } 56 57 func (cc *CatalogCache) UpdateDuration(start types.TS, end types.TS) { 58 cc.mu.Lock() 59 defer cc.mu.Unlock() 60 cc.mu.start = start 61 cc.mu.end = end 62 } 63 64 var _ = (&CatalogCache{}).UpdateStart 65 66 func (cc *CatalogCache) UpdateStart(ts types.TS) { 67 cc.mu.Lock() 68 defer cc.mu.Unlock() 69 if cc.mu.start != types.MaxTs() { 70 cc.mu.start = ts 71 } 72 } 73 74 func (cc *CatalogCache) CanServe(ts types.TS) bool { 75 cc.mu.Lock() 76 defer cc.mu.Unlock() 77 return ts.GreaterEq(&cc.mu.start) && ts.LessEq(&cc.mu.end) 78 } 79 80 func (cc *CatalogCache) GC(ts timestamp.Timestamp) { 81 { // table cache gc 82 var items []*TableItem 83 84 cc.tables.data.Scan(func(item *TableItem) bool { 85 if len(items) > GcBuffer { 86 return false 87 } 88 if item.Ts.Less(ts) { 89 items = append(items, item) 90 } 91 return true 92 }) 93 for _, item := range items { 94 cc.tables.data.Delete(item) 95 if !item.deleted { 96 cc.tables.rowidIndex.Delete(item) 97 } 98 } 99 } 100 { // database cache gc 101 var items []*DatabaseItem 102 103 cc.databases.data.Scan(func(item *DatabaseItem) bool { 104 if len(items) > GcBuffer { 105 return false 106 } 107 if item.Ts.Less(ts) { 108 items = append(items, item) 109 } 110 return true 111 }) 112 for _, item := range items { 113 cc.databases.data.Delete(item) 114 if !item.deleted { 115 cc.databases.rowidIndex.Delete(item) 116 } 117 } 118 } 119 } 120 121 type tableIdNameKey struct { 122 id uint64 123 name string 124 } 125 126 func (cc *CatalogCache) Tables(accountId uint32, databaseId uint64, 127 ts timestamp.Timestamp) ([]string, []uint64) { 128 var rs []string 129 var rids []uint64 130 131 key := &TableItem{ 132 AccountId: accountId, 133 DatabaseId: databaseId, 134 } 135 mp := make(map[tableIdNameKey]uint8) 136 cc.tables.data.Ascend(key, func(item *TableItem) bool { 137 if item.AccountId != accountId { 138 return false 139 } 140 if item.DatabaseId != databaseId { 141 return false 142 } 143 // In previous impl table id is used to deduplicate, but this a corner case: rename table t to newt, and rename newt back to t. 144 // In this case newt is first found deleted and taking the place of active t's tableid. 145 // What's more, if a table is truncated, a name can be occuppied by different ids. only use name to to dedup is also inadequate. 146 if item.Ts.Greater(ts) { 147 return true 148 } 149 key := tableIdNameKey{id: item.Id, name: item.Name} 150 if _, ok := mp[key]; !ok { 151 mp[key] = 0 152 if !item.deleted { 153 rs = append(rs, item.Name) 154 rids = append(rids, item.Id) 155 } 156 } 157 return true 158 }) 159 return rs, rids 160 } 161 162 func (cc *CatalogCache) GetTableById(databaseId, tblId uint64) *TableItem { 163 var rel *TableItem 164 165 key := &TableItem{ 166 DatabaseId: databaseId, 167 } 168 // If account is much, the performance is very bad. 169 cc.tables.data.Ascend(key, func(item *TableItem) bool { 170 if item.Id == tblId { 171 rel = item 172 return false 173 } 174 return true 175 }) 176 return rel 177 } 178 179 // GetTableByName returns the table item whose name is tableName in the database. 180 func (cc *CatalogCache) GetTableByName(databaseID uint64, tableName string) *TableItem { 181 var rel *TableItem 182 key := &TableItem{ 183 DatabaseId: databaseID, 184 } 185 cc.tables.data.Ascend(key, func(item *TableItem) bool { 186 if item.Name == tableName { 187 rel = item 188 return false 189 } 190 return true 191 }) 192 return rel 193 } 194 195 func (cc *CatalogCache) Databases(accountId uint32, ts timestamp.Timestamp) []string { 196 var rs []string 197 198 key := &DatabaseItem{ 199 AccountId: accountId, 200 } 201 mp := make(map[string]uint8) 202 cc.databases.data.Ascend(key, func(item *DatabaseItem) bool { 203 if item.AccountId != accountId { 204 return false 205 } 206 if item.Ts.Greater(ts) { 207 return true 208 } 209 if _, ok := mp[item.Name]; !ok { 210 mp[item.Name] = 0 211 if !item.deleted { 212 rs = append(rs, item.Name) 213 } 214 } 215 return true 216 }) 217 return rs 218 } 219 220 func (cc *CatalogCache) GetTable(tbl *TableItem) bool { 221 var find bool 222 var ts timestamp.Timestamp 223 /** 224 In push mode. 225 It is necessary to distinguish the case create table/drop table 226 from truncate table. 227 228 CORNER CASE 1: 229 begin; 230 create table t1(a int);//table id x. catalog.insertTable(table id x) 231 insert into t1 values (1); 232 drop table t1; //same table id x. catalog.deleteTable(table id x) 233 commit; 234 235 CORNER CASE 2: 236 create table t1(a int); //table id x. 237 begin; 238 insert into t1 values (1); 239 -- @session:id=1{ 240 truncate table t1;//insert table id y, then delete table id x. catalog.insertTable(table id y). catalog.deleteTable(table id x) 241 -- @session} 242 commit; 243 244 CORNER CASE 3: 245 create table t1(a int); //table id x. 246 begin; 247 truncate t1;//table id x changed to x1 248 truncate t1;//table id x1 changed to x2 249 truncate t1;//table id x2 changed to x3 250 commit;//catalog.insertTable(table id x1,x2,x3). catalog.deleteTable(table id x,x1,x2) 251 252 To be clear that the TableItem in catalogCache is sorted by the table id. 253 */ 254 var tableId uint64 255 deleted := make(map[uint64]bool) 256 inserted := make(map[uint64]*TableItem) 257 tbl.Id = math.MaxUint64 258 cc.tables.data.Ascend(tbl, func(item *TableItem) bool { 259 if item.deleted && item.AccountId == tbl.AccountId && 260 item.DatabaseId == tbl.DatabaseId && item.Name == tbl.Name { 261 if !ts.IsEmpty() { 262 //if it is the truncate operation, we collect deleteTable together. 263 if item.Ts.Equal(ts) { 264 deleted[item.Id] = true 265 return true 266 } else { 267 return false 268 } 269 } 270 ts = item.Ts 271 tableId = item.Id 272 deleted[item.Id] = true 273 return true 274 } 275 if !item.deleted && item.AccountId == tbl.AccountId && 276 item.DatabaseId == tbl.DatabaseId && item.Name == tbl.Name && 277 (ts.IsEmpty() || ts.Equal(item.Ts) && tableId != item.Id) { 278 //if it is the truncate operation, we collect insertTable together first. 279 if !ts.IsEmpty() && ts.Equal(item.Ts) && tableId != item.Id { 280 inserted[item.Id] = item 281 return true 282 } else { 283 find = true 284 copyTableItem(tbl, item) 285 return false 286 } 287 } 288 if find { 289 return false 290 } 291 return false 292 }) 293 294 if find { 295 return true 296 } 297 298 //handle truncate operation independently 299 //remove deleted item from inserted item 300 for rowid := range deleted { 301 delete(inserted, rowid) 302 } 303 304 //if there is no inserted item, it means that the table is deleted. 305 if len(inserted) == 0 { 306 return false 307 } 308 309 //if there is more than one inserted item, it means that it is wrong 310 if len(inserted) > 1 { 311 panic(fmt.Sprintf("account %d database %d has multiple tables %s", 312 tbl.AccountId, tbl.DatabaseId, tbl.Name)) 313 } 314 315 //get item 316 for _, item := range inserted { 317 copyTableItem(tbl, item) 318 } 319 320 return true 321 } 322 323 func (cc *CatalogCache) GetDatabase(db *DatabaseItem) bool { 324 var find bool 325 var ts timestamp.Timestamp 326 var databaseId uint64 327 328 deleted := make(map[uint64]bool) 329 inserted := make(map[uint64]*DatabaseItem) 330 db.Id = math.MaxUint64 331 332 cc.databases.data.Ascend(db, func(item *DatabaseItem) bool { 333 if item.deleted && item.AccountId == db.AccountId && item.Name == db.Name { 334 if !ts.IsEmpty() { 335 if item.Ts.Equal(ts) { 336 deleted[item.Id] = true 337 return true 338 } else { 339 return false 340 } 341 } 342 ts = item.Ts 343 databaseId = item.Id 344 deleted[item.Id] = true 345 return true 346 } 347 348 if !item.deleted && item.AccountId == db.AccountId && item.Name == db.Name && 349 (ts.IsEmpty() || ts.Equal(item.Ts) && databaseId != item.Id) { 350 if !ts.IsEmpty() && ts.Equal(item.Ts) && databaseId != item.Id { 351 inserted[item.Id] = item 352 return true 353 } else { 354 find = true 355 copyDatabaseItem(db, item) 356 return false 357 } 358 } 359 return false 360 }) 361 362 if find { 363 return true 364 } 365 366 for rowid := range deleted { 367 delete(inserted, rowid) 368 } 369 370 //if there is no inserted item, it means that the database is deleted. 371 if len(inserted) == 0 { 372 return false 373 } 374 375 //if there is more than one inserted item, it means that it is wrong 376 if len(inserted) > 1 { 377 panic(fmt.Sprintf("account %d has multiple database %s", db.AccountId, db.Name)) 378 } 379 380 //get item 381 for _, item := range inserted { 382 copyDatabaseItem(db, item) 383 } 384 return true 385 } 386 387 func (cc *CatalogCache) DeleteTable(bat *batch.Batch) { 388 rowids := vector.MustFixedCol[types.Rowid](bat.GetVector(MO_ROWID_IDX)) 389 timestamps := vector.MustFixedCol[types.TS](bat.GetVector(MO_TIMESTAMP_IDX)) 390 for i, rowid := range rowids { 391 if item, ok := cc.tables.rowidIndex.Get(&TableItem{Rowid: rowid}); ok { 392 newItem := &TableItem{ 393 deleted: true, 394 Id: item.Id, 395 Name: item.Name, 396 Rowid: item.Rowid, 397 AccountId: item.AccountId, 398 DatabaseId: item.DatabaseId, 399 Ts: timestamps[i].ToTimestamp(), 400 } 401 cc.tables.addTableItem(newItem) 402 403 key := TableKey{ 404 AccountId: item.AccountId, 405 DatabaseId: item.DatabaseId, 406 Name: item.Name, 407 } 408 409 oldVersion := cc.tables.tableGuard.getSchemaVersion(key) 410 411 if oldVersion != nil && oldVersion.TableId != item.Id { 412 // drop old table for alter table stmt 413 oldVersion.Version = math.MaxUint32 414 cc.tables.tableGuard.setSchemaVersion(key, oldVersion) 415 } else { 416 // normal drop table stmt 417 cc.tables.tableGuard.setSchemaVersion(key, &TableVersion{ 418 Version: math.MaxUint32, 419 Ts: &item.Ts, 420 }) 421 } 422 } 423 } 424 } 425 426 func (cc *CatalogCache) DeleteDatabase(bat *batch.Batch) { 427 rowids := vector.MustFixedCol[types.Rowid](bat.GetVector(MO_ROWID_IDX)) 428 timestamps := vector.MustFixedCol[types.TS](bat.GetVector(MO_TIMESTAMP_IDX)) 429 for i, rowid := range rowids { 430 if item, ok := cc.databases.rowidIndex.Get(&DatabaseItem{Rowid: rowid}); ok { 431 newItem := &DatabaseItem{ 432 deleted: true, 433 Id: item.Id, 434 Name: item.Name, 435 Rowid: item.Rowid, 436 AccountId: item.AccountId, 437 Typ: item.Typ, 438 CreateSql: item.CreateSql, 439 Ts: timestamps[i].ToTimestamp(), 440 } 441 cc.databases.data.Set(newItem) 442 } 443 } 444 } 445 446 func (cc *CatalogCache) InsertTable(bat *batch.Batch) { 447 rowids := vector.MustFixedCol[types.Rowid](bat.GetVector(MO_ROWID_IDX)) 448 timestamps := vector.MustFixedCol[types.TS](bat.GetVector(MO_TIMESTAMP_IDX)) 449 accounts := vector.MustFixedCol[uint32](bat.GetVector(catalog.MO_TABLES_ACCOUNT_ID_IDX + MO_OFF)) 450 names := bat.GetVector(catalog.MO_TABLES_REL_NAME_IDX + MO_OFF) 451 ids := vector.MustFixedCol[uint64](bat.GetVector(catalog.MO_TABLES_REL_ID_IDX + MO_OFF)) 452 databaseIds := vector.MustFixedCol[uint64](bat.GetVector(catalog.MO_TABLES_RELDATABASE_ID_IDX + MO_OFF)) 453 kinds := bat.GetVector(catalog.MO_TABLES_RELKIND_IDX + MO_OFF) 454 comments := bat.GetVector(catalog.MO_TABLES_REL_COMMENT_IDX + MO_OFF) 455 createSqls := bat.GetVector(catalog.MO_TABLES_REL_CREATESQL_IDX + MO_OFF) 456 viewDefs := bat.GetVector(catalog.MO_TABLES_VIEWDEF_IDX + MO_OFF) 457 partitioneds := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_TABLES_PARTITIONED_IDX + MO_OFF)) 458 paritions := bat.GetVector(catalog.MO_TABLES_PARTITION_INFO_IDX + MO_OFF) 459 constraints := bat.GetVector(catalog.MO_TABLES_CONSTRAINT_IDX + MO_OFF) 460 versions := vector.MustFixedCol[uint32](bat.GetVector(catalog.MO_TABLES_VERSION_IDX + MO_OFF)) 461 catalogVersions := vector.MustFixedCol[uint32](bat.GetVector(catalog.MO_TABLES_CATALOG_VERSION_IDX + MO_OFF)) 462 for i, account := range accounts { 463 item := new(TableItem) 464 item.Id = ids[i] 465 item.Name = names.GetStringAt(i) 466 item.AccountId = account 467 item.DatabaseId = databaseIds[i] 468 item.Ts = timestamps[i].ToTimestamp() 469 item.Kind = kinds.GetStringAt(i) 470 item.ViewDef = viewDefs.GetStringAt(i) 471 item.Constraint = append(item.Constraint, constraints.GetBytesAt(i)...) 472 item.Comment = comments.GetStringAt(i) 473 item.Partitioned = partitioneds[i] 474 item.Partition = paritions.GetStringAt(i) 475 item.CreateSql = createSqls.GetStringAt(i) 476 item.Version = versions[i] 477 item.CatalogVersion = catalogVersions[i] 478 item.PrimaryIdx = -1 479 item.PrimarySeqnum = -1 480 item.ClusterByIdx = -1 481 copy(item.Rowid[:], rowids[i][:]) 482 // invalid old name table 483 exist, ok := cc.tables.rowidIndex.Get(&TableItem{Rowid: rowids[i]}) 484 if ok && exist.Name != item.Name { 485 logutil.Infof("rename invalidate %d-%s,v%d@%s", exist.Id, exist.Name, exist.Version, item.Ts.String()) 486 newItem := &TableItem{ 487 deleted: true, 488 Id: exist.Id, 489 Name: exist.Name, 490 Rowid: exist.Rowid, 491 AccountId: exist.AccountId, 492 DatabaseId: exist.DatabaseId, 493 Version: exist.Version, 494 Ts: item.Ts, 495 } 496 cc.tables.addTableItem(newItem) 497 498 key := TableKey{ 499 AccountId: account, 500 DatabaseId: item.DatabaseId, 501 Name: exist.Name, 502 } 503 cc.tables.tableGuard.setSchemaVersion(key, &TableVersion{ 504 Version: math.MaxUint32, 505 Ts: &item.Ts, 506 TableId: item.Id, 507 }) 508 } 509 510 key := TableKey{ 511 AccountId: account, 512 DatabaseId: item.DatabaseId, 513 Name: item.Name, 514 } 515 516 cc.tables.tableGuard.setSchemaVersion(key, &TableVersion{ 517 Version: item.Version, 518 Ts: &item.Ts, 519 TableId: item.Id, 520 }) 521 cc.tables.addTableItem(item) 522 cc.tables.rowidIndex.Set(item) 523 } 524 } 525 526 func (cc *CatalogCache) InsertColumns(bat *batch.Batch) { 527 var tblKey tableItemKey 528 529 mp := make(map[tableItemKey]columns) // TableItem -> columns 530 key := new(TableItem) 531 rowids := vector.MustFixedCol[types.Rowid](bat.GetVector(MO_ROWID_IDX)) 532 // get table key info 533 timestamps := vector.MustFixedCol[types.TS](bat.GetVector(MO_TIMESTAMP_IDX)) 534 accounts := vector.MustFixedCol[uint32](bat.GetVector(catalog.MO_COLUMNS_ACCOUNT_ID_IDX + MO_OFF)) 535 databaseIds := vector.MustFixedCol[uint64](bat.GetVector(catalog.MO_COLUMNS_ATT_DATABASE_ID_IDX + MO_OFF)) 536 tableNames := bat.GetVector(catalog.MO_COLUMNS_ATT_RELNAME_IDX + MO_OFF) 537 tableIds := vector.MustFixedCol[uint64](bat.GetVector(catalog.MO_COLUMNS_ATT_RELNAME_ID_IDX + MO_OFF)) 538 // get columns info 539 names := bat.GetVector(catalog.MO_COLUMNS_ATTNAME_IDX + MO_OFF) 540 comments := bat.GetVector(catalog.MO_COLUMNS_ATT_COMMENT_IDX + MO_OFF) 541 isHiddens := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_COLUMNS_ATT_IS_HIDDEN_IDX + MO_OFF)) 542 isAutos := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_COLUMNS_ATT_IS_AUTO_INCREMENT_IDX + MO_OFF)) 543 constraintTypes := bat.GetVector(catalog.MO_COLUMNS_ATT_CONSTRAINT_TYPE_IDX + MO_OFF) 544 typs := bat.GetVector(catalog.MO_COLUMNS_ATTTYP_IDX + MO_OFF) 545 hasDefs := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_COLUMNS_ATTHASDEF_IDX + MO_OFF)) 546 defaultExprs := bat.GetVector(catalog.MO_COLUMNS_ATT_DEFAULT_IDX + MO_OFF) 547 hasUpdates := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_COLUMNS_ATT_HAS_UPDATE_IDX + MO_OFF)) 548 updateExprs := bat.GetVector(catalog.MO_COLUMNS_ATT_UPDATE_IDX + MO_OFF) 549 nums := vector.MustFixedCol[int32](bat.GetVector(catalog.MO_COLUMNS_ATTNUM_IDX + MO_OFF)) 550 clusters := vector.MustFixedCol[int8](bat.GetVector(catalog.MO_COLUMNS_ATT_IS_CLUSTERBY + MO_OFF)) 551 seqnums := vector.MustFixedCol[uint16](bat.GetVector(catalog.MO_COLUMNS_ATT_SEQNUM_IDX + MO_OFF)) 552 enumValues := bat.GetVector(catalog.MO_COLUMNS_ATT_ENUM_IDX + MO_OFF) 553 for i, account := range accounts { 554 key.AccountId = account 555 key.Name = tableNames.GetStringAt(i) 556 key.DatabaseId = databaseIds[i] 557 key.Ts = timestamps[i].ToTimestamp() 558 key.Id = tableIds[i] 559 tblKey.Name = key.Name 560 tblKey.AccountId = key.AccountId 561 tblKey.DatabaseId = key.DatabaseId 562 tblKey.NodeId = key.Ts.NodeID 563 tblKey.LogicalTime = key.Ts.LogicalTime 564 tblKey.PhysicalTime = uint64(key.Ts.PhysicalTime) 565 tblKey.Id = tableIds[i] 566 if _, ok := cc.tables.data.Get(key); ok { 567 col := column{ 568 num: nums[i], 569 name: names.GetStringAt(i), 570 comment: comments.GetStringAt(i), 571 isHidden: isHiddens[i], 572 isAutoIncrement: isAutos[i], 573 hasDef: hasDefs[i], 574 hasUpdate: hasUpdates[i], 575 constraintType: constraintTypes.GetStringAt(i), 576 isClusterBy: clusters[i], 577 seqnum: seqnums[i], 578 enumValues: enumValues.GetStringAt(i), 579 } 580 copy(col.rowid[:], rowids[i][:]) 581 col.typ = append(col.typ, typs.GetBytesAt(i)...) 582 col.updateExpr = append(col.updateExpr, updateExprs.GetBytesAt(i)...) 583 col.defaultExpr = append(col.defaultExpr, defaultExprs.GetBytesAt(i)...) 584 mp[tblKey] = append(mp[tblKey], col) 585 } 586 } 587 for k, cols := range mp { 588 sort.Sort(cols) 589 key.Name = k.Name 590 key.AccountId = k.AccountId 591 key.DatabaseId = k.DatabaseId 592 key.Ts = timestamp.Timestamp{ 593 NodeID: k.NodeId, 594 PhysicalTime: int64(k.PhysicalTime), 595 LogicalTime: k.LogicalTime, 596 } 597 key.Id = k.Id 598 item, _ := cc.tables.data.Get(key) 599 defs := make([]engine.TableDef, 0, len(cols)) 600 defs = append(defs, genTableDefOfComment(item.Comment)) 601 item.Rowids = make([]types.Rowid, len(cols)) 602 for i, col := range cols { 603 if col.constraintType == catalog.SystemColPKConstraint { 604 item.PrimaryIdx = i 605 item.PrimarySeqnum = int(col.seqnum) 606 } 607 if col.isClusterBy == 1 { 608 item.ClusterByIdx = i 609 } 610 defs = append(defs, genTableDefOfColumn(col)) 611 copy(item.Rowids[i][:], col.rowid[:]) 612 } 613 item.Defs = defs 614 item.TableDef = getTableDef(item, defs) 615 } 616 } 617 618 func (cc *CatalogCache) InsertDatabase(bat *batch.Batch) { 619 rowids := vector.MustFixedCol[types.Rowid](bat.GetVector(MO_ROWID_IDX)) 620 timestamps := vector.MustFixedCol[types.TS](bat.GetVector(MO_TIMESTAMP_IDX)) 621 accounts := vector.MustFixedCol[uint32](bat.GetVector(catalog.MO_DATABASE_ACCOUNT_ID_IDX + MO_OFF)) 622 names := bat.GetVector(catalog.MO_DATABASE_DAT_NAME_IDX + MO_OFF) 623 ids := vector.MustFixedCol[uint64](bat.GetVector(catalog.MO_DATABASE_DAT_ID_IDX + MO_OFF)) 624 typs := bat.GetVector(catalog.MO_DATABASE_DAT_TYPE_IDX + MO_OFF) 625 createSqls := bat.GetVector(catalog.MO_DATABASE_CREATESQL_IDX + MO_OFF) 626 for i, account := range accounts { 627 item := new(DatabaseItem) 628 item.Id = ids[i] 629 item.Name = names.GetStringAt(i) 630 item.AccountId = account 631 item.Ts = timestamps[i].ToTimestamp() 632 item.Typ = typs.GetStringAt(i) 633 item.CreateSql = createSqls.GetStringAt(i) 634 copy(item.Rowid[:], rowids[i][:]) 635 cc.databases.data.Set(item) 636 cc.databases.rowidIndex.Set(item) 637 } 638 } 639 640 func genTableDefOfComment(comment string) engine.TableDef { 641 return &engine.CommentDef{ 642 Comment: comment, 643 } 644 } 645 646 func genTableDefOfColumn(col column) engine.TableDef { 647 var attr engine.Attribute 648 649 attr.Name = col.name 650 attr.ID = uint64(col.num) 651 attr.Alg = compress.Lz4 652 attr.Comment = col.comment 653 attr.IsHidden = col.isHidden == 1 654 attr.ClusterBy = col.isClusterBy == 1 655 attr.AutoIncrement = col.isAutoIncrement == 1 656 attr.Seqnum = col.seqnum 657 attr.EnumVlaues = col.enumValues 658 if err := types.Decode(col.typ, &attr.Type); err != nil { 659 panic(err) 660 } 661 attr.Default = new(plan.Default) 662 if col.hasDef == 1 { 663 if err := types.Decode(col.defaultExpr, attr.Default); err != nil { 664 panic(err) 665 } 666 } 667 if col.hasUpdate == 1 { 668 attr.OnUpdate = new(plan.OnUpdate) 669 if err := types.Decode(col.updateExpr, attr.OnUpdate); err != nil { 670 panic(err) 671 } 672 } 673 if col.constraintType == catalog.SystemColPKConstraint { 674 attr.Primary = true 675 } 676 return &engine.AttributeDef{Attr: attr} 677 } 678 679 /* 680 // getTableDef only return all cols and their index. 681 func getTableDef(name string, defs []engine.TableDef) *plan.TableDef { 682 var cols []*plan.ColDef 683 684 i := int32(0) 685 name2index := make(map[string]int32) 686 for _, def := range defs { 687 if attr, ok := def.(*engine.AttributeDef); ok { 688 name2index[attr.Attr.Name] = i 689 cols = append(cols, &plan.ColDef{ 690 ColId: attr.Attr.ID, 691 Name: attr.Attr.Name, 692 Typ: &plan.Type{ 693 Id: int32(attr.Attr.Type.Oid), 694 Width: attr.Attr.Type.Width, 695 Scale: attr.Attr.Type.Scale, 696 AutoIncr: attr.Attr.AutoIncrement, 697 Enumvalues: attr.Attr.EnumVlaues, 698 }, 699 Primary: attr.Attr.Primary, 700 Default: attr.Attr.Default, 701 OnUpdate: attr.Attr.OnUpdate, 702 Comment: attr.Attr.Comment, 703 Hidden: attr.Attr.IsHidden, 704 Seqnum: uint32(attr.Attr.Seqnum), 705 }) 706 i++ 707 } 708 } 709 return &plan.TableDef{ 710 Name: name, 711 Cols: cols, 712 Name2ColIndex: name2index, 713 } 714 } 715 */ 716 717 // GetSchemaVersion returns the version of table 718 func (cc *CatalogCache) GetSchemaVersion(name TableKey) *TableVersion { 719 return cc.tables.tableGuard.getSchemaVersion(name) 720 } 721 722 // addTableItem inserts a new table item. 723 func (c *tableCache) addTableItem(item *TableItem) { 724 c.data.Set(item) 725 } 726 727 func getTableDef(tblItem *TableItem, coldefs []engine.TableDef) *plan.TableDef { 728 var clusterByDef *plan.ClusterByDef 729 var cols []*plan.ColDef 730 var defs []*plan.TableDef_DefType 731 var properties []*plan.Property 732 var TableType string 733 var Createsql string 734 var partitionInfo *plan.PartitionByDef 735 var viewSql *plan.ViewDef 736 var foreignKeys []*plan.ForeignKeyDef 737 var primarykey *plan.PrimaryKeyDef 738 var indexes []*plan.IndexDef 739 var refChildTbls []uint64 740 741 i := int32(0) 742 name2index := make(map[string]int32) 743 for _, def := range coldefs { 744 if attr, ok := def.(*engine.AttributeDef); ok { 745 name2index[attr.Attr.Name] = i 746 cols = append(cols, &plan.ColDef{ 747 ColId: attr.Attr.ID, 748 Name: attr.Attr.Name, 749 Typ: plan.Type{ 750 Id: int32(attr.Attr.Type.Oid), 751 Width: attr.Attr.Type.Width, 752 Scale: attr.Attr.Type.Scale, 753 AutoIncr: attr.Attr.AutoIncrement, 754 Table: tblItem.Name, 755 NotNullable: attr.Attr.Default != nil && !attr.Attr.Default.NullAbility, 756 Enumvalues: attr.Attr.EnumVlaues, 757 }, 758 Primary: attr.Attr.Primary, 759 Default: attr.Attr.Default, 760 OnUpdate: attr.Attr.OnUpdate, 761 Comment: attr.Attr.Comment, 762 ClusterBy: attr.Attr.ClusterBy, 763 Hidden: attr.Attr.IsHidden, 764 Seqnum: uint32(attr.Attr.Seqnum), 765 }) 766 if attr.Attr.ClusterBy { 767 clusterByDef = &plan.ClusterByDef{ 768 Name: attr.Attr.Name, 769 } 770 } 771 i++ 772 } 773 } 774 775 if tblItem.Comment != "" { 776 properties = append(properties, &plan.Property{ 777 Key: catalog.SystemRelAttr_Comment, 778 Value: tblItem.Comment, 779 }) 780 } 781 782 if tblItem.Partitioned > 0 { 783 p := &plan.PartitionByDef{} 784 err := p.UnMarshalPartitionInfo(([]byte)(tblItem.Partition)) 785 if err != nil { 786 //panic(fmt.Sprintf("cannot unmarshal partition metadata information: %s", err)) 787 return nil 788 } 789 partitionInfo = p 790 } 791 792 if tblItem.ViewDef != "" { 793 viewSql = &plan.ViewDef{ 794 View: tblItem.ViewDef, 795 } 796 } 797 798 if len(tblItem.Constraint) > 0 { 799 c := &engine.ConstraintDef{} 800 err := c.UnmarshalBinary(tblItem.Constraint) 801 if err != nil { 802 //panic(fmt.Sprintf("cannot unmarshal table constraint information: %s", err)) 803 return nil 804 } 805 for _, ct := range c.Cts { 806 switch k := ct.(type) { 807 case *engine.IndexDef: 808 indexes = k.Indexes 809 case *engine.ForeignKeyDef: 810 foreignKeys = k.Fkeys 811 case *engine.RefChildTableDef: 812 refChildTbls = k.Tables 813 case *engine.PrimaryKeyDef: 814 primarykey = k.Pkey 815 case *engine.StreamConfigsDef: 816 properties = append(properties, k.Configs...) 817 } 818 } 819 } 820 821 properties = append(properties, &plan.Property{ 822 Key: catalog.SystemRelAttr_Kind, 823 Value: tblItem.Kind, 824 }) 825 TableType = tblItem.Kind 826 827 if tblItem.CreateSql != "" { 828 properties = append(properties, &plan.Property{ 829 Key: catalog.SystemRelAttr_CreateSQL, 830 Value: tblItem.CreateSql, 831 }) 832 Createsql = tblItem.CreateSql 833 } 834 835 if len(properties) > 0 { 836 defs = append(defs, &plan.TableDef_DefType{ 837 Def: &plan.TableDef_DefType_Properties{ 838 Properties: &plan.PropertiesDef{ 839 Properties: properties, 840 }, 841 }, 842 }) 843 } 844 845 if primarykey != nil && primarykey.PkeyColName == catalog.CPrimaryKeyColName { 846 primarykey.CompPkeyCol = plan2.GetColDefFromTable(cols, catalog.CPrimaryKeyColName) 847 } 848 if clusterByDef != nil && util.JudgeIsCompositeClusterByColumn(clusterByDef.Name) { 849 clusterByDef.CompCbkeyCol = plan2.GetColDefFromTable(cols, clusterByDef.Name) 850 } 851 852 return &plan.TableDef{ 853 TblId: tblItem.Id, 854 Name: tblItem.Name, 855 Cols: cols, 856 Name2ColIndex: name2index, 857 Defs: defs, 858 TableType: TableType, 859 Createsql: Createsql, 860 Pkey: primarykey, 861 ViewSql: viewSql, 862 Partition: partitionInfo, 863 Fkeys: foreignKeys, 864 RefChildTbls: refChildTbls, 865 ClusterBy: clusterByDef, 866 Indexes: indexes, 867 Version: tblItem.Version, 868 } 869 }