github.com/matrixorigin/matrixone@v0.7.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 "encoding/binary" 19 "fmt" 20 "regexp" 21 "strconv" 22 23 "github.com/matrixorigin/matrixone/pkg/compress" 24 "github.com/matrixorigin/matrixone/pkg/container/batch" 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 "github.com/matrixorigin/matrixone/pkg/container/vector" 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 func init() { 33 MoDatabaseTableDefs = make([]engine.TableDef, len(MoDatabaseSchema)) 34 for i, name := range MoDatabaseSchema { 35 MoDatabaseTableDefs[i] = newAttributeDef(name, MoDatabaseTypes[i], i == 0) 36 } 37 MoTablesTableDefs = make([]engine.TableDef, len(MoTablesSchema)) 38 for i, name := range MoTablesSchema { 39 MoTablesTableDefs[i] = newAttributeDef(name, MoTablesTypes[i], i == 0) 40 } 41 MoColumnsTableDefs = make([]engine.TableDef, len(MoColumnsSchema)) 42 for i, name := range MoColumnsSchema { 43 MoColumnsTableDefs[i] = newAttributeDef(name, MoColumnsTypes[i], i == 0) 44 } 45 MoTableMetaDefs = make([]engine.TableDef, len(MoTableMetaSchema)) 46 for i, name := range MoTableMetaSchema { 47 MoTableMetaDefs[i] = newAttributeDef(name, MoTableMetaTypes[i], i == 0) 48 } 49 } 50 51 func newAttributeDef(name string, typ types.Type, isPrimary bool) engine.TableDef { 52 return &engine.AttributeDef{ 53 Attr: engine.Attribute{ 54 Type: typ, 55 Name: name, 56 Primary: isPrimary, 57 Alg: compress.Lz4, 58 Default: &plan.Default{NullAbility: true}, 59 }, 60 } 61 } 62 63 // consume a set of entries and return a command and the remaining entries 64 func ParseEntryList(es []*api.Entry) (any, []*api.Entry, error) { 65 if len(es) == 0 { 66 return nil, nil, nil 67 } 68 e := es[0] 69 if e.DatabaseId != MO_CATALOG_ID { 70 return e, es[1:], nil 71 } 72 switch e.TableId { 73 case MO_DATABASE_ID: 74 bat, err := batch.ProtoBatchToBatch(e.Bat) 75 if err != nil { 76 return nil, nil, err 77 } 78 if e.EntryType == api.Entry_Insert { 79 return genCreateDatabases(GenRows(bat)), es[1:], nil 80 } 81 return genDropDatabases(GenRows(bat)), es[1:], nil 82 case MO_TABLES_ID: 83 bat, err := batch.ProtoBatchToBatch(e.Bat) 84 if err != nil { 85 return nil, nil, err 86 } 87 if e.EntryType == api.Entry_Delete { 88 return genDropOrTruncateTables(GenRows(bat)), es[1:], nil 89 } else if e.EntryType == api.Entry_Update { 90 return genUpdateConstraint(GenRows(bat)), es[1:], nil 91 } 92 cmds := genCreateTables(GenRows(bat)) 93 idx := 0 94 for i := range cmds { 95 // tae's logic 96 if len(cmds[i].Comment) > 0 { 97 cmds[i].Defs = append(cmds[i].Defs, &engine.CommentDef{ 98 Comment: cmds[i].Comment, 99 }) 100 } 101 if len(cmds[i].Viewdef) > 0 { 102 cmds[i].Defs = append(cmds[i].Defs, &engine.ViewDef{ 103 View: cmds[i].Viewdef, 104 }) 105 } 106 if len(cmds[i].Constraint) > 0 { 107 c := new(engine.ConstraintDef) 108 if err = c.UnmarshalBinary(cmds[i].Constraint); err != nil { 109 return nil, nil, err 110 } 111 cmds[i].Defs = append(cmds[i].Defs, c) 112 } 113 if len(cmds[i].Partition) > 0 { 114 cmds[i].Defs = append(cmds[i].Defs, &engine.PartitionDef{ 115 Partition: cmds[i].Partition, 116 }) 117 } 118 pro := new(engine.PropertiesDef) 119 pro.Properties = append(pro.Properties, engine.Property{ 120 Key: SystemRelAttr_Kind, 121 Value: string(cmds[i].RelKind), 122 }) 123 pro.Properties = append(pro.Properties, engine.Property{ 124 Key: SystemRelAttr_CreateSQL, 125 Value: cmds[i].CreateSql, 126 }) 127 cmds[i].Defs = append(cmds[i].Defs, pro) 128 if err = fillCreateTable(&idx, &cmds[i], es); err != nil { 129 return nil, nil, err 130 } 131 } 132 return cmds, es[idx+1:], nil 133 default: 134 return e, es[1:], nil 135 } 136 } 137 138 func GenBlockInfo(rows [][]any) []BlockInfo { 139 infos := make([]BlockInfo, len(rows)) 140 for i, row := range rows { 141 infos[i].BlockID = row[BLOCKMETA_ID_IDX].(uint64) 142 infos[i].EntryState = row[BLOCKMETA_ENTRYSTATE_IDX].(bool) 143 infos[i].Sorted = row[BLOCKMETA_SORTED_IDX].(bool) 144 infos[i].MetaLoc = string(row[BLOCKMETA_METALOC_IDX].([]byte)) 145 infos[i].DeltaLoc = string(row[BLOCKMETA_DELTALOC_IDX].([]byte)) 146 infos[i].CommitTs = row[BLOCKMETA_COMMITTS_IDX].(types.TS) 147 infos[i].SegmentID = row[BLOCKMETA_SEGID_IDX].(uint64) 148 } 149 return infos 150 } 151 152 func genCreateDatabases(rows [][]any) []CreateDatabase { 153 cmds := make([]CreateDatabase, len(rows)) 154 for i, row := range rows { 155 cmds[i].DatabaseId = row[MO_DATABASE_DAT_ID_IDX].(uint64) 156 cmds[i].Name = string(row[MO_DATABASE_DAT_NAME_IDX].([]byte)) 157 cmds[i].Owner = row[MO_DATABASE_OWNER_IDX].(uint32) 158 cmds[i].Creator = row[MO_DATABASE_CREATOR_IDX].(uint32) 159 cmds[i].AccountId = row[MO_DATABASE_ACCOUNT_ID_IDX].(uint32) 160 cmds[i].CreatedTime = row[MO_DATABASE_CREATED_TIME_IDX].(types.Timestamp) 161 cmds[i].CreateSql = string(row[MO_DATABASE_CREATESQL_IDX].([]byte)) 162 } 163 return cmds 164 } 165 166 func genDropDatabases(rows [][]any) []DropDatabase { 167 cmds := make([]DropDatabase, len(rows)) 168 for i, row := range rows { 169 cmds[i].Id = row[MO_DATABASE_DAT_ID_IDX].(uint64) 170 cmds[i].Name = string(row[MO_DATABASE_DAT_NAME_IDX].([]byte)) 171 } 172 return cmds 173 } 174 175 func genCreateTables(rows [][]any) []CreateTable { 176 cmds := make([]CreateTable, len(rows)) 177 for i, row := range rows { 178 cmds[i].TableId = row[MO_TABLES_REL_ID_IDX].(uint64) 179 cmds[i].Name = string(row[MO_TABLES_REL_NAME_IDX].([]byte)) 180 cmds[i].CreateSql = string(row[MO_TABLES_REL_CREATESQL_IDX].([]byte)) 181 cmds[i].Owner = row[MO_TABLES_OWNER_IDX].(uint32) 182 cmds[i].Creator = row[MO_TABLES_CREATOR_IDX].(uint32) 183 cmds[i].AccountId = row[MO_TABLES_ACCOUNT_ID_IDX].(uint32) 184 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 185 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 186 cmds[i].Comment = string(row[MO_TABLES_REL_COMMENT_IDX].([]byte)) 187 cmds[i].Partition = string(row[MO_TABLES_PARTITIONED_IDX].([]byte)) 188 cmds[i].Viewdef = string(row[MO_TABLES_VIEWDEF_IDX].([]byte)) 189 cmds[i].Constraint = row[MO_TABLES_CONSTRAINT_IDX].([]byte) 190 cmds[i].RelKind = string(row[MO_TABLES_RELKIND_IDX].([]byte)) 191 } 192 return cmds 193 } 194 195 func genUpdateConstraint(rows [][]any) []UpdateConstraint { 196 cmds := make([]UpdateConstraint, len(rows)) 197 for i, row := range rows { 198 cmds[i].TableId = row[MO_TABLES_REL_ID_IDX].(uint64) 199 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 200 cmds[i].TableName = string(row[MO_TABLES_REL_NAME_IDX].([]byte)) 201 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 202 cmds[i].Constraint = row[MO_TABLES_UPDATE_CONSTRAINT].([]byte) 203 } 204 return cmds 205 } 206 207 func genDropOrTruncateTables(rows [][]any) []DropOrTruncateTable { 208 cmds := make([]DropOrTruncateTable, len(rows)) 209 for i, row := range rows { 210 name := string(row[MO_TABLES_REL_NAME_IDX].([]byte)) 211 if id, tblName, ok := isTruncate(name); ok { 212 cmds[i].Id = id 213 cmds[i].Name = tblName 214 cmds[i].NewId = row[MO_TABLES_REL_ID_IDX].(uint64) 215 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 216 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 217 } else { 218 cmds[i].IsDrop = true 219 cmds[i].Id = row[MO_TABLES_REL_ID_IDX].(uint64) 220 cmds[i].Name = name 221 cmds[i].DatabaseId = row[MO_TABLES_RELDATABASE_ID_IDX].(uint64) 222 cmds[i].DatabaseName = string(row[MO_TABLES_RELDATABASE_IDX].([]byte)) 223 } 224 } 225 return cmds 226 } 227 228 func fillCreateTable(idx *int, cmd *CreateTable, es []*api.Entry) error { 229 for i, e := range es { 230 // to find tabledef, only need to detect the insertion of mo_columns 231 if e.TableId != MO_COLUMNS_ID || e.EntryType != api.Entry_Insert { 232 continue 233 } 234 bat, err := batch.ProtoBatchToBatch(e.Bat) 235 if err != nil { 236 return err 237 } 238 rows := GenRows(bat) 239 for _, row := range rows { 240 if row[MO_COLUMNS_ATT_RELNAME_ID_IDX].(uint64) == cmd.TableId { 241 def, err := genTableDefs(row) 242 if err != nil { 243 return err 244 } 245 cmd.Defs = append(cmd.Defs, def) 246 if i > *idx { 247 *idx = i 248 } 249 } 250 } 251 } 252 return nil 253 } 254 255 func genTableDefs(row []any) (engine.TableDef, error) { 256 var attr engine.Attribute 257 258 attr.Name = string(row[MO_COLUMNS_ATTNAME_IDX].([]byte)) 259 attr.Alg = compress.Lz4 260 if err := types.Decode(row[MO_COLUMNS_ATTTYP_IDX].([]byte), &attr.Type); err != nil { 261 return nil, err 262 } 263 if row[MO_COLUMNS_ATTHASDEF_IDX].(int8) == 1 { 264 attr.Default = new(plan.Default) 265 if err := types.Decode(row[MO_COLUMNS_ATT_DEFAULT_IDX].([]byte), attr.Default); err != nil { 266 return nil, err 267 } 268 } 269 if row[MO_COLUMNS_ATT_HAS_UPDATE_IDX].(int8) == 1 { 270 attr.OnUpdate = new(plan.OnUpdate) 271 if err := types.Decode(row[MO_COLUMNS_ATT_UPDATE_IDX].([]byte), attr.OnUpdate); err != nil { 272 return nil, err 273 } 274 } 275 attr.Comment = string(row[MO_COLUMNS_ATT_COMMENT_IDX].([]byte)) 276 attr.IsHidden = row[MO_COLUMNS_ATT_IS_HIDDEN_IDX].(int8) == 1 277 attr.AutoIncrement = row[MO_COLUMNS_ATT_IS_AUTO_INCREMENT_IDX].(int8) == 1 278 attr.Primary = string(row[MO_COLUMNS_ATT_CONSTRAINT_TYPE_IDX].([]byte)) == "p" 279 attr.ClusterBy = row[MO_COLUMNS_ATT_IS_CLUSTERBY].(int8) == 1 280 return &engine.AttributeDef{Attr: attr}, nil 281 } 282 283 func GenRows(bat *batch.Batch) [][]any { 284 rows := make([][]any, bat.Length()) 285 for i := 0; i < bat.Length(); i++ { 286 rows[i] = make([]any, bat.VectorCount()) 287 } 288 for i := 0; i < bat.VectorCount(); i++ { 289 vec := bat.GetVector(int32(i)) 290 switch vec.GetType().Oid { 291 case types.T_bool: 292 col := vector.GetFixedVectorValues[bool](vec) 293 for j := 0; j < vec.Length(); j++ { 294 rows[j][i] = col[j] 295 } 296 case types.T_int8: 297 col := vector.GetFixedVectorValues[int8](vec) 298 for j := 0; j < vec.Length(); j++ { 299 rows[j][i] = col[j] 300 } 301 case types.T_int16: 302 col := vector.GetFixedVectorValues[int16](vec) 303 for j := 0; j < vec.Length(); j++ { 304 rows[j][i] = col[j] 305 } 306 case types.T_int32: 307 col := vector.GetFixedVectorValues[int32](vec) 308 for j := 0; j < vec.Length(); j++ { 309 rows[j][i] = col[j] 310 } 311 case types.T_int64: 312 col := vector.GetFixedVectorValues[int64](vec) 313 for j := 0; j < vec.Length(); j++ { 314 rows[j][i] = col[j] 315 } 316 case types.T_uint8: 317 col := vector.GetFixedVectorValues[uint8](vec) 318 for j := 0; j < vec.Length(); j++ { 319 rows[j][i] = col[j] 320 } 321 case types.T_uint16: 322 col := vector.GetFixedVectorValues[uint16](vec) 323 for j := 0; j < vec.Length(); j++ { 324 rows[j][i] = col[j] 325 } 326 case types.T_uint32: 327 col := vector.GetFixedVectorValues[uint32](vec) 328 for j := 0; j < vec.Length(); j++ { 329 rows[j][i] = col[j] 330 } 331 case types.T_uint64: 332 col := vector.GetFixedVectorValues[uint64](vec) 333 for j := 0; j < vec.Length(); j++ { 334 rows[j][i] = col[j] 335 } 336 case types.T_float32: 337 col := vector.GetFixedVectorValues[float32](vec) 338 for j := 0; j < vec.Length(); j++ { 339 rows[j][i] = col[j] 340 } 341 case types.T_float64: 342 col := vector.GetFixedVectorValues[float64](vec) 343 for j := 0; j < vec.Length(); j++ { 344 rows[j][i] = col[j] 345 } 346 case types.T_date: 347 col := vector.GetFixedVectorValues[types.Date](vec) 348 for j := 0; j < vec.Length(); j++ { 349 rows[j][i] = col[j] 350 } 351 case types.T_time: 352 col := vector.GetFixedVectorValues[types.Time](vec) 353 for j := 0; j < vec.Length(); j++ { 354 rows[j][i] = col[j] 355 } 356 case types.T_datetime: 357 col := vector.GetFixedVectorValues[types.Datetime](vec) 358 for j := 0; j < vec.Length(); j++ { 359 rows[j][i] = col[j] 360 } 361 case types.T_timestamp: 362 col := vector.GetFixedVectorValues[types.Timestamp](vec) 363 for j := 0; j < vec.Length(); j++ { 364 rows[j][i] = col[j] 365 } 366 case types.T_decimal64: 367 col := vector.GetFixedVectorValues[types.Decimal64](vec) 368 for j := 0; j < vec.Length(); j++ { 369 rows[j][i] = col[j] 370 } 371 case types.T_decimal128: 372 col := vector.GetFixedVectorValues[types.Decimal128](vec) 373 for j := 0; j < vec.Length(); j++ { 374 rows[j][i] = col[j] 375 } 376 case types.T_uuid: 377 col := vector.GetFixedVectorValues[types.Uuid](vec) 378 for j := 0; j < vec.Length(); j++ { 379 rows[j][i] = col[j] 380 } 381 case types.T_TS: 382 col := vector.GetFixedVectorValues[types.TS](vec) 383 for j := 0; j < vec.Length(); j++ { 384 rows[j][i] = col[j] 385 } 386 case types.T_Rowid: 387 col := vector.GetFixedVectorValues[types.Rowid](vec) 388 for j := 0; j < vec.Length(); j++ { 389 rows[j][i] = col[j] 390 } 391 case types.T_char, types.T_varchar, types.T_blob, types.T_json, types.T_text: 392 col := vector.GetBytesVectorValues(vec) 393 for j := 0; j < vec.Length(); j++ { 394 rows[j][i] = col[j] 395 } 396 } 397 } 398 return rows 399 } 400 401 func isTruncate(name string) (uint64, string, bool) { 402 ok, _ := regexp.MatchString(`\_\d+\_meta`, name) 403 if !ok { 404 return 0, "", false 405 } 406 reg, _ := regexp.Compile(`\d+`) 407 str := reg.FindString(name) 408 id, _ := strconv.ParseUint(str, 10, 64) 409 return id, name[len(str)+Meta_Length:], true 410 } 411 412 func DecodeRowid(rowid types.Rowid) (blockId uint64, offset uint32) { 413 tempBuf := make([]byte, 8) 414 copy(tempBuf[2:], rowid[6:12]) 415 blockId = binary.BigEndian.Uint64(tempBuf) 416 offset = binary.BigEndian.Uint32(rowid[12:]) 417 return 418 } 419 420 func BuildQueryResultPath(accountName, statementId string, blockIdx int) string { 421 return fmt.Sprintf(QueryResultPath, accountName, statementId, blockIdx) 422 } 423 424 func BuildQueryResultMetaPath(accountName, statementId string) string { 425 return fmt.Sprintf(QueryResultMetaPath, accountName, statementId) 426 } 427 428 func BuildQueryResultMetaName(accountName, statementId string) string { 429 return fmt.Sprintf(QueryResultMetaName, accountName, statementId) 430 } 431 432 func BuildQueryResultName(accountName, statementId string, blockIdx int) string { 433 return fmt.Sprintf(QueryResultName, accountName, statementId, blockIdx) 434 }