github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/optimizer/plan/plan.go (about) 1 // Copyright 2015 PingCAP, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package plan 15 16 import ( 17 "math" 18 19 "github.com/insionng/yougam/libraries/pingcap/tidb/ast" 20 ) 21 22 // Plan is a description of an execution flow. 23 // It is created from ast.Node first, then optimized by optimizer, 24 // then used by executor to create a Cursor which executes the statement. 25 type Plan interface { 26 // Fields returns the result fields of the plan. 27 Fields() []*ast.ResultField 28 // SetFields sets the results fields of the plan. 29 SetFields(fields []*ast.ResultField) 30 // The cost before returning fhe first row. 31 StartupCost() float64 32 // The cost after returning all the rows. 33 TotalCost() float64 34 // The expected row count. 35 RowCount() float64 36 // SetLimit is used to push limit to upstream to estimate the cost. 37 SetLimit(limit float64) 38 // AddParent means append a parent for plan. 39 AddParent(parent Plan) 40 // AddChild means append a child for plan. 41 AddChild(children Plan) 42 // ReplaceParent means replace a parent with another one. 43 ReplaceParent(parent, newPar Plan) error 44 // ReplaceChild means replace a child with another one. 45 ReplaceChild(children, newChild Plan) error 46 // Retrieve parent by index. 47 GetParentByIndex(index int) Plan 48 // Retrieve child by index. 49 GetChildByIndex(index int) Plan 50 // Get all the parents. 51 GetParents() []Plan 52 // Get all the children. 53 GetChildren() []Plan 54 } 55 56 // basePlan implements base Plan interface. 57 // Should be used as embedded struct in Plan implementations. 58 type basePlan struct { 59 fields []*ast.ResultField 60 startupCost float64 61 totalCost float64 62 rowCount float64 63 limit float64 64 65 parents []Plan 66 children []Plan 67 } 68 69 // StartupCost implements Plan StartupCost interface. 70 func (p *basePlan) StartupCost() float64 { 71 return p.startupCost 72 } 73 74 // TotalCost implements Plan TotalCost interface. 75 func (p *basePlan) TotalCost() float64 { 76 return p.totalCost 77 } 78 79 // RowCount implements Plan RowCount interface. 80 func (p *basePlan) RowCount() float64 { 81 if p.limit == 0 { 82 return p.rowCount 83 } 84 return math.Min(p.rowCount, p.limit) 85 } 86 87 // SetLimit implements Plan SetLimit interface. 88 func (p *basePlan) SetLimit(limit float64) { 89 p.limit = limit 90 } 91 92 // Fields implements Plan Fields interface. 93 func (p *basePlan) Fields() []*ast.ResultField { 94 return p.fields 95 } 96 97 // SetFields implements Plan SetFields interface. 98 func (p *basePlan) SetFields(fields []*ast.ResultField) { 99 p.fields = fields 100 } 101 102 // AddParent implements Plan AddParent interface. 103 func (p *basePlan) AddParent(parent Plan) { 104 p.parents = append(p.parents, parent) 105 } 106 107 // AddChild implements Plan AddChild interface. 108 func (p *basePlan) AddChild(child Plan) { 109 p.children = append(p.children, child) 110 } 111 112 // ReplaceParent means replace a parent for another one. 113 func (p *basePlan) ReplaceParent(parent, newPar Plan) error { 114 for i, par := range p.parents { 115 if par == parent { 116 p.parents[i] = newPar 117 return nil 118 } 119 } 120 return SystemInternalErrorType.Gen("RemoveParent Failed!") 121 } 122 123 // ReplaceChild means replace a child with another one. 124 func (p *basePlan) ReplaceChild(child, newChild Plan) error { 125 for i, ch := range p.children { 126 if ch == child { 127 p.children[i] = newChild 128 return nil 129 } 130 } 131 return SystemInternalErrorType.Gen("RemoveChildren Failed!") 132 } 133 134 // GetParentByIndex implements Plan GetParentByIndex interface. 135 func (p *basePlan) GetParentByIndex(index int) (parent Plan) { 136 if index < len(p.parents) && index >= 0 { 137 return p.parents[index] 138 } 139 return nil 140 } 141 142 // GetChildByIndex implements Plan GetChildByIndex interface. 143 func (p *basePlan) GetChildByIndex(index int) (parent Plan) { 144 if index < len(p.children) && index >= 0 { 145 return p.children[index] 146 } 147 return nil 148 } 149 150 // GetParents implements Plan GetParents interface. 151 func (p *basePlan) GetParents() []Plan { 152 return p.parents 153 } 154 155 // GetChildren implements Plan GetChildren interface. 156 func (p *basePlan) GetChildren() []Plan { 157 return p.children 158 }