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  }