github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/ctl/ctl.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 ctl 16 17 import ( 18 "context" 19 "strings" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/container/vector" 24 "github.com/matrixorigin/matrixone/pkg/pb/txn" 25 "github.com/matrixorigin/matrixone/pkg/txn/client" 26 "github.com/matrixorigin/matrixone/pkg/util/json" 27 "github.com/matrixorigin/matrixone/pkg/vm/process" 28 ) 29 30 // Handler used to handle mo_debug SQL function. 31 // Format of the function: mo_debug('service name', 'command', 'command parameter') 32 // service name: [CN|DN|LOG|HAKEEPER] 33 // command: command in supportedCmds 34 // command parameter: the parameter of the command 35 func Handler(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 36 service := serviceType(strings.ToUpper(vector.MustStrCols(vs[0])[0])) 37 command := strings.ToUpper(vector.MustStrCols(vs[1])[0]) 38 parameter := vector.MustStrCols(vs[2])[0] 39 40 if _, ok := supportedServiceTypes[service]; !ok { 41 return nil, moerr.NewNotSupported(proc.Ctx, "service type %s not supported", service) 42 } 43 44 f, ok := supportedCmds[command] 45 if !ok { 46 return nil, moerr.NewNotSupported(proc.Ctx, "command %s not supported", command) 47 } 48 49 result, err := f(proc, 50 service, 51 parameter, 52 // We use a transaction client to send debug requests with the following in mind. 53 // 1. reuse the RPC mechanism of cn and dn 54 // 2. may support debug support for transactions in the future, such as testing the 55 // correctness of the transaction by forcing the timestamp of the transaction to 56 // be modified, etc. 57 // TODO: add more ut tests for this. 58 func(ctx context.Context, requests []txn.CNOpRequest) ([]txn.CNOpResponse, error) { 59 txnOp := proc.TxnOperator 60 if txnOp == nil { 61 v, err := proc.TxnClient.New() 62 if err != nil { 63 return nil, err 64 } 65 txnOp = v 66 defer func() { 67 _ = txnOp.Commit(proc.Ctx) 68 }() 69 } 70 op, ok := txnOp.(client.DebugableTxnOperator) 71 if !ok { 72 return nil, moerr.NewNotSupported(proc.Ctx, "debug function not supported") 73 } 74 75 debugRequests := make([]txn.TxnRequest, 0, len(requests)) 76 for _, req := range requests { 77 tq := txn.NewTxnRequest(&req) 78 tq.Method = txn.TxnMethod_DEBUG 79 debugRequests = append(debugRequests, tq) 80 } 81 result, err := op.Debug(ctx, debugRequests) 82 if err != nil { 83 return nil, err 84 } 85 defer result.Release() 86 87 responses := make([]txn.CNOpResponse, 0, len(requests)) 88 for _, resp := range result.Responses { 89 responses = append(responses, *resp.CNOpResponse) 90 } 91 return responses, nil 92 }) 93 if err != nil { 94 return nil, err 95 } 96 97 value := vector.New(types.New(types.T_varchar, types.MaxVarcharLen, 0, 0)) 98 if err := value.Append(json.Pretty(result), false, proc.Mp()); err != nil { 99 return nil, err 100 } 101 return value, nil 102 }