github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/mergeoffset/offset.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 mergeoffset 16 17 import ( 18 "bytes" 19 "fmt" 20 21 "github.com/matrixorigin/matrixone/pkg/vm" 22 "github.com/matrixorigin/matrixone/pkg/vm/process" 23 ) 24 25 const argName = "merge_offset" 26 27 func (arg *Argument) String(buf *bytes.Buffer) { 28 buf.WriteString(argName) 29 buf.WriteString(fmt.Sprintf("mergeOffset(%d)", arg.Offset)) 30 } 31 32 func (arg *Argument) Prepare(proc *process.Process) error { 33 ap := arg 34 ap.ctr = new(container) 35 ap.ctr.InitReceiver(proc, true) 36 ap.ctr.seen = 0 37 return nil 38 } 39 40 func (arg *Argument) Call(proc *process.Process) (vm.CallResult, error) { 41 if err, isCancel := vm.CancelCheck(proc); isCancel { 42 return vm.CancelResult, err 43 } 44 45 anal := proc.GetAnalyze(arg.GetIdx(), arg.GetParallelIdx(), arg.GetParallelMajor()) 46 anal.Start() 47 defer anal.Stop() 48 49 result := vm.NewCallResult() 50 var end bool 51 var err error 52 if arg.buf != nil { 53 proc.PutBatch(arg.buf) 54 arg.buf = nil 55 } 56 57 for { 58 arg.buf, end, err = arg.ctr.ReceiveFromAllRegs(anal) 59 if err != nil { 60 // WTF, nil? 61 result.Status = vm.ExecStop 62 return result, nil 63 } 64 65 if end { 66 result.Batch = nil 67 result.Status = vm.ExecStop 68 return result, nil 69 } 70 71 anal.Input(arg.buf, arg.GetIsFirst()) 72 if arg.ctr.seen > arg.Offset { 73 anal.Output(arg.buf, arg.GetIsLast()) 74 result.Batch = arg.buf 75 return result, nil 76 } 77 length := arg.buf.RowCount() 78 // bat = PartOne + PartTwo, and PartTwo is required. 79 if arg.ctr.seen+uint64(length) > arg.Offset { 80 sels := newSels(int64(arg.Offset-arg.ctr.seen), int64(length)-int64(arg.Offset-arg.ctr.seen), proc) 81 arg.ctr.seen += uint64(length) 82 arg.buf.Shrink(sels, false) 83 proc.Mp().PutSels(sels) 84 anal.Output(arg.buf, arg.GetIsLast()) 85 result.Batch = arg.buf 86 return result, nil 87 } 88 arg.ctr.seen += uint64(length) 89 proc.PutBatch(arg.buf) 90 } 91 } 92 93 func newSels(start, count int64, proc *process.Process) []int64 { 94 sels := proc.Mp().GetSels() 95 for i := int64(0); i < count; i++ { 96 sels = append(sels, start+i) 97 } 98 return sels[:count] 99 }