github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/pipeline/types.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 pipeline 16 17 import ( 18 "reflect" 19 20 "github.com/matrixorigin/matrixone/pkg/container/batch" 21 "github.com/matrixorigin/matrixone/pkg/vm" 22 "github.com/matrixorigin/matrixone/pkg/vm/process" 23 ) 24 25 // Pipeline contains the information associated with a pipeline in a query execution plan. 26 // A query execution plan may contains one or more pipelines. 27 // As an example: 28 // 29 // CREATE TABLE order 30 // ( 31 // order_id INT, 32 // uid INT, 33 // item_id INT, 34 // year INT, 35 // nation VARCHAR(100) 36 // ); 37 // 38 // CREATE TABLE customer 39 // ( 40 // uid INT, 41 // nation VARCHAR(100), 42 // city VARCHAR(100) 43 // ); 44 // 45 // CREATE TABLE supplier 46 // ( 47 // item_id INT, 48 // nation VARCHAR(100), 49 // city VARCHAR(100) 50 // ); 51 // 52 // SELECT c.city, s.city, sum(o.revenue) AS revenue 53 // FROM customer c, order o, supplier s 54 // WHERE o.uid = c.uid 55 // AND o.item_id = s.item_id 56 // AND c.nation = 'CHINA' 57 // AND s.nation = 'CHINA' 58 // AND o.year >= 1992 and o.year <= 1997 59 // GROUP BY c.city, s.city, o.year 60 // ORDER BY o.year asc, revenue desc; 61 // 62 // AST PLAN: 63 // order 64 // | 65 // group 66 // | 67 // filter 68 // | 69 // join 70 // / \ 71 // s join 72 // / \ 73 // l c 74 // 75 // In this example, a possible pipeline is as follows: 76 // 77 // pipeline: 78 // o ⨝ c ⨝ s 79 // 80 // -> σ(c.nation = 'CHINA' ∧ o.year >= 1992 ∧ o.year <= 1997 ∧ s.nation = 'CHINA') 81 // -> γ([c.city, s.city, o.year, sum(o.revenue) as revenue], c.city, s.city, o.year) 82 // -> τ(o.year asc, revenue desc) 83 // -> π(c.city, s.city, revenue) 84 type Pipeline struct { 85 // attrs, column list. 86 attrs []string 87 // orders to be executed 88 instructions vm.Instructions 89 reg *process.WaitRegister 90 } 91 92 // cleanup do memory release work for whole pipeline. 93 func (p *Pipeline) cleanup(proc *process.Process, pipelineFailed bool) { 94 // clean all the coming batches. 95 if pipelineFailed { 96 bat := proc.InputBatch() 97 if bat != nil { 98 bat.Clean(proc.Mp()) 99 } 100 proc.SetInputBatch(nil) 101 } 102 // clean operator hold memory. 103 for i := range p.instructions { 104 p.instructions[i].Arg.Free(proc, pipelineFailed) 105 } 106 107 // select all merge receivers 108 listeners, alive := newSelectListener(proc.Reg.MergeReceivers) 109 for alive != 0 { 110 chosen, value, ok := reflect.Select(listeners) 111 if !ok { 112 break 113 } 114 pointer := value.UnsafePointer() 115 bat := (*batch.Batch)(pointer) 116 if bat == nil { 117 alive-- 118 listeners = append(listeners[:chosen], listeners[chosen+1:]...) 119 continue 120 } 121 bat.Clean(proc.Mp()) 122 } 123 } 124 125 func newSelectListener(wrs []*process.WaitRegister) ([]reflect.SelectCase, int) { 126 listener := make([]reflect.SelectCase, len(wrs)) 127 for i, mr := range wrs { 128 listener[i] = reflect.SelectCase{ 129 Dir: reflect.SelectRecv, 130 Chan: reflect.ValueOf(mr.Ch), 131 } 132 } 133 return listener, len(wrs) 134 }