github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/table_function/metadata_scan.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 table_function
    16  
    17  import (
    18  	"strings"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/logutil"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    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/defines"
    27  	"github.com/matrixorigin/matrixone/pkg/objectio"
    28  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    29  	"github.com/matrixorigin/matrixone/pkg/sql/colexec"
    30  	plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan"
    31  	"github.com/matrixorigin/matrixone/pkg/vm"
    32  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    33  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    34  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    35  )
    36  
    37  func metadataScanPrepare(proc *process.Process, arg *Argument) (err error) {
    38  	arg.ctr = new(container)
    39  	arg.ctr.executorsForArgs, err = colexec.NewExpressionExecutorsFromPlanExpressions(proc, arg.Args)
    40  
    41  	for i := range arg.Attrs {
    42  		arg.Attrs[i] = strings.ToUpper(arg.Attrs[i])
    43  	}
    44  	return err
    45  }
    46  
    47  func metadataScan(_ int, proc *process.Process, arg *Argument, result *vm.CallResult) (bool, error) {
    48  	var (
    49  		err         error
    50  		source, col *vector.Vector
    51  		rbat        *batch.Batch
    52  	)
    53  	defer func() {
    54  		if err != nil && rbat != nil {
    55  			rbat.Clean(proc.Mp())
    56  		}
    57  	}()
    58  
    59  	bat := result.Batch
    60  	if bat == nil {
    61  		return true, nil
    62  	}
    63  
    64  	source, err = arg.ctr.executorsForArgs[0].Eval(proc, []*batch.Batch{bat})
    65  	if err != nil {
    66  		return false, err
    67  	}
    68  	col, err = arg.ctr.executorsForArgs[1].Eval(proc, []*batch.Batch{bat})
    69  	if err != nil {
    70  		return false, err
    71  	}
    72  
    73  	dbname, tablename, colname, err := handleDatasource(vector.MustStrCol(source), vector.MustStrCol(col))
    74  	logutil.Infof("db: %s, table: %s, col: %s in metadataScan", dbname, tablename, colname)
    75  	if err != nil {
    76  		return false, err
    77  	}
    78  
    79  	e := proc.Ctx.Value(defines.EngineKey{}).(engine.Engine)
    80  	db, err := e.Database(proc.Ctx, dbname, proc.TxnOperator)
    81  	if err != nil {
    82  		return false, moerr.NewInternalError(proc.Ctx, "get database failed in metadata scan")
    83  	}
    84  
    85  	rel, err := db.Relation(proc.Ctx, tablename, nil)
    86  	if err != nil {
    87  		return false, err
    88  	}
    89  
    90  	metaInfos, err := rel.GetColumMetadataScanInfo(proc.Ctx, colname)
    91  	if err != nil {
    92  		return false, err
    93  	}
    94  
    95  	rbat, err = genRetBatch(*proc, arg, metaInfos)
    96  	if err != nil {
    97  		return false, err
    98  	}
    99  
   100  	result.Batch = rbat
   101  	return false, nil
   102  }
   103  
   104  func handleDatasource(first []string, second []string) (string, string, string, error) {
   105  	if len(first) != 1 || len(second) != 1 {
   106  		return "", "", "", moerr.NewInternalErrorNoCtx("wrong input len")
   107  	}
   108  	s := first[0]
   109  	strs := strings.Split(s, ".")
   110  	if len(strs) != 2 {
   111  		return "", "", "", moerr.NewInternalErrorNoCtx("wrong len of db and tbl input")
   112  	}
   113  	return strs[0], strs[1], second[0], nil
   114  }
   115  
   116  func genRetBatch(proc process.Process, arg *Argument, metaInfos []*plan.MetadataScanInfo) (*batch.Batch, error) {
   117  	retBat, err := initMetadataInfoBat(proc, arg)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	for i := range metaInfos {
   123  		fillMetadataInfoBat(retBat, proc, arg, metaInfos[i])
   124  	}
   125  
   126  	retBat.AddRowCount(len(metaInfos))
   127  
   128  	return retBat, nil
   129  }
   130  
   131  func initMetadataInfoBat(proc process.Process, arg *Argument) (*batch.Batch, error) {
   132  	retBat := batch.New(false, arg.Attrs)
   133  	retBat.Cnt = 1
   134  
   135  	for i, a := range arg.Attrs {
   136  		idx, ok := plan.MetadataScanInfo_MetadataScanInfoType_value[a]
   137  		if !ok {
   138  			return nil, moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", a)
   139  		}
   140  
   141  		tp := plan2.MetadataScanColTypes[idx]
   142  		retBat.Vecs[i] = proc.GetVector(tp)
   143  	}
   144  
   145  	return retBat, nil
   146  }
   147  
   148  func fillMetadataInfoBat(opBat *batch.Batch, proc process.Process, arg *Argument, info *plan.MetadataScanInfo) error {
   149  	mp := proc.GetMPool()
   150  	zm := index.ZM(info.ZoneMap)
   151  	zmNull := !zm.IsInited()
   152  
   153  	for i, colname := range arg.Attrs {
   154  		idx, ok := plan.MetadataScanInfo_MetadataScanInfoType_value[colname]
   155  		if !ok {
   156  			opBat.Clean(proc.GetMPool())
   157  			return moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", colname)
   158  		}
   159  
   160  		switch plan.MetadataScanInfo_MetadataScanInfoType(idx) {
   161  		case plan.MetadataScanInfo_COL_NAME:
   162  			vector.AppendBytes(opBat.Vecs[i], []byte(info.ColName), false, mp)
   163  
   164  		case plan.MetadataScanInfo_OBJECT_NAME:
   165  			vector.AppendBytes(opBat.Vecs[i], []byte(info.ObjectName), false, mp)
   166  
   167  		case plan.MetadataScanInfo_IS_HIDDEN:
   168  			vector.AppendFixed(opBat.Vecs[i], info.IsHidden, false, mp)
   169  
   170  		case plan.MetadataScanInfo_OBJ_LOC:
   171  			vector.AppendBytes(opBat.Vecs[i], []byte(objectio.Location(info.ObjLoc).String()), false, mp)
   172  
   173  		case plan.MetadataScanInfo_CREATE_TS:
   174  			var ts types.TS
   175  			if err := ts.Unmarshal(info.CreateTs); err != nil {
   176  				return err
   177  			}
   178  			vector.AppendFixed(opBat.Vecs[i], ts, false, mp)
   179  
   180  		case plan.MetadataScanInfo_DELETE_TS:
   181  			var ts types.TS
   182  			if err := ts.Unmarshal(info.DeleteTs); err != nil {
   183  				return err
   184  			}
   185  			vector.AppendFixed(opBat.Vecs[i], ts, false, mp)
   186  
   187  		case plan.MetadataScanInfo_ROWS_CNT:
   188  			vector.AppendFixed(opBat.Vecs[i], info.RowCnt, false, mp)
   189  
   190  		case plan.MetadataScanInfo_NULL_CNT:
   191  			vector.AppendFixed(opBat.Vecs[i], info.NullCnt, false, mp)
   192  
   193  		case plan.MetadataScanInfo_COMPRESS_SIZE:
   194  			vector.AppendFixed(opBat.Vecs[i], info.CompressSize, false, mp)
   195  
   196  		case plan.MetadataScanInfo_ORIGIN_SIZE:
   197  			vector.AppendFixed(opBat.Vecs[i], info.OriginSize, false, mp)
   198  
   199  		case plan.MetadataScanInfo_MIN: // TODO: find a way to show this info
   200  			vector.AppendBytes(opBat.Vecs[i], zm.GetMinBuf(), zmNull, mp)
   201  
   202  		case plan.MetadataScanInfo_MAX: // TODO: find a way to show this info
   203  			vector.AppendBytes(opBat.Vecs[i], zm.GetMaxBuf(), zmNull, mp)
   204  
   205  		case plan.MetadataScanInfo_SUM: // TODO: find a way to show this info
   206  			vector.AppendBytes(opBat.Vecs[i], zm.GetSumBuf(), zmNull, mp)
   207  
   208  		default:
   209  		}
   210  	}
   211  
   212  	return nil
   213  }