134 lines
3.8 KiB
Go
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
|
|
}
|