Files
tidb/planner/memo/pattern.go
2018-12-13 13:17:24 +08:00

134 lines
3.8 KiB
Go

// Copyright 2018 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package memo
import (
plannercore "github.com/pingcap/tidb/planner/core"
)
// Operand is the node of a pattern tree, it represents a logical expression operator.
// Different from logical plan operator which holds the full information about an expression
// operator, Operand only stores the type information.
// An Operand may correspond to a concrete logical plan operator, or it can has special meaning,
// e.g, a placeholder for any logical plan operator.
type Operand int
const (
// OperandAny is a placeholder for any Operand.
OperandAny Operand = iota
// OperandJoin for LogicalJoin.
OperandJoin
// OperandAggregation for LogicalAggregation.
OperandAggregation
// OperandProjection for LogicalProjection.
OperandProjection
// OperandSelection for LogicalSelection.
OperandSelection
// OperandApply for LogicalApply.
OperandApply
// OperandMaxOneRow for LogicalMaxOneRow.
OperandMaxOneRow
// OperandTableDual for LogicalTableDual.
OperandTableDual
// OperandDataSource for DataSource.
OperandDataSource
// OperandUnionScan for LogicalUnionScan.
OperandUnionScan
// OperandUnionAll for LogicalUnionAll.
OperandUnionAll
// OperandSort for LogicalSort.
OperandSort
// OperandTopN for LogicalTopN.
OperandTopN
// OperandLock for LogicalLock.
OperandLock
// OperandLimit for LogicalLimit.
OperandLimit
// OperandUnsupported is upper bound of defined Operand yet.
OperandUnsupported
)
// GetOperand maps logical plan operator to Operand.
func GetOperand(p plannercore.LogicalPlan) Operand {
switch p.(type) {
case *plannercore.LogicalJoin:
return OperandJoin
case *plannercore.LogicalAggregation:
return OperandAggregation
case *plannercore.LogicalProjection:
return OperandProjection
case *plannercore.LogicalSelection:
return OperandSelection
case *plannercore.LogicalApply:
return OperandApply
case *plannercore.LogicalMaxOneRow:
return OperandMaxOneRow
case *plannercore.LogicalTableDual:
return OperandTableDual
case *plannercore.DataSource:
return OperandDataSource
case *plannercore.LogicalUnionScan:
return OperandUnionScan
case *plannercore.LogicalUnionAll:
return OperandUnionAll
case *plannercore.LogicalSort:
return OperandSort
case *plannercore.LogicalTopN:
return OperandTopN
case *plannercore.LogicalLock:
return OperandLock
case *plannercore.LogicalLimit:
return OperandLimit
default:
return OperandUnsupported
}
}
// Match checks if current Operand matches specified one.
func (o Operand) Match(t Operand) bool {
if o == OperandAny || t == OperandAny {
return true
}
if o == t {
return true
}
return false
}
// Pattern defines the Match pattern for a rule.
// It describes a piece of logical expression.
// It's a tree-like structure and each node in the tree is an Operand.
type Pattern struct {
Operand
Children []*Pattern
}
// NewPattern creats a pattern node according to the Operand.
func NewPattern(operand Operand) *Pattern {
return &Pattern{Operand: operand}
}
// SetChildren sets the Children information for a pattern node.
func (p *Pattern) SetChildren(children ...*Pattern) {
p.Children = children
}
// BuildPattern builds a Pattern from Operand and child Patterns.
// Used in GetPattern() of Transformation interface to generate a Pattern.
func BuildPattern(operand Operand, children ...*Pattern) *Pattern {
p := &Pattern{Operand: operand}
p.Children = children
return p
}