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