github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/table_function/table_function.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  	"bytes"
    19  	"fmt"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/vm"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    27  )
    28  
    29  const argName = "table_function"
    30  
    31  func (arg *Argument) Call(proc *process.Process) (vm.CallResult, error) {
    32  	if err, isCancel := vm.CancelCheck(proc); isCancel {
    33  		return vm.CancelResult, err
    34  	}
    35  
    36  	tblArg := arg
    37  	var (
    38  		f bool
    39  		e error
    40  	)
    41  	idx := arg.GetIdx()
    42  
    43  	result, err := arg.GetChildren(0).Call(proc)
    44  	if err != nil {
    45  		return result, err
    46  	}
    47  
    48  	anal := proc.GetAnalyze(arg.GetIdx(), arg.GetParallelIdx(), arg.GetParallelMajor())
    49  	anal.Start()
    50  	defer anal.Stop()
    51  
    52  	switch tblArg.FuncName {
    53  	case "unnest":
    54  		f, e = unnestCall(idx, proc, tblArg, &result)
    55  	case "generate_series":
    56  		f, e = generateSeriesCall(idx, proc, tblArg, &result)
    57  	case "meta_scan":
    58  		f, e = metaScanCall(idx, proc, tblArg, &result)
    59  	case "current_account":
    60  		f, e = currentAccountCall(idx, proc, tblArg, &result)
    61  	case "metadata_scan":
    62  		f, e = metadataScan(idx, proc, tblArg, &result)
    63  	case "processlist":
    64  		f, e = processlist(idx, proc, tblArg, &result)
    65  	case "mo_locks":
    66  		f, e = moLocksCall(idx, proc, tblArg, &result)
    67  	case "mo_configurations":
    68  		f, e = moConfigurationsCall(idx, proc, tblArg, &result)
    69  	case "mo_transactions":
    70  		f, e = moTransactionsCall(idx, proc, tblArg, &result)
    71  	case "mo_cache":
    72  		f, e = moCacheCall(idx, proc, tblArg, &result)
    73  	default:
    74  		result.Status = vm.ExecStop
    75  		return result, moerr.NewNotSupported(proc.Ctx, fmt.Sprintf("table function %s is not supported", tblArg.FuncName))
    76  	}
    77  	if e != nil || f {
    78  		if f {
    79  			result.Status = vm.ExecStop
    80  			return result, e
    81  		}
    82  		return result, e
    83  	}
    84  
    85  	if arg.buf != nil {
    86  		proc.PutBatch(arg.buf)
    87  		arg.buf = nil
    88  	}
    89  	arg.buf = result.Batch
    90  	if arg.buf == nil {
    91  		result.Status = vm.ExecStop
    92  		return result, e
    93  	}
    94  	if arg.buf.IsEmpty() {
    95  		return result, e
    96  	}
    97  
    98  	if arg.buf.VectorCount() != len(tblArg.retSchema) {
    99  		result.Status = vm.ExecStop
   100  		return result, moerr.NewInternalError(proc.Ctx, "table function %s return length mismatch", tblArg.FuncName)
   101  	}
   102  	for i := range tblArg.retSchema {
   103  		if arg.buf.GetVector(int32(i)).GetType().Oid != tblArg.retSchema[i].Oid {
   104  			result.Status = vm.ExecStop
   105  			return result, moerr.NewInternalError(proc.Ctx, "table function %s return type mismatch", tblArg.FuncName)
   106  		}
   107  	}
   108  
   109  	if f {
   110  		result.Status = vm.ExecStop
   111  		return result, e
   112  	}
   113  	return result, e
   114  }
   115  
   116  func (arg *Argument) String(buf *bytes.Buffer) {
   117  	buf.WriteString(argName)
   118  	buf.WriteString(arg.FuncName)
   119  }
   120  
   121  func (arg *Argument) Prepare(proc *process.Process) error {
   122  	tblArg := arg
   123  	tblArg.ctr = new(container)
   124  
   125  	retSchema := make([]types.Type, len(tblArg.Rets))
   126  	for i := range tblArg.Rets {
   127  		retSchema[i] = dupType(&tblArg.Rets[i].Typ)
   128  	}
   129  	tblArg.retSchema = retSchema
   130  
   131  	switch tblArg.FuncName {
   132  	case "unnest":
   133  		return unnestPrepare(proc, tblArg)
   134  	case "generate_series":
   135  		return generateSeriesPrepare(proc, tblArg)
   136  	case "meta_scan":
   137  		return metaScanPrepare(proc, tblArg)
   138  	case "current_account":
   139  		return currentAccountPrepare(proc, tblArg)
   140  	case "metadata_scan":
   141  		return metadataScanPrepare(proc, tblArg)
   142  	case "processlist":
   143  		return processlistPrepare(proc, tblArg)
   144  	case "mo_locks":
   145  		return moLocksPrepare(proc, tblArg)
   146  	case "mo_configurations":
   147  		return moConfigurationsPrepare(proc, tblArg)
   148  	case "mo_transactions":
   149  		return moTransactionsPrepare(proc, tblArg)
   150  	case "mo_cache":
   151  		return moCachePrepare(proc, tblArg)
   152  	default:
   153  		return moerr.NewNotSupported(proc.Ctx, fmt.Sprintf("table function %s is not supported", tblArg.FuncName))
   154  	}
   155  }
   156  
   157  func dupType(typ *plan.Type) types.Type {
   158  	return types.New(types.T(typ.Id), typ.Width, typ.Scale)
   159  }