github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/vm.go (about) 1 // Copyright 2021 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 vm 16 17 import ( 18 "bytes" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/logutil" 22 "github.com/matrixorigin/matrixone/pkg/vm/process" 23 ) 24 25 func (ins *Instruction) MarshalBinary() ([]byte, error) { 26 return nil, nil 27 } 28 29 func (ins *Instruction) UnmarshalBinary(_ []byte) error { 30 return nil 31 } 32 33 // String range instructions and call each operator's string function to show a query plan 34 func String(ins Instructions, buf *bytes.Buffer) { 35 for i, in := range ins { 36 if i > 0 { 37 buf.WriteString(" -> ") 38 } 39 in.Arg.String(buf) 40 } 41 } 42 43 // Prepare range instructions and do init work for each operator's argument by calling its prepare function 44 func Prepare(ins Instructions, proc *process.Process) error { 45 for _, in := range ins { 46 if err := in.Arg.Prepare(proc); err != nil { 47 return err 48 } 49 } 50 return nil 51 } 52 53 func setAnalyzeInfo(ins Instructions, proc *process.Process) { 54 for i := 0; i < len(ins); i++ { 55 switch ins[i].Op { 56 case Output: 57 ins[i].Idx = -1 58 case TableScan: 59 ins[i].Idx = ins[i+1].Idx 60 } 61 } 62 63 idxMapMajor := make(map[int]int, 0) 64 idxMapMinor := make(map[int]int, 0) 65 for i := 0; i < len(ins); i++ { 66 info := &OperatorInfo{ 67 Idx: ins[i].Idx, 68 IsFirst: ins[i].IsFirst, 69 IsLast: ins[i].IsLast, 70 71 CnAddr: ins[i].CnAddr, 72 OperatorID: ins[i].OperatorID, 73 ParallelID: ins[i].ParallelID, 74 MaxParallel: ins[i].MaxParallel, 75 } 76 switch ins[i].Op { 77 case HashBuild, Restrict, MergeGroup, MergeOrder: 78 isMinor := true 79 if ins[i].Op == Restrict { 80 if ins[0].Op != TableScan && ins[0].Op != External { 81 isMinor = false // restrict operator is minor only for scan 82 } 83 } 84 85 if isMinor { 86 if info.Idx >= 0 && info.Idx < len(proc.AnalInfos) { 87 info.ParallelMajor = false 88 if pidx, ok := idxMapMinor[info.Idx]; ok { 89 info.ParallelIdx = pidx 90 } else { 91 pidx = proc.AnalInfos[info.Idx].AddNewParallel(false) 92 idxMapMinor[info.Idx] = pidx 93 info.ParallelIdx = pidx 94 } 95 } 96 } else { 97 info.ParallelIdx = -1 98 } 99 100 case TableScan, External, Order, Window, Group, Join, LoopJoin, Left, LoopLeft, Single, LoopSingle, Semi, RightSemi, LoopSemi, Anti, RightAnti, LoopAnti, Mark, LoopMark, Product: 101 info.ParallelMajor = true 102 if info.Idx >= 0 && info.Idx < len(proc.AnalInfos) { 103 if pidx, ok := idxMapMajor[info.Idx]; ok { 104 info.ParallelIdx = pidx 105 } else { 106 pidx = proc.AnalInfos[info.Idx].AddNewParallel(true) 107 idxMapMajor[info.Idx] = pidx 108 info.ParallelIdx = pidx 109 } 110 } 111 default: 112 info.ParallelIdx = -1 // do nothing for parallel analyze info 113 } 114 ins[i].Arg.SetInfo(info) 115 } 116 } 117 118 func Run(ins Instructions, proc *process.Process) (end bool, err error) { 119 defer func() { 120 if e := recover(); e != nil { 121 err = moerr.ConvertPanicError(proc.Ctx, e) 122 logutil.Errorf("panic in vm.Run: %v", err) 123 } 124 }() 125 126 setAnalyzeInfo(ins, proc) 127 128 for i := 1; i < len(ins); i++ { 129 ins[i].Arg.AppendChild(ins[i-1].Arg) 130 } 131 132 root := ins[len(ins)-1].Arg 133 end = false 134 for !end { 135 result, err := root.Call(proc) 136 if err != nil { 137 return true, err 138 } 139 end = result.Status == ExecStop || result.Batch == nil 140 } 141 return end, nil 142 }