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  }