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  }