github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/storage/memorystorage/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 memorystorage
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/catalog"
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    22  	"github.com/matrixorigin/matrixone/pkg/txn/storage/memorystorage/memorytable"
    23  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    24  	"github.com/matrixorigin/matrixone/pkg/vm/engine/memoryengine"
    25  )
    26  
    27  var (
    28  	index_AccountID            = Text("account id")
    29  	index_AccountID_Name       = Text("account id, name")
    30  	index_DatabaseID           = Text("database id")
    31  	index_DatabaseID_Name      = Text("database id, name")
    32  	index_RelationID           = Text("relation id")
    33  	index_RelationID_IsHidden  = Text("relation id, is hidden")
    34  	index_RelationID_IsPrimary = Text("relation id, is primary")
    35  	index_RelationID_Name      = Text("relation id, name")
    36  	index_RowID                = Text("row id")
    37  )
    38  
    39  type (
    40  	DatabaseRowIter  = Iter[ID, *DatabaseRow]
    41  	RelationRowIter  = Iter[ID, *RelationRow]
    42  	AttributeRowIter = Iter[ID, *AttributeRow]
    43  )
    44  
    45  type DatabaseRow struct {
    46  	ID        ID
    47  	AccountID uint32 // 0 is the sys account
    48  	Name      []byte
    49  	Typ       []byte
    50  	CreateSql []byte
    51  }
    52  
    53  func (d *DatabaseRow) Key() ID {
    54  	return d.ID
    55  }
    56  
    57  func (d *DatabaseRow) Value() *DatabaseRow {
    58  	return d
    59  }
    60  
    61  func (d *DatabaseRow) Indexes() []Tuple {
    62  	return []Tuple{
    63  		{index_AccountID, Uint(d.AccountID)},
    64  		{index_AccountID_Name, Uint(d.AccountID), Text(d.Name)},
    65  	}
    66  }
    67  
    68  func (d *DatabaseRow) UniqueIndexes() []Tuple {
    69  	return []Tuple{
    70  		{index_AccountID_Name, Uint(d.AccountID), Text(d.Name)},
    71  	}
    72  }
    73  
    74  var _ NamedRow = new(DatabaseRow)
    75  
    76  func (d *DatabaseRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) {
    77  	defer func() {
    78  		if ret.Value != nil {
    79  			verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value)
    80  		}
    81  	}()
    82  	switch name {
    83  	case catalog.SystemDBAttr_ID:
    84  		ret.Value = uint64(d.ID)
    85  	case catalog.SystemDBAttr_Name:
    86  		ret.Value = d.Name
    87  	case catalog.SystemDBAttr_CatalogName:
    88  		ret.Value = []byte("")
    89  	case catalog.SystemDBAttr_CreateSQL:
    90  		ret.Value = []byte("")
    91  	case catalog.SystemDBAttr_Owner:
    92  		ret.Value = uint32(d.AccountID)
    93  	case catalog.SystemDBAttr_Creator:
    94  		ret.Value = uint32(d.AccountID)
    95  	case catalog.SystemDBAttr_CreateAt:
    96  		ret.Value = types.Timestamp(0)
    97  	case catalog.SystemDBAttr_AccID:
    98  		ret.Value = uint32(d.AccountID)
    99  	case rowIDColumnName:
   100  		ret.Value = d.ID.ToRowID()
   101  	default:
   102  		panic(fmt.Sprintf("fixme: %s", name))
   103  	}
   104  	return
   105  }
   106  
   107  type RelationRow struct {
   108  	ID           ID
   109  	DatabaseID   ID
   110  	Name         []byte
   111  	Type         memoryengine.RelationType
   112  	Comments     []byte
   113  	Properties   map[string]string
   114  	Partitioned  int8   // 1 : the table has partitions. 0 : no partition
   115  	PartitionDef []byte // partition info for the table has paritions
   116  	ViewDef      []byte
   117  	Constraint   []byte
   118  }
   119  
   120  func (r *RelationRow) Key() ID {
   121  	return r.ID
   122  }
   123  
   124  func (r *RelationRow) Value() *RelationRow {
   125  	return r
   126  }
   127  
   128  func (r *RelationRow) Indexes() []Tuple {
   129  	return []Tuple{
   130  		{index_DatabaseID, r.DatabaseID},
   131  		{index_DatabaseID_Name, r.DatabaseID, Text(r.Name)},
   132  	}
   133  }
   134  
   135  func (r *RelationRow) UniqueIndexes() []Tuple {
   136  	return []Tuple{
   137  		{index_DatabaseID_Name, r.DatabaseID, Text(r.Name)},
   138  	}
   139  }
   140  
   141  var _ NamedRow = new(RelationRow)
   142  
   143  func (r *RelationRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) {
   144  	defer func() {
   145  		if ret.Value != nil {
   146  			verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value)
   147  		}
   148  	}()
   149  	switch name {
   150  	case catalog.SystemRelAttr_ID:
   151  		ret.Value = uint64(r.ID)
   152  	case catalog.SystemRelAttr_Name:
   153  		ret.Value = r.Name
   154  	case catalog.SystemRelAttr_DBID:
   155  		if r.DatabaseID.IsEmpty() {
   156  			ret.Value = uint64(0)
   157  			return
   158  		}
   159  		db, err := handler.databases.Get(tx, r.DatabaseID)
   160  		if err != nil {
   161  			return ret, err
   162  		}
   163  		ret.Value = uint64(db.ID)
   164  	case catalog.SystemRelAttr_DBName:
   165  		if r.DatabaseID.IsEmpty() {
   166  			ret.Value = []byte("")
   167  			return
   168  		}
   169  		db, err := handler.databases.Get(tx, r.DatabaseID)
   170  		if err != nil {
   171  			return ret, err
   172  		}
   173  		ret.Value = db.Name
   174  	case catalog.SystemRelAttr_Persistence:
   175  		ret.Value = []byte("")
   176  	case catalog.SystemRelAttr_Kind:
   177  		ret.Value = []byte(r.Properties[catalog.SystemRelAttr_Kind]) // tae's logic
   178  	case catalog.SystemRelAttr_Comment:
   179  		ret.Value = r.Comments
   180  	case catalog.SystemRelAttr_Partitioned:
   181  		ret.Value = r.Partitioned
   182  	case catalog.SystemRelAttr_Partition:
   183  		ret.Value = r.PartitionDef
   184  	case catalog.SystemRelAttr_CreateSQL:
   185  		ret.Value = []byte(r.Properties[catalog.SystemRelAttr_CreateSQL]) // tae's logic
   186  	case catalog.SystemRelAttr_Owner:
   187  		ret.Value = uint32(0) //TODO
   188  	case catalog.SystemRelAttr_Creator:
   189  		ret.Value = uint32(0) //TODO
   190  	case catalog.SystemRelAttr_CreateAt:
   191  		ret.Value = types.Timestamp(0) //TODO
   192  	case catalog.SystemRelAttr_AccID:
   193  		ret.Value = uint32(0)
   194  	case rowIDColumnName:
   195  		ret.Value = r.ID.ToRowID()
   196  	case catalog.SystemRelAttr_ViewDef:
   197  		ret.Value = []byte(r.ViewDef)
   198  	case catalog.SystemRelAttr_Constraint:
   199  		ret.Value = r.Constraint
   200  	default:
   201  		panic(fmt.Sprintf("fixme: %s", name))
   202  	}
   203  	return
   204  }
   205  
   206  type AttributeRow struct {
   207  	ID         ID
   208  	RelationID ID
   209  	Order      int
   210  	Nullable   bool
   211  	engine.Attribute
   212  }
   213  
   214  func (a *AttributeRow) Key() ID {
   215  	return a.ID
   216  }
   217  
   218  func (a *AttributeRow) Value() *AttributeRow {
   219  	return a
   220  }
   221  
   222  func (a *AttributeRow) Indexes() []Tuple {
   223  	return []Tuple{
   224  		{index_RelationID, a.RelationID},
   225  		{index_RelationID_Name, a.RelationID, Text(a.Name)},
   226  		{index_RelationID_IsPrimary, a.RelationID, Bool(a.Primary)},
   227  		{index_RelationID_IsHidden, a.RelationID, Bool(a.IsHidden)},
   228  	}
   229  }
   230  
   231  func (a *AttributeRow) UniqueIndexes() []Tuple {
   232  	return []Tuple{
   233  		{index_RelationID_Name, a.RelationID, Text(a.Name)},
   234  	}
   235  }
   236  
   237  var _ NamedRow = new(AttributeRow)
   238  
   239  func (a *AttributeRow) AttrByName(handler *MemHandler, tx *Transaction, name string) (ret Nullable, err error) {
   240  	defer func() {
   241  		if ret.Value != nil {
   242  			verifyAttr(catalog.MoDatabaseSchema, catalog.MoDatabaseTypes, name, ret.Value)
   243  		}
   244  	}()
   245  	switch name {
   246  	case catalog.SystemColAttr_UniqName:
   247  		ret.Value = []byte(a.Name)
   248  	case catalog.SystemColAttr_AccID:
   249  		ret.Value = uint32(0)
   250  	case catalog.SystemColAttr_Name:
   251  		ret.Value = []byte(a.Name)
   252  	case catalog.SystemColAttr_DBID:
   253  		rel, err := handler.relations.Get(tx, a.RelationID)
   254  		if err != nil {
   255  			return ret, err
   256  		}
   257  		if rel.DatabaseID.IsEmpty() {
   258  			ret.Value = uint64(0)
   259  			return ret, nil
   260  		}
   261  		db, err := handler.databases.Get(tx, rel.DatabaseID)
   262  		if err != nil {
   263  			return ret, err
   264  		}
   265  		ret.Value = uint64(db.ID)
   266  	case catalog.SystemColAttr_DBName:
   267  		rel, err := handler.relations.Get(tx, a.RelationID)
   268  		if err != nil {
   269  			return ret, err
   270  		}
   271  		if rel.DatabaseID.IsEmpty() {
   272  			ret.Value = []byte("")
   273  			return ret, nil
   274  		}
   275  		db, err := handler.databases.Get(tx, rel.DatabaseID)
   276  		if err != nil {
   277  			return ret, err
   278  		}
   279  		ret.Value = db.Name
   280  	case catalog.SystemColAttr_RelID:
   281  		ret.Value = uint64(a.RelationID)
   282  	case catalog.SystemColAttr_RelName:
   283  		rel, err := handler.relations.Get(tx, a.RelationID)
   284  		if err != nil {
   285  			return ret, err
   286  		}
   287  		ret.Value = rel.Name
   288  	case catalog.SystemColAttr_Type:
   289  		data, err := types.Encode(&a.Type)
   290  		if err != nil {
   291  			return ret, err
   292  		}
   293  		ret.Value = data
   294  	case catalog.SystemColAttr_Num:
   295  		ret.Value = int32(a.Order)
   296  	case catalog.SystemColAttr_Length:
   297  		ret.Value = int32(a.Type.TypeSize())
   298  	case catalog.SystemColAttr_NullAbility:
   299  		ret.Value = boolToInt8(a.Nullable)
   300  	case catalog.SystemColAttr_HasExpr:
   301  		ret.Value = boolToInt8(a.Default != nil)
   302  	case catalog.SystemColAttr_DefaultExpr:
   303  		if a.Default != nil {
   304  			defaultExpr, err := types.Encode(a.Default)
   305  			if err != nil {
   306  				return ret, nil
   307  			}
   308  			ret.Value = defaultExpr
   309  		} else {
   310  			ret.Value = []byte("")
   311  		}
   312  	case catalog.SystemColAttr_HasUpdate:
   313  		ret.Value = boolToInt8(a.OnUpdate != nil)
   314  	case catalog.SystemColAttr_Update:
   315  		if a.OnUpdate != nil {
   316  			expr, err := types.Encode(a.OnUpdate)
   317  			if err != nil {
   318  				return ret, nil
   319  			}
   320  			ret.Value = expr
   321  		} else {
   322  			ret.Value = []byte("")
   323  		}
   324  	case catalog.SystemColAttr_IsDropped:
   325  		ret.Value = boolToInt8(false)
   326  	case catalog.SystemColAttr_ConstraintType:
   327  		if a.Primary {
   328  			ret.Value = []byte("p")
   329  		} else {
   330  			ret.Value = []byte("n")
   331  		}
   332  	case catalog.SystemColAttr_IsUnsigned:
   333  		ret.Value = boolToInt8(a.Type.Oid == types.T_uint8 ||
   334  			a.Type.Oid == types.T_uint16 ||
   335  			a.Type.Oid == types.T_uint32 ||
   336  			a.Type.Oid == types.T_uint64 ||
   337  			a.Type.Oid == types.T_uint128)
   338  	case catalog.SystemColAttr_IsAutoIncrement:
   339  		ret.Value = boolToInt8(a.AutoIncrement)
   340  	case catalog.SystemColAttr_IsHidden:
   341  		ret.Value = boolToInt8(a.IsHidden)
   342  	case catalog.SystemColAttr_Comment:
   343  		ret.Value = []byte(a.Comment)
   344  	case rowIDColumnName:
   345  		ret.Value = a.ID.ToRowID()
   346  	case catalog.SystemColAttr_IsClusterBy:
   347  		ret.Value = boolToInt8(a.ClusterBy)
   348  	default:
   349  		panic(fmt.Sprintf("fixme: %s", name))
   350  	}
   351  	return
   352  }
   353  
   354  func verifyAttr(
   355  	names []string,
   356  	types []types.Type,
   357  	name string,
   358  	value any,
   359  ) {
   360  	for i, attrName := range names {
   361  		if attrName != name {
   362  			continue
   363  		}
   364  		if value == nil {
   365  			panic(fmt.Sprintf("%s should not be nil", attrName))
   366  		}
   367  		if !memorytable.TypeMatch(value, types[i].Oid) {
   368  			panic(fmt.Sprintf("%s should be %v typed", name, types[i]))
   369  		}
   370  	}
   371  }