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