github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/projection/projection.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 projection 16 17 import ( 18 "bytes" 19 20 "github.com/matrixorigin/matrixone/pkg/container/batch" 21 "github.com/matrixorigin/matrixone/pkg/container/vector" 22 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 23 "github.com/matrixorigin/matrixone/pkg/sql/plan" 24 "github.com/matrixorigin/matrixone/pkg/vm" 25 "github.com/matrixorigin/matrixone/pkg/vm/process" 26 ) 27 28 const argName = "projection" 29 30 func (arg *Argument) String(buf *bytes.Buffer) { 31 buf.WriteString(argName) 32 n := arg 33 buf.WriteString(": projection(") 34 for i, e := range n.Es { 35 if i > 0 { 36 buf.WriteString(",") 37 } 38 buf.WriteString(e.String()) 39 } 40 buf.WriteString(")") 41 } 42 43 func (arg *Argument) Prepare(proc *process.Process) (err error) { 44 ap := arg 45 ap.ctr = new(container) 46 ap.ctr.projExecutors, err = colexec.NewExpressionExecutorsFromPlanExpressions(proc, ap.Es) 47 ap.ctr.uafs = make([]func(v *vector.Vector, w *vector.Vector) error, len(ap.Es)) 48 for i, e := range ap.Es { 49 if e.Typ.Id != 0 { 50 ap.ctr.uafs[i] = vector.GetUnionAllFunction(plan.MakeTypeByPlan2Expr(e), proc.Mp()) 51 } 52 } 53 return err 54 } 55 56 func (arg *Argument) Call(proc *process.Process) (vm.CallResult, error) { 57 if err, isCancel := vm.CancelCheck(proc); isCancel { 58 return vm.CancelResult, err 59 } 60 61 result, err := arg.GetChildren(0).Call(proc) 62 if err != nil { 63 return result, err 64 } 65 66 anal := proc.GetAnalyze(arg.GetIdx(), arg.GetParallelIdx(), arg.GetParallelMajor()) 67 anal.Start() 68 defer anal.Stop() 69 70 if result.Batch == nil || result.Batch.IsEmpty() || result.Batch.Last() { 71 return result, nil 72 } 73 bat := result.Batch 74 anal.Input(bat, arg.GetIsFirst()) 75 76 if arg.buf != nil { 77 proc.PutBatch(arg.buf) 78 arg.buf = nil 79 } 80 81 arg.buf = batch.NewWithSize(len(arg.Es)) 82 // keep shuffleIDX unchanged 83 arg.buf.ShuffleIDX = bat.ShuffleIDX 84 // do projection. 85 for i := range arg.ctr.projExecutors { 86 vec, err := arg.ctr.projExecutors[i].Eval(proc, []*batch.Batch{bat}) 87 if err != nil { 88 for _, newV := range arg.buf.Vecs { 89 if newV != nil { 90 for k, oldV := range bat.Vecs { 91 if oldV != nil && newV == oldV { 92 bat.Vecs[k] = nil 93 } 94 } 95 } 96 } 97 arg.buf = nil 98 return result, err 99 } 100 arg.buf.Vecs[i] = vec 101 } 102 103 newAlloc, err := colexec.FixProjectionResult(proc, arg.ctr.projExecutors, arg.ctr.uafs, arg.buf, bat) 104 if err != nil { 105 return result, err 106 } 107 arg.maxAllocSize = max(arg.maxAllocSize, newAlloc) 108 arg.buf.SetRowCount(bat.RowCount()) 109 110 anal.Output(arg.buf, arg.GetIsLast()) 111 result.Batch = arg.buf 112 return result, nil 113 }