github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/txn/txnimpl/sysobject.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 txnimpl
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  
    21  	pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog"
    22  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle"
    28  )
    29  
    30  type txnSysObject struct {
    31  	*txnObject
    32  	table   *txnTable
    33  	catalog *catalog.Catalog
    34  }
    35  
    36  func newSysObject(table *txnTable, meta *catalog.ObjectEntry) *txnSysObject {
    37  	obj := &txnSysObject{
    38  		txnObject: newObject(table, meta),
    39  		table:     table,
    40  		catalog:   meta.GetTable().GetCatalog(),
    41  	}
    42  	return obj
    43  }
    44  
    45  func bool2i8(v bool) int8 {
    46  	if v {
    47  		return int8(1)
    48  	} else {
    49  		return int8(0)
    50  	}
    51  }
    52  
    53  func (obj *txnSysObject) isSysTable() bool {
    54  	return isSysTable(obj.table.entry.GetLastestSchemaLocked().Name)
    55  }
    56  
    57  func (obj *txnSysObject) GetTotalChanges() int {
    58  	if obj.isSysTable() {
    59  		panic("not supported")
    60  	}
    61  	return obj.txnObject.GetTotalChanges()
    62  }
    63  
    64  func (obj *txnSysObject) RangeDelete(blkID uint16, start, end uint32, dt handle.DeleteType, mp *mpool.MPool) (err error) {
    65  	if obj.isSysTable() {
    66  		panic("not supported")
    67  	}
    68  	return obj.txnObject.RangeDelete(blkID, start, end, dt, mp)
    69  }
    70  
    71  func (obj *txnSysObject) processDB(fn func(*catalog.DBEntry) error, ignoreErr bool) (err error) {
    72  	it := newDBIt(obj.Txn, obj.catalog)
    73  	for it.linkIt.Valid() {
    74  		if err = it.GetError(); err != nil && !ignoreErr {
    75  			break
    76  		}
    77  		db := it.GetCurr()
    78  		if err = fn(db); err != nil && !ignoreErr {
    79  			break
    80  		}
    81  		it.Next()
    82  	}
    83  	return
    84  }
    85  
    86  func (obj *txnSysObject) processTable(entry *catalog.DBEntry, fn func(*catalog.TableEntry) error, ignoreErr bool) (err error) {
    87  	txnDB, err := obj.table.store.getOrSetDB(entry.GetID())
    88  	if err != nil {
    89  		return
    90  	}
    91  	it := newRelationIt(txnDB)
    92  	for it.linkIt.Valid() {
    93  		if err = it.GetError(); err != nil && !ignoreErr {
    94  			break
    95  		}
    96  		table := it.GetCurr()
    97  		if err = fn(table); err != nil && !ignoreErr {
    98  			break
    99  		}
   100  		it.Next()
   101  	}
   102  	return
   103  }
   104  
   105  func FillColumnRow(table *catalog.TableEntry, node *catalog.MVCCNode[*catalog.TableMVCCNode], attr string, colData containers.Vector) {
   106  	schema := node.BaseNode.Schema
   107  	tableID := table.GetID()
   108  	for i, colDef := range schema.ColDefs {
   109  		switch attr {
   110  		case pkgcatalog.SystemColAttr_UniqName:
   111  			colData.Append([]byte(fmt.Sprintf("%d-%s", tableID, colDef.Name)), false)
   112  		case pkgcatalog.SystemColAttr_AccID:
   113  			colData.Append(schema.AcInfo.TenantID, false)
   114  		case pkgcatalog.SystemColAttr_Name:
   115  			colData.Append([]byte(colDef.Name), false)
   116  		case pkgcatalog.SystemColAttr_Num:
   117  			colData.Append(int32(i+1), false)
   118  		case pkgcatalog.SystemColAttr_Type:
   119  			//colData.Append(int32(colDef.Type.Oid))
   120  			data, _ := types.Encode(&colDef.Type)
   121  			colData.Append(data, false)
   122  		case pkgcatalog.SystemColAttr_DBID:
   123  			colData.Append(table.GetDB().GetID(), false)
   124  		case pkgcatalog.SystemColAttr_DBName:
   125  			colData.Append([]byte(table.GetDB().GetName()), false)
   126  		case pkgcatalog.SystemColAttr_RelID:
   127  			colData.Append(tableID, false)
   128  		case pkgcatalog.SystemColAttr_RelName:
   129  			colData.Append([]byte(schema.Name), false)
   130  		case pkgcatalog.SystemColAttr_ConstraintType:
   131  			if colDef.Primary {
   132  				colData.Append([]byte(pkgcatalog.SystemColPKConstraint), false)
   133  			} else {
   134  				colData.Append([]byte(pkgcatalog.SystemColNoConstraint), false)
   135  			}
   136  		case pkgcatalog.SystemColAttr_Length:
   137  			colData.Append(int32(colDef.Type.Width), false)
   138  		case pkgcatalog.SystemColAttr_NullAbility:
   139  			colData.Append(bool2i8(!colDef.NullAbility), false)
   140  		case pkgcatalog.SystemColAttr_HasExpr:
   141  			colData.Append(bool2i8(len(colDef.Default) > 0), false) // @imlinjunhong says always has Default, expect row_id
   142  		case pkgcatalog.SystemColAttr_DefaultExpr:
   143  			colData.Append(colDef.Default, false)
   144  		case pkgcatalog.SystemColAttr_IsDropped:
   145  			colData.Append(int8(0), false)
   146  		case pkgcatalog.SystemColAttr_IsHidden:
   147  			colData.Append(bool2i8(colDef.Hidden), false)
   148  		case pkgcatalog.SystemColAttr_IsUnsigned:
   149  			colData.Append(bool2i8(colDef.Type.IsUInt()), false)
   150  		case pkgcatalog.SystemColAttr_IsAutoIncrement:
   151  			colData.Append(bool2i8(colDef.AutoIncrement), false)
   152  		case pkgcatalog.SystemColAttr_Comment:
   153  			colData.Append([]byte(colDef.Comment), false)
   154  		case pkgcatalog.SystemColAttr_HasUpdate:
   155  			colData.Append(bool2i8(len(colDef.OnUpdate) > 0), false)
   156  		case pkgcatalog.SystemColAttr_IsClusterBy:
   157  			colData.Append(bool2i8(colDef.IsClusterBy()), false)
   158  		case pkgcatalog.SystemColAttr_Update:
   159  			colData.Append(colDef.OnUpdate, false)
   160  		case pkgcatalog.SystemColAttr_Seqnum:
   161  			colData.Append(colDef.SeqNum, false)
   162  		case pkgcatalog.SystemColAttr_EnumValues:
   163  			colData.Append([]byte(colDef.EnumValues), false)
   164  		default:
   165  			panic("unexpected colname. if add new catalog def, fill it in this switch")
   166  		}
   167  	}
   168  }
   169  
   170  // func (obj *txnSysObject) GetDeltaPersistedTS() types.TS {
   171  // 	return types.TS{}.Next()
   172  // }
   173  
   174  func (obj *txnSysObject) getColumnTableVec(
   175  	ts types.TS, colIdx int, mp *mpool.MPool,
   176  ) (colData containers.Vector, err error) {
   177  	col := catalog.SystemColumnSchema.ColDefs[colIdx]
   178  	colData = containers.MakeVector(col.Type, mp)
   179  	tableFn := func(table *catalog.TableEntry) error {
   180  		table.RLock()
   181  		node := table.GetVisibleNodeLocked(obj.Txn)
   182  		table.RUnlock()
   183  		FillColumnRow(table, node, col.Name, colData)
   184  		return nil
   185  	}
   186  	dbFn := func(db *catalog.DBEntry) error {
   187  		return obj.processTable(db, tableFn, false)
   188  	}
   189  	err = obj.processDB(dbFn, false)
   190  	if err != nil {
   191  		return
   192  	}
   193  	return
   194  }
   195  func (obj *txnSysObject) getColumnTableData(
   196  	colIdx int, mp *mpool.MPool,
   197  ) (view *containers.ColumnView, err error) {
   198  	ts := obj.Txn.GetStartTS()
   199  	view = containers.NewColumnView(colIdx)
   200  	colData, err := obj.getColumnTableVec(ts, colIdx, mp)
   201  	view.SetData(colData)
   202  	return
   203  }
   204  
   205  func FillTableRow(table *catalog.TableEntry, node *catalog.MVCCNode[*catalog.TableMVCCNode], attr string, colData containers.Vector) {
   206  	schema := node.BaseNode.Schema
   207  	switch attr {
   208  	case pkgcatalog.SystemRelAttr_ID:
   209  		colData.Append(table.GetID(), false)
   210  	case pkgcatalog.SystemRelAttr_Name:
   211  		colData.Append([]byte(schema.Name), false)
   212  	case pkgcatalog.SystemRelAttr_DBName:
   213  		colData.Append([]byte(table.GetDB().GetName()), false)
   214  	case pkgcatalog.SystemRelAttr_DBID:
   215  		colData.Append(table.GetDB().GetID(), false)
   216  	case pkgcatalog.SystemRelAttr_Comment:
   217  		colData.Append([]byte(schema.Comment), false)
   218  	case pkgcatalog.SystemRelAttr_Partitioned:
   219  		colData.Append(schema.Partitioned, false)
   220  	case pkgcatalog.SystemRelAttr_Partition:
   221  		colData.Append([]byte(schema.Partition), false)
   222  	case pkgcatalog.SystemRelAttr_Persistence:
   223  		colData.Append([]byte(pkgcatalog.SystemPersistRel), false)
   224  	case pkgcatalog.SystemRelAttr_Kind:
   225  		colData.Append([]byte(schema.Relkind), false)
   226  	case pkgcatalog.SystemRelAttr_CreateSQL:
   227  		colData.Append([]byte(schema.Createsql), false)
   228  	case pkgcatalog.SystemRelAttr_ViewDef:
   229  		colData.Append([]byte(schema.View), false)
   230  	case pkgcatalog.SystemRelAttr_Owner:
   231  		colData.Append(schema.AcInfo.RoleID, false)
   232  	case pkgcatalog.SystemRelAttr_Creator:
   233  		colData.Append(schema.AcInfo.UserID, false)
   234  	case pkgcatalog.SystemRelAttr_CreateAt:
   235  		colData.Append(schema.AcInfo.CreateAt, false)
   236  	case pkgcatalog.SystemRelAttr_AccID:
   237  		colData.Append(schema.AcInfo.TenantID, false)
   238  	case pkgcatalog.SystemRelAttr_Constraint:
   239  		colData.Append(schema.Constraint, false)
   240  	case pkgcatalog.SystemRelAttr_Version:
   241  		colData.Append(schema.Version, false)
   242  	case pkgcatalog.SystemRelAttr_CatalogVersion:
   243  		colData.Append(schema.CatalogVersion, false)
   244  	case catalog.AccountIDDbNameTblName:
   245  		packer := types.NewPacker(common.WorkspaceAllocator)
   246  		packer.EncodeUint32(schema.AcInfo.TenantID)
   247  		packer.EncodeStringType([]byte(table.GetDB().GetName()))
   248  		packer.EncodeStringType([]byte(schema.Name))
   249  		colData.Append(packer.Bytes(), false)
   250  		packer.FreeMem()
   251  	default:
   252  		panic("unexpected colname. if add new catalog def, fill it in this switch")
   253  	}
   254  }
   255  
   256  func (obj *txnSysObject) getRelTableVec(ts types.TS, colIdx int, mp *mpool.MPool) (colData containers.Vector, err error) {
   257  	colDef := catalog.SystemTableSchema.ColDefs[colIdx]
   258  	colData = containers.MakeVector(colDef.Type, mp)
   259  	tableFn := func(table *catalog.TableEntry) error {
   260  		table.RLock()
   261  		node := table.GetVisibleNodeLocked(obj.Txn)
   262  		table.RUnlock()
   263  		FillTableRow(table, node, colDef.Name, colData)
   264  		return nil
   265  	}
   266  	dbFn := func(db *catalog.DBEntry) error {
   267  		return obj.processTable(db, tableFn, false)
   268  	}
   269  	if err = obj.processDB(dbFn, false); err != nil {
   270  		return
   271  	}
   272  	return
   273  }
   274  
   275  func (obj *txnSysObject) getRelTableData(colIdx int, mp *mpool.MPool) (view *containers.ColumnView, err error) {
   276  	ts := obj.Txn.GetStartTS()
   277  	view = containers.NewColumnView(colIdx)
   278  	colData, err := obj.getRelTableVec(ts, colIdx, mp)
   279  	view.SetData(colData)
   280  	return
   281  }
   282  
   283  func FillDBRow(db *catalog.DBEntry, _ *catalog.MVCCNode[*catalog.EmptyMVCCNode], attr string, colData containers.Vector) {
   284  	switch attr {
   285  	case pkgcatalog.SystemDBAttr_ID:
   286  		colData.Append(db.GetID(), false)
   287  	case pkgcatalog.SystemDBAttr_Name:
   288  		colData.Append([]byte(db.GetName()), false)
   289  	case pkgcatalog.SystemDBAttr_CatalogName:
   290  		colData.Append([]byte(pkgcatalog.SystemCatalogName), false)
   291  	case pkgcatalog.SystemDBAttr_CreateSQL:
   292  		colData.Append([]byte(db.GetCreateSql()), false)
   293  	case pkgcatalog.SystemDBAttr_Owner:
   294  		colData.Append(db.GetRoleID(), false)
   295  	case pkgcatalog.SystemDBAttr_Creator:
   296  		colData.Append(db.GetUserID(), false)
   297  	case pkgcatalog.SystemDBAttr_CreateAt:
   298  		colData.Append(db.GetCreateAt(), false)
   299  	case pkgcatalog.SystemDBAttr_AccID:
   300  		colData.Append(db.GetTenantID(), false)
   301  	case pkgcatalog.SystemDBAttr_Type:
   302  		colData.Append([]byte(db.GetDatType()), false)
   303  	case catalog.AccountIDDbName:
   304  		packer := types.NewPacker(common.WorkspaceAllocator)
   305  		packer.EncodeUint32(db.GetTenantID())
   306  		packer.EncodeStringType([]byte(db.GetName()))
   307  		colData.Append(packer.Bytes(), false)
   308  		packer.FreeMem()
   309  	default:
   310  		panic("unexpected colname. if add new catalog def, fill it in this switch")
   311  	}
   312  }
   313  func (obj *txnSysObject) getDBTableVec(colIdx int, mp *mpool.MPool) (colData containers.Vector, err error) {
   314  	colDef := catalog.SystemDBSchema.ColDefs[colIdx]
   315  	colData = containers.MakeVector(colDef.Type, mp)
   316  	fn := func(db *catalog.DBEntry) error {
   317  		FillDBRow(db, nil, colDef.Name, colData)
   318  		return nil
   319  	}
   320  	if err = obj.processDB(fn, false); err != nil {
   321  		return
   322  	}
   323  	return
   324  }
   325  func (obj *txnSysObject) getDBTableData(
   326  	colIdx int, mp *mpool.MPool,
   327  ) (view *containers.ColumnView, err error) {
   328  	view = containers.NewColumnView(colIdx)
   329  	colData, err := obj.getDBTableVec(colIdx, mp)
   330  	view.SetData(colData)
   331  	return
   332  }
   333  
   334  func (obj *txnSysObject) GetColumnDataById(
   335  	ctx context.Context, blkID uint16, colIdx int, mp *mpool.MPool,
   336  ) (view *containers.ColumnView, err error) {
   337  	if !obj.isSysTable() {
   338  		return obj.txnObject.GetColumnDataById(ctx, blkID, colIdx, mp)
   339  	}
   340  	if obj.table.GetID() == pkgcatalog.MO_DATABASE_ID {
   341  		return obj.getDBTableData(colIdx, mp)
   342  	} else if obj.table.GetID() == pkgcatalog.MO_TABLES_ID {
   343  		return obj.getRelTableData(colIdx, mp)
   344  	} else if obj.table.GetID() == pkgcatalog.MO_COLUMNS_ID {
   345  		return obj.getColumnTableData(colIdx, mp)
   346  	} else {
   347  		panic("not supported")
   348  	}
   349  }
   350  
   351  func (obj *txnSysObject) Prefetch(idxes []int) error {
   352  	return nil
   353  }
   354  
   355  func (obj *txnSysObject) GetColumnDataByName(
   356  	ctx context.Context, blkID uint16, attr string, mp *mpool.MPool,
   357  ) (view *containers.ColumnView, err error) {
   358  	colIdx := obj.entry.GetSchema().GetColIdx(attr)
   359  	return obj.GetColumnDataById(ctx, blkID, colIdx, mp)
   360  }
   361  
   362  func (obj *txnSysObject) GetColumnDataByNames(
   363  	ctx context.Context, blkID uint16, attrs []string, mp *mpool.MPool,
   364  ) (view *containers.BlockView, err error) {
   365  	if !obj.isSysTable() {
   366  		return obj.txnObject.GetColumnDataByNames(ctx, blkID, attrs, mp)
   367  	}
   368  	view = containers.NewBlockView()
   369  	ts := obj.Txn.GetStartTS()
   370  	switch obj.table.GetID() {
   371  	case pkgcatalog.MO_DATABASE_ID:
   372  		for _, attr := range attrs {
   373  			colIdx := obj.entry.GetSchema().GetColIdx(attr)
   374  			vec, err := obj.getDBTableVec(colIdx, mp)
   375  			view.SetData(colIdx, vec)
   376  			if err != nil {
   377  				return view, err
   378  			}
   379  		}
   380  	case pkgcatalog.MO_TABLES_ID:
   381  		for _, attr := range attrs {
   382  			colIdx := obj.entry.GetSchema().GetColIdx(attr)
   383  			vec, err := obj.getRelTableVec(ts, colIdx, mp)
   384  			view.SetData(colIdx, vec)
   385  			if err != nil {
   386  				return view, err
   387  			}
   388  		}
   389  	case pkgcatalog.MO_COLUMNS_ID:
   390  		for _, attr := range attrs {
   391  			colIdx := obj.entry.GetSchema().GetColIdx(attr)
   392  			vec, err := obj.getColumnTableVec(ts, colIdx, mp)
   393  			view.SetData(colIdx, vec)
   394  			if err != nil {
   395  				return view, err
   396  			}
   397  		}
   398  	default:
   399  		panic("not supported")
   400  	}
   401  	return
   402  }