github.com/matrixorigin/matrixone@v1.2.0/pkg/catalog/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 catalog 16 17 import ( 18 "fmt" 19 "regexp" 20 "strconv" 21 22 "github.com/matrixorigin/matrixone/pkg/compress" 23 "github.com/matrixorigin/matrixone/pkg/container/batch" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/container/vector" 26 "github.com/matrixorigin/matrixone/pkg/logutil" 27 "github.com/matrixorigin/matrixone/pkg/pb/api" 28 "github.com/matrixorigin/matrixone/pkg/pb/plan" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine" 30 ) 31 32 const ( 33 CatalogVersion_V1 uint32 = 1 34 35 CatalogVersion_Curr uint32 = CatalogVersion_V1 36 ) 37 38 func init() { 39 MoDatabaseTableDefs = make([]engine.TableDef, len(MoDatabaseSchema)) 40 for i, name := range MoDatabaseSchema { 41 MoDatabaseTableDefs[i] = newAttributeDef(name, MoDatabaseTypes[i], i == 0) 42 } 43 MoTablesTableDefs = make([]engine.TableDef, len(MoTablesSchema)) 44 for i, name := range MoTablesSchema { 45 MoTablesTableDefs[i] = newAttributeDef(name, MoTablesTypes[i], i == 0) 46 } 47 MoColumnsTableDefs = make([]engine.TableDef, len(MoColumnsSchema)) 48 for i, name := range MoColumnsSchema { 49 MoColumnsTableDefs[i] = newAttributeDef(name, MoColumnsTypes[i], i == 0) 50 } 51 MoTableMetaDefs = make([]engine.TableDef, len(MoTableMetaSchema)) 52 for i, name := range MoTableMetaSchema { 53 MoTableMetaDefs[i] = newAttributeDef(name, MoTableMetaTypes[i], i == 0) 54 } 55 56 def := &engine.ConstraintDef{ 57 Cts: []engine.Constraint{ 58 &engine.PrimaryKeyDef{ 59 Pkey: &plan.PrimaryKeyDef{ 60 Cols: []uint64{0}, 61 PkeyColId: 0, 62 PkeyColName: SystemDBAttr_ID, 63 Names: []string{SystemDBAttr_ID}, 64 }, 65 }, 66 }, 67 } 68 MoDatabaseConstraint, _ = def.MarshalBinary() 69 70 def = &engine.ConstraintDef{ 71 Cts: []engine.Constraint{ 72 &engine.PrimaryKeyDef{ 73 Pkey: &plan.PrimaryKeyDef{ 74 Cols: []uint64{0}, 75 PkeyColId: 0, 76 PkeyColName: SystemRelAttr_ID, 77 Names: []string{SystemRelAttr_ID}, 78 }, 79 }, 80 }, 81 } 82 MoTableConstraint, _ = def.MarshalBinary() 83 84 def = &engine.ConstraintDef{ 85 Cts: []engine.Constraint{ 86 &engine.PrimaryKeyDef{ 87 Pkey: &plan.PrimaryKeyDef{ 88 Cols: []uint64{0}, 89 PkeyColId: 0, 90 PkeyColName: SystemColAttr_UniqName, 91 Names: []string{SystemColAttr_UniqName}, 92 }, 93 }, 94 }, 95 } 96 MoColumnConstraint, _ = def.MarshalBinary() 97 } 98 99 func newAttributeDef(name string, typ types.Type, isPrimary bool) engine.TableDef { 100 return &engine.AttributeDef{ 101 Attr: engine.Attribute{ 102 Type: typ, 103 Name: name, 104 Primary: isPrimary, 105 Alg: compress.Lz4, 106 Default: &plan.Default{NullAbility: true}, 107 }, 108 } 109 } 110 111 // consume a set of entries and return a command and the remaining entries 112 func ParseEntryList(es []*api.Entry) (any, []*api.Entry, error) { 113 if len(es) == 0 { 114 return nil, nil, nil 115 } 116 e := es[0] 117 if e.DatabaseId != MO_CATALOG_ID { 118 return e, es[1:], nil 119 } 120 switch e.TableId { 121 case MO_DATABASE_ID: 122 bat, err := batch.ProtoBatchToBatch(e.Bat) 123 if err != nil { 124 return nil, nil, err 125 } 126 if e.EntryType == api.Entry_Insert { 127 return genCreateDatabases(GenRows(bat)), es[1:], nil 128 } 129 return genDropDatabases(GenRows(bat)), es[1:], nil 130 case MO_TABLES_ID: 131 bat, err := batch.ProtoBatchToBatch(e.Bat) 132 if err != nil { 133 return nil, nil, err 134 } 135 if e.EntryType == api.Entry_Delete { 136 return genDropOrTruncateTables(GenRows(bat)), es[1:], nil 137 } else if e.EntryType == api.Entry_Update { 138 return genUpdateConstraint(GenRows(bat)), es[1:], nil 139 } else if e.EntryType == api.Entry_Alter { 140 e, err := genUpdateAltertable(GenRows(bat)) 141 if err != nil { 142 return nil, nil, err 143 } 144 return e, es[1:], nil 145 } 146 cmds := genCreateTables(GenRows(bat)) 147 idx := 0 148 for i := range cmds { 149 // tae's logic 150 if len(cmds[i].Comment) > 0 { 151 cmds[i].Defs = append(cmds[i].Defs, &engine.CommentDef{ 152 Comment: cmds[i].Comment, 153 }) 154 } 155 if len(cmds[i].Viewdef) > 0 { 156 cmds[i].Defs = append(cmds[i].Defs, &engine.ViewDef{ 157 View: cmds[i].Viewdef, 158 }) 159 } 160 if len(cmds[i].Constraint) > 0 { 161 c := new(engine.ConstraintDef) 162 if err = c.UnmarshalBinary(cmds[i].Constraint); err != nil { 163 return nil, nil, err 164 } 165 cmds[i].Defs = append(cmds[i].Defs, c) 166 } 167 if cmds[i].Partitioned > 0 || len(cmds[i].Partition) > 0 { 168 cmds[i].Defs = append(cmds[i].Defs, &engine.PartitionDef{ 169 Partitioned: cmds[i].Partitioned, 170 Partition: cmds[i].Partition, 171 }) 172 } 173 pro := new(engine.PropertiesDef) 174 pro.Properties = append(pro.Properties, engine.Property{ 175 Key: SystemRelAttr_Kind, 176 Value: string(cmds[i].RelKind), 177 }) 178 pro.Properties = append(pro.Properties, engine.Property{ 179 Key: SystemRelAttr_CreateSQL, 180 Value: cmds[i].CreateSql, 181 }) 182 cmds[i].Defs = append(cmds[i].Defs, pro) 183 if err = fillCreateTable(&idx, &cmds[i], es); err != nil { 184 return nil, nil, err 185 } 186 } 187 return cmds, es[idx+1:], nil 188 default: 189 return e, es[1:], nil 190 } 191 } 192 193 func genCreateDatabases(rows [][]any) []CreateDatabase { 194 cmds := make([]CreateDatabase, len(rows)) 195 for i, row := range rows { 196 cmds[i].DatabaseId = row[MO_DATABASE_DAT_ID_IDX].(uint64) 197 cmds[i].Name = string(row[MO_DATABASE_DAT_NAME_IDX].([]byte)) 198 cmds[i].Owner = row[MO_DATABASE_OWNER_IDX].(uint32) 199 cmds[i].Creator = row[MO_DATABASE_CREATOR_IDX].(uint32) 200 cmds[i].AccountId = row[MO_DATABASE_ACCOUNT_ID_IDX].(uint32) 201 cmds[i].CreatedTime = row[MO_DATABASE_CREATED_TIME_IDX].(types.Timestamp) 202 cmds[i].CreateSql = string(row[MO_DATABASE_CREATESQL_IDX].([]byte)) 203 cmds[i].DatTyp = string(row[MO_DATABASE_DAT_TYPE_IDX].([]byte)) 204 } 205 return cmds 206 } 207 208 func genDropDatabases(rows [][]any) []DropDatabase { 209 cmds := make([]DropDatabase, len(rows)) 210 for i, row := range rows { 211 cmds[i].Id = row[SKIP_ROWID_OFFSET+MO_DATABASE_DAT_ID_IDX].(uint64) 212 cmds[i].Name = string(row[SKIP_ROWID_OFFSET+MO_DATABASE_DAT_NAME_IDX].([]byte)) 213 } 214 return cmds 215 } 216 217 func genCreateTables(rows [][]any) []CreateTable { 218 cmds := make([]CreateTable, len(rows)) 219 for i, row := range rows { 220 cmds[i].TableId = row[MO_TABLES_REL_ID_IDX].(uint64) 221 cmds[i].Name = string(row[MO_TABLES_REL_NAME_IDX].([]byte)) 222 cmds[i].CreateSql = string(row[MO_TABLES_REL_CREATESQL_IDX].([]byte)) 223 cmds[i].Owner = row[MO_TABLES_OWNER_IDX].(uint32) 224 cmds[i].Creator = row[MO_TABLES_CREATOR_IDX].(uint32) 225 cmds[i].AccountId = row[MO_TABLES_ACCOUNT_ID_IDX].(uint32) 226 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 227 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 228 cmds[i].Comment = string(row[MO_TABLES_REL_COMMENT_IDX].([]byte)) 229 cmds[i].Partitioned = row[MO_TABLES_PARTITIONED_IDX].(int8) 230 cmds[i].Partition = string(row[MO_TABLES_PARTITION_INFO_IDX].([]byte)) 231 cmds[i].Viewdef = string(row[MO_TABLES_VIEWDEF_IDX].([]byte)) 232 cmds[i].Constraint = row[MO_TABLES_CONSTRAINT_IDX].([]byte) 233 cmds[i].RelKind = string(row[MO_TABLES_RELKIND_IDX].([]byte)) 234 } 235 return cmds 236 } 237 238 func genUpdateConstraint(rows [][]any) []UpdateConstraint { 239 cmds := make([]UpdateConstraint, len(rows)) 240 for i, row := range rows { 241 cmds[i].TableId = row[MO_TABLES_REL_ID_IDX].(uint64) 242 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 243 cmds[i].TableName = string(row[MO_TABLES_REL_NAME_IDX].([]byte)) 244 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 245 cmds[i].Constraint = row[MO_TABLES_UPDATE_CONSTRAINT].([]byte) 246 } 247 return cmds 248 } 249 250 func genUpdateAltertable(rows [][]any) ([]*api.AlterTableReq, error) { 251 cmds := make([]*api.AlterTableReq, len(rows)) 252 for i, row := range rows { 253 req := &api.AlterTableReq{} 254 err := req.Unmarshal(row[MO_TABLES_ALTER_TABLE].([]byte)) 255 if err != nil { 256 return nil, err 257 } 258 cmds[i] = req 259 } 260 return cmds, nil 261 } 262 263 func genDropOrTruncateTables(rows [][]any) []DropOrTruncateTable { 264 cmds := make([]DropOrTruncateTable, len(rows)) 265 for i, row := range rows { 266 name := string(row[SKIP_ROWID_OFFSET+MO_TABLES_REL_NAME_IDX].([]byte)) 267 if id, tblName, ok := isTruncate(name); ok { 268 if id == 0 { 269 logutil.Infof("truncate table %s: %v-%v-%v", name, id, tblName, ok) 270 } 271 cmds[i].Id = id 272 cmds[i].Name = tblName 273 cmds[i].NewId = row[SKIP_ROWID_OFFSET+MO_TABLES_REL_ID_IDX].(uint64) 274 cmds[i].DatabaseId = row[SKIP_ROWID_OFFSET+MO_TABLES_RELDATABASE_ID_IDX].(uint64) 275 cmds[i].DatabaseName = string(row[SKIP_ROWID_OFFSET+MO_TABLES_RELDATABASE_IDX].([]byte)) 276 } else { 277 cmds[i].IsDrop = true 278 cmds[i].Id = row[SKIP_ROWID_OFFSET+MO_TABLES_REL_ID_IDX].(uint64) 279 cmds[i].Name = name 280 cmds[i].DatabaseId = row[SKIP_ROWID_OFFSET+MO_TABLES_RELDATABASE_ID_IDX].(uint64) 281 cmds[i].DatabaseName = string(row[SKIP_ROWID_OFFSET+MO_TABLES_RELDATABASE_IDX].([]byte)) 282 } 283 } 284 return cmds 285 } 286 287 func fillCreateTable(idx *int, cmd *CreateTable, es []*api.Entry) error { 288 for i, e := range es { 289 // to find tabledef, only need to detect the insertion of mo_columns 290 if e.TableId != MO_COLUMNS_ID || e.EntryType != api.Entry_Insert { 291 continue 292 } 293 bat, err := batch.ProtoBatchToBatch(e.Bat) 294 if err != nil { 295 return err 296 } 297 rows := GenRows(bat) 298 for _, row := range rows { 299 if row[MO_COLUMNS_ATT_RELNAME_ID_IDX].(uint64) == cmd.TableId { 300 def, err := genTableDefs(row) 301 if err != nil { 302 return err 303 } 304 cmd.Defs = append(cmd.Defs, def) 305 if i > *idx { 306 *idx = i 307 } 308 } 309 } 310 } 311 return nil 312 } 313 314 func genTableDefs(row []any) (engine.TableDef, error) { 315 var attr engine.Attribute 316 317 attr.Name = string(row[MO_COLUMNS_ATTNAME_IDX].([]byte)) 318 attr.Alg = compress.Lz4 319 if err := types.Decode(row[MO_COLUMNS_ATTTYP_IDX].([]byte), &attr.Type); err != nil { 320 return nil, err 321 } 322 if row[MO_COLUMNS_ATTHASDEF_IDX].(int8) == 1 { 323 attr.Default = new(plan.Default) 324 if err := types.Decode(row[MO_COLUMNS_ATT_DEFAULT_IDX].([]byte), attr.Default); err != nil { 325 return nil, err 326 } 327 } 328 if row[MO_COLUMNS_ATT_HAS_UPDATE_IDX].(int8) == 1 { 329 attr.OnUpdate = new(plan.OnUpdate) 330 if err := types.Decode(row[MO_COLUMNS_ATT_UPDATE_IDX].([]byte), attr.OnUpdate); err != nil { 331 return nil, err 332 } 333 } 334 attr.Comment = string(row[MO_COLUMNS_ATT_COMMENT_IDX].([]byte)) 335 attr.IsHidden = row[MO_COLUMNS_ATT_IS_HIDDEN_IDX].(int8) == 1 336 attr.AutoIncrement = row[MO_COLUMNS_ATT_IS_AUTO_INCREMENT_IDX].(int8) == 1 337 attr.Primary = string(row[MO_COLUMNS_ATT_CONSTRAINT_TYPE_IDX].([]byte)) == "p" 338 attr.ClusterBy = row[MO_COLUMNS_ATT_IS_CLUSTERBY].(int8) == 1 339 attr.EnumVlaues = string(row[MO_COLUMNS_ATT_ENUM_IDX].([]byte)) 340 return &engine.AttributeDef{Attr: attr}, nil 341 } 342 343 func GenRows(bat *batch.Batch) [][]any { 344 rows := make([][]any, bat.RowCount()) 345 for i := 0; i < bat.RowCount(); i++ { 346 rows[i] = make([]any, bat.VectorCount()) 347 } 348 for i := 0; i < bat.VectorCount(); i++ { 349 vec := bat.GetVector(int32(i)) 350 switch vec.GetType().Oid { 351 case types.T_bool: 352 col := vector.MustFixedCol[bool](vec) 353 for j := 0; j < vec.Length(); j++ { 354 rows[j][i] = col[j] 355 } 356 case types.T_bit: 357 col := vector.MustFixedCol[uint64](vec) 358 for j := 0; j < vec.Length(); j++ { 359 rows[j][i] = col[j] 360 } 361 case types.T_int8: 362 col := vector.MustFixedCol[int8](vec) 363 for j := 0; j < vec.Length(); j++ { 364 rows[j][i] = col[j] 365 } 366 case types.T_int16: 367 col := vector.MustFixedCol[int16](vec) 368 for j := 0; j < vec.Length(); j++ { 369 rows[j][i] = col[j] 370 } 371 case types.T_int32: 372 col := vector.MustFixedCol[int32](vec) 373 for j := 0; j < vec.Length(); j++ { 374 rows[j][i] = col[j] 375 } 376 case types.T_int64: 377 col := vector.MustFixedCol[int64](vec) 378 for j := 0; j < vec.Length(); j++ { 379 rows[j][i] = col[j] 380 } 381 case types.T_uint8: 382 col := vector.MustFixedCol[uint8](vec) 383 for j := 0; j < vec.Length(); j++ { 384 rows[j][i] = col[j] 385 } 386 case types.T_uint16: 387 col := vector.MustFixedCol[uint16](vec) 388 for j := 0; j < vec.Length(); j++ { 389 rows[j][i] = col[j] 390 } 391 case types.T_uint32: 392 col := vector.MustFixedCol[uint32](vec) 393 for j := 0; j < vec.Length(); j++ { 394 rows[j][i] = col[j] 395 } 396 case types.T_uint64: 397 col := vector.MustFixedCol[uint64](vec) 398 for j := 0; j < vec.Length(); j++ { 399 rows[j][i] = col[j] 400 } 401 case types.T_float32: 402 col := vector.MustFixedCol[float32](vec) 403 for j := 0; j < vec.Length(); j++ { 404 rows[j][i] = col[j] 405 } 406 case types.T_float64: 407 col := vector.MustFixedCol[float64](vec) 408 for j := 0; j < vec.Length(); j++ { 409 rows[j][i] = col[j] 410 } 411 case types.T_date: 412 col := vector.MustFixedCol[types.Date](vec) 413 for j := 0; j < vec.Length(); j++ { 414 rows[j][i] = col[j] 415 } 416 case types.T_time: 417 col := vector.MustFixedCol[types.Time](vec) 418 for j := 0; j < vec.Length(); j++ { 419 rows[j][i] = col[j] 420 } 421 case types.T_datetime: 422 col := vector.MustFixedCol[types.Datetime](vec) 423 for j := 0; j < vec.Length(); j++ { 424 rows[j][i] = col[j] 425 } 426 case types.T_timestamp: 427 col := vector.MustFixedCol[types.Timestamp](vec) 428 for j := 0; j < vec.Length(); j++ { 429 rows[j][i] = col[j] 430 } 431 case types.T_enum: 432 col := vector.MustFixedCol[types.Enum](vec) 433 for j := 0; j < vec.Length(); j++ { 434 rows[j][i] = col[j] 435 } 436 case types.T_decimal64: 437 col := vector.MustFixedCol[types.Decimal64](vec) 438 for j := 0; j < vec.Length(); j++ { 439 rows[j][i] = col[j] 440 } 441 case types.T_decimal128: 442 col := vector.MustFixedCol[types.Decimal128](vec) 443 for j := 0; j < vec.Length(); j++ { 444 rows[j][i] = col[j] 445 } 446 case types.T_uuid: 447 col := vector.MustFixedCol[types.Uuid](vec) 448 for j := 0; j < vec.Length(); j++ { 449 rows[j][i] = col[j] 450 } 451 case types.T_TS: 452 col := vector.MustFixedCol[types.TS](vec) 453 for j := 0; j < vec.Length(); j++ { 454 rows[j][i] = col[j] 455 } 456 case types.T_Rowid: 457 col := vector.MustFixedCol[types.Rowid](vec) 458 for j := 0; j < vec.Length(); j++ { 459 rows[j][i] = col[j] 460 } 461 case types.T_Blockid: 462 col := vector.MustFixedCol[types.Blockid](vec) 463 for j := 0; j < vec.Length(); j++ { 464 rows[j][i] = col[j] 465 } 466 case types.T_char, types.T_varchar, types.T_binary, types.T_varbinary, types.T_blob, types.T_json, types.T_text: 467 for j := 0; j < vec.Length(); j++ { 468 rows[j][i] = vec.GetBytesAt(j) 469 } 470 case types.T_array_float32: 471 for j := 0; j < vec.Length(); j++ { 472 rows[j][i] = vector.GetArrayAt[float32](vec, j) 473 } 474 case types.T_array_float64: 475 for j := 0; j < vec.Length(); j++ { 476 rows[j][i] = vector.GetArrayAt[float64](vec, j) 477 } 478 default: 479 panic(fmt.Sprintf("unspported type: %v", vec.GetType())) 480 } 481 } 482 return rows 483 } 484 485 func isTruncate(name string) (uint64, string, bool) { 486 ok, _ := regexp.MatchString(`\_\d+\_meta`, name) 487 if !ok { 488 return 0, "", false 489 } 490 reg, _ := regexp.Compile(`\d+`) 491 str := reg.FindString(name) 492 id, _ := strconv.ParseUint(str, 10, 64) 493 return id, name[len(str)+Meta_Length:], true 494 } 495 496 func BuildQueryResultPath(accountName, statementId string, blockIdx int) string { 497 return fmt.Sprintf(QueryResultPath, accountName, statementId, blockIdx) 498 } 499 500 func BuildQueryResultMetaPath(accountName, statementId string) string { 501 return fmt.Sprintf(QueryResultMetaPath, accountName, statementId) 502 } 503 504 func BuildProfilePath(typ, name string) string { 505 return fmt.Sprintf("%s/%s_%s", ProfileDir, typ, name) 506 }