From 21f738e58b47b54d097d67a8a8b4b4be4d4f6c2c Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Tue, 26 Mar 2024 20:09:36 +0800 Subject: [PATCH 1/3] refactor pattern dir output memo related logic Signed-off-by: AilinKid <314806019@qq.com> --- pkg/planner/cascades/BUILD.bazel | 2 + pkg/planner/cascades/enforcer_rules.go | 3 +- pkg/planner/cascades/implementation_rules.go | 51 +-- pkg/planner/cascades/optimize.go | 9 +- pkg/planner/cascades/optimize_test.go | 11 +- pkg/planner/cascades/stringer_test.go | 7 +- pkg/planner/cascades/transformation_rules.go | 317 +++++++++--------- .../cascades/transformation_rules_test.go | 91 ++--- pkg/planner/memo/BUILD.bazel | 6 +- pkg/planner/memo/expr_iterator.go | 19 +- pkg/planner/memo/expr_iterator_test.go | 117 ++++--- pkg/planner/memo/group.go | 72 +--- pkg/planner/memo/group_test.go | 43 +-- pkg/planner/pattern/BUILD.bazel | 28 ++ pkg/planner/pattern/engine.go | 64 ++++ pkg/planner/pattern/engine_test.go | 43 +++ pkg/planner/{memo => pattern}/pattern.go | 4 +- pkg/planner/{memo => pattern}/pattern_test.go | 2 +- 18 files changed, 491 insertions(+), 398 deletions(-) create mode 100644 pkg/planner/pattern/BUILD.bazel create mode 100644 pkg/planner/pattern/engine.go create mode 100644 pkg/planner/pattern/engine_test.go rename pkg/planner/{memo => pattern}/pattern.go (99%) rename pkg/planner/{memo => pattern}/pattern_test.go (99%) diff --git a/pkg/planner/cascades/BUILD.bazel b/pkg/planner/cascades/BUILD.bazel index 0105b9a459ffa..25d33ca880bfe 100644 --- a/pkg/planner/cascades/BUILD.bazel +++ b/pkg/planner/cascades/BUILD.bazel @@ -21,6 +21,7 @@ go_library( "//pkg/planner/core", "//pkg/planner/implementation", "//pkg/planner/memo", + "//pkg/planner/pattern", "//pkg/planner/property", "//pkg/planner/util", "//pkg/types", @@ -52,6 +53,7 @@ go_test( "//pkg/parser/model", "//pkg/planner/core", "//pkg/planner/memo", + "//pkg/planner/pattern", "//pkg/planner/property", "//pkg/testkit/testdata", "//pkg/testkit/testsetup", diff --git a/pkg/planner/cascades/enforcer_rules.go b/pkg/planner/cascades/enforcer_rules.go index 19e96ce5a439d..1a41c3f895b3b 100644 --- a/pkg/planner/cascades/enforcer_rules.go +++ b/pkg/planner/cascades/enforcer_rules.go @@ -15,6 +15,7 @@ package cascades import ( + "github.com/pingcap/tidb/pkg/planner/pattern" "math" plannercore "github.com/pingcap/tidb/pkg/planner/core" @@ -38,7 +39,7 @@ type Enforcer interface { // GetEnforcerRules gets all candidate enforcer rules based // on required physical property. func GetEnforcerRules(g *memo.Group, prop *property.PhysicalProperty) (enforcers []Enforcer) { - if g.EngineType != memo.EngineTiDB { + if g.EngineType != pattern.EngineTiDB { return } if !prop.IsSortItemEmpty() { diff --git a/pkg/planner/cascades/implementation_rules.go b/pkg/planner/cascades/implementation_rules.go index f4f865076a79d..9b1485b406e34 100644 --- a/pkg/planner/cascades/implementation_rules.go +++ b/pkg/planner/cascades/implementation_rules.go @@ -15,6 +15,7 @@ package cascades import ( + "github.com/pingcap/tidb/pkg/planner/pattern" "math" "github.com/pingcap/tidb/pkg/expression" @@ -34,59 +35,59 @@ type ImplementationRule interface { OnImplement(expr *memo.GroupExpr, reqProp *property.PhysicalProperty) ([]memo.Implementation, error) } -var defaultImplementationMap = map[memo.Operand][]ImplementationRule{ - memo.OperandTableDual: { +var defaultImplementationMap = map[pattern.Operand][]ImplementationRule{ + pattern.OperandTableDual: { &ImplTableDual{}, }, - memo.OperandMemTableScan: { + pattern.OperandMemTableScan: { &ImplMemTableScan{}, }, - memo.OperandProjection: { + pattern.OperandProjection: { &ImplProjection{}, }, - memo.OperandTableScan: { + pattern.OperandTableScan: { &ImplTableScan{}, }, - memo.OperandIndexScan: { + pattern.OperandIndexScan: { &ImplIndexScan{}, }, - memo.OperandTiKVSingleGather: { + pattern.OperandTiKVSingleGather: { &ImplTiKVSingleReadGather{}, }, - memo.OperandShow: { + pattern.OperandShow: { &ImplShow{}, }, - memo.OperandSelection: { + pattern.OperandSelection: { &ImplSelection{}, }, - memo.OperandSort: { + pattern.OperandSort: { &ImplSort{}, }, - memo.OperandAggregation: { + pattern.OperandAggregation: { &ImplHashAgg{}, }, - memo.OperandLimit: { + pattern.OperandLimit: { &ImplLimit{}, }, - memo.OperandTopN: { + pattern.OperandTopN: { &ImplTopN{}, &ImplTopNAsLimit{}, }, - memo.OperandJoin: { + pattern.OperandJoin: { &ImplHashJoinBuildLeft{}, &ImplHashJoinBuildRight{}, &ImplMergeJoin{}, }, - memo.OperandUnionAll: { + pattern.OperandUnionAll: { &ImplUnionAll{}, }, - memo.OperandApply: { + pattern.OperandApply: { &ImplApply{}, }, - memo.OperandMaxOneRow: { + pattern.OperandMaxOneRow: { &ImplMaxOneRow{}, }, - memo.OperandWindow: { + pattern.OperandWindow: { &ImplWindow{}, }, } @@ -272,9 +273,9 @@ func (*ImplSelection) OnImplement(expr *memo.GroupExpr, reqProp *property.Physic Conditions: logicalSel.Conditions, }.Init(logicalSel.SCtx(), expr.Group.Prop.Stats.ScaleByExpectCnt(reqProp.ExpectedCnt), logicalSel.QueryBlockOffset(), reqProp.CloneEssentialFields()) switch expr.Group.EngineType { - case memo.EngineTiDB: + case pattern.EngineTiDB: return []memo.Implementation{impl.NewTiDBSelectionImpl(physicalSel)}, nil - case memo.EngineTiKV: + case pattern.EngineTiKV: return []memo.Implementation{impl.NewTiKVSelectionImpl(physicalSel)}, nil default: return nil, plannererrors.ErrInternal.GenWithStack("Unsupported EngineType '%s' for Selection.", expr.Group.EngineType.String()) @@ -333,9 +334,9 @@ func (*ImplHashAgg) OnImplement(expr *memo.GroupExpr, reqProp *property.Physical ) hashAgg.SetSchema(expr.Group.Prop.Schema.Clone()) switch expr.Group.EngineType { - case memo.EngineTiDB: + case pattern.EngineTiDB: return []memo.Implementation{impl.NewTiDBHashAggImpl(hashAgg)}, nil - case memo.EngineTiKV: + case pattern.EngineTiKV: return []memo.Implementation{impl.NewTiKVHashAggImpl(hashAgg)}, nil default: return nil, plannererrors.ErrInternal.GenWithStack("Unsupported EngineType '%s' for HashAggregation.", expr.Group.EngineType.String()) @@ -372,7 +373,7 @@ type ImplTopN struct { // Match implements ImplementationRule Match interface. func (*ImplTopN) Match(expr *memo.GroupExpr, prop *property.PhysicalProperty) (matched bool) { topN := expr.ExprNode.(*plannercore.LogicalTopN) - if expr.Group.EngineType != memo.EngineTiDB { + if expr.Group.EngineType != pattern.EngineTiDB { return prop.IsSortItemEmpty() } return plannercore.MatchItems(prop, topN.ByItems) @@ -388,9 +389,9 @@ func (*ImplTopN) OnImplement(expr *memo.GroupExpr, _ *property.PhysicalProperty) Offset: lt.Offset, }.Init(lt.SCtx(), expr.Group.Prop.Stats, lt.QueryBlockOffset(), resultProp) switch expr.Group.EngineType { - case memo.EngineTiDB: + case pattern.EngineTiDB: return []memo.Implementation{impl.NewTiDBTopNImpl(topN)}, nil - case memo.EngineTiKV: + case pattern.EngineTiKV: return []memo.Implementation{impl.NewTiKVTopNImpl(topN)}, nil default: return nil, plannererrors.ErrInternal.GenWithStack("Unsupported EngineType '%s' for TopN.", expr.Group.EngineType.String()) diff --git a/pkg/planner/cascades/optimize.go b/pkg/planner/cascades/optimize.go index 5d20ab2f0c782..d685540623cf9 100644 --- a/pkg/planner/cascades/optimize.go +++ b/pkg/planner/cascades/optimize.go @@ -16,6 +16,7 @@ package cascades import ( "container/list" + "github.com/pingcap/tidb/pkg/planner/pattern" "math" "github.com/pingcap/tidb/pkg/expression" @@ -32,7 +33,7 @@ var DefaultOptimizer = NewOptimizer() // Optimizer is the struct for cascades optimizer. type Optimizer struct { transformationRuleBatches []TransformationRuleBatch - implementationRuleMap map[memo.Operand][]ImplementationRule + implementationRuleMap map[pattern.Operand][]ImplementationRule } // NewOptimizer returns a cascades optimizer with default transformation @@ -51,7 +52,7 @@ func (opt *Optimizer) ResetTransformationRules(ruleBatches ...TransformationRule } // ResetImplementationRules resets the implementationRuleMap of the optimizer, and returns the optimizer. -func (opt *Optimizer) ResetImplementationRules(rules map[memo.Operand][]ImplementationRule) *Optimizer { +func (opt *Optimizer) ResetImplementationRules(rules map[pattern.Operand][]ImplementationRule) *Optimizer { opt.implementationRuleMap = rules return opt } @@ -59,7 +60,7 @@ func (opt *Optimizer) ResetImplementationRules(rules map[memo.Operand][]Implemen // GetImplementationRules gets all the candidate implementation rules of the optimizer // for the logical plan node. func (opt *Optimizer) GetImplementationRules(node plannercore.LogicalPlan) []ImplementationRule { - return opt.implementationRuleMap[memo.GetOperand(node)] + return opt.implementationRuleMap[pattern.GetOperand(node)] } // FindBestPlan is the optimization entrance of the cascades planner. The @@ -172,7 +173,7 @@ func (opt *Optimizer) exploreGroup(g *memo.Group, round int, ruleBatch Transform // findMoreEquiv finds and applies the matched transformation rules. func (*Optimizer) findMoreEquiv(g *memo.Group, elem *list.Element, round int, ruleBatch TransformationRuleBatch) (eraseCur bool, err error) { expr := elem.Value.(*memo.GroupExpr) - operand := memo.GetOperand(expr.ExprNode) + operand := pattern.GetOperand(expr.ExprNode) for _, rule := range ruleBatch[operand] { pattern := rule.GetPattern() if !pattern.Operand.Match(operand) { diff --git a/pkg/planner/cascades/optimize_test.go b/pkg/planner/cascades/optimize_test.go index 49abd0c6e64df..a947b7a16537d 100644 --- a/pkg/planner/cascades/optimize_test.go +++ b/pkg/planner/cascades/optimize_test.go @@ -16,6 +16,7 @@ package cascades import ( "context" + "github.com/pingcap/tidb/pkg/planner/pattern" "math" "testing" @@ -116,8 +117,8 @@ func TestPreparePossibleProperties(t *testing.T) { domain.GetDomain(ctx).MockInfoCacheAndLoadInfoSchema(is) optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandDataSource: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }) @@ -212,9 +213,9 @@ func TestAppliedRuleSet(t *testing.T) { optimizer := NewOptimizer() rule := fakeTransformation{} - rule.pattern = memo.NewPattern(memo.OperandProjection, memo.EngineAll) - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandProjection: { + rule.pattern = pattern.NewPattern(pattern.OperandProjection, memo.EngineAll) + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandProjection: { &rule, }, }) diff --git a/pkg/planner/cascades/stringer_test.go b/pkg/planner/cascades/stringer_test.go index 14359e6de8cf1..768f2ff92258f 100644 --- a/pkg/planner/cascades/stringer_test.go +++ b/pkg/planner/cascades/stringer_test.go @@ -16,6 +16,7 @@ package cascades import ( "context" + "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -30,12 +31,12 @@ import ( func TestGroupStringer(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandSelection: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandSelection: { NewRulePushSelDownTiKVSingleGather(), NewRulePushSelDownTableScan(), }, - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }) diff --git a/pkg/planner/cascades/transformation_rules.go b/pkg/planner/cascades/transformation_rules.go index 4b32d6b10da10..c09eeeb56cc3f 100644 --- a/pkg/planner/cascades/transformation_rules.go +++ b/pkg/planner/cascades/transformation_rules.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/tidb/pkg/planner/context" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/util" "github.com/pingcap/tidb/pkg/types" "github.com/pingcap/tidb/pkg/util/ranger" @@ -34,7 +35,7 @@ import ( // Transformation defines the interface for the transformation rules. type Transformation interface { // GetPattern gets the cached pattern of the rule. - GetPattern() *memo.Pattern + GetPattern() *pattern.Pattern // Match is used to check whether the GroupExpr satisfies all the requirements of the transformation rule. // // The pattern only identifies the operator type, some transformation rules also need @@ -53,7 +54,7 @@ type Transformation interface { } // TransformationRuleBatch is a batch of transformation rules. -type TransformationRuleBatch map[memo.Operand][]Transformation +type TransformationRuleBatch map[pattern.Operand][]Transformation // DefaultRuleBatches contain all the transformation rules. // Each batch will be applied to the memo independently. @@ -65,7 +66,7 @@ var DefaultRuleBatches = []TransformationRuleBatch{ // TiDBLayerOptimizationBatch does the optimization in the TiDB layer. var TiDBLayerOptimizationBatch = TransformationRuleBatch{ - memo.OperandSelection: { + pattern.OperandSelection: { NewRulePushSelDownSort(), NewRulePushSelDownProjection(), NewRulePushSelDownAggregation(), @@ -74,14 +75,14 @@ var TiDBLayerOptimizationBatch = TransformationRuleBatch{ NewRulePushSelDownWindow(), NewRuleMergeAdjacentSelection(), }, - memo.OperandAggregation: { + pattern.OperandAggregation: { NewRuleMergeAggregationProjection(), NewRuleEliminateSingleMaxMin(), NewRuleEliminateOuterJoinBelowAggregation(), NewRuleTransformAggregateCaseToSelection(), NewRuleTransformAggToProj(), }, - memo.OperandLimit: { + pattern.OperandLimit: { NewRuleTransformLimitToTopN(), NewRulePushLimitDownProjection(), NewRulePushLimitDownUnionAll(), @@ -89,25 +90,25 @@ var TiDBLayerOptimizationBatch = TransformationRuleBatch{ NewRuleMergeAdjacentLimit(), NewRuleTransformLimitToTableDual(), }, - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleEliminateProjection(), NewRuleMergeAdjacentProjection(), NewRuleEliminateOuterJoinBelowProjection(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRulePushTopNDownProjection(), NewRulePushTopNDownOuterJoin(), NewRulePushTopNDownUnionAll(), NewRuleMergeAdjacentTopN(), }, - memo.OperandApply: { + pattern.OperandApply: { NewRuleTransformApplyToJoin(), NewRulePullSelectionUpApply(), }, - memo.OperandJoin: { + pattern.OperandJoin: { NewRuleTransformJoinCondToSel(), }, - memo.OperandWindow: { + pattern.OperandWindow: { NewRuleMergeAdjacentWindow(), }, } @@ -116,22 +117,22 @@ var TiDBLayerOptimizationBatch = TransformationRuleBatch{ // For example, rules about pushing down Operators like Selection, Limit, // Aggregation into TiKV layer should be inside this batch. var TiKVLayerOptimizationBatch = TransformationRuleBatch{ - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, - memo.OperandSelection: { + pattern.OperandSelection: { NewRulePushSelDownTiKVSingleGather(), NewRulePushSelDownTableScan(), NewRulePushSelDownIndexScan(), NewRuleMergeAdjacentSelection(), }, - memo.OperandAggregation: { + pattern.OperandAggregation: { NewRulePushAggDownGather(), }, - memo.OperandLimit: { + pattern.OperandLimit: { NewRulePushLimitDownTiKVSingleGather(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRulePushTopNDownTiKVSingleGather(), }, } @@ -142,20 +143,20 @@ var TiKVLayerOptimizationBatch = TransformationRuleBatch{ // as for scalar functions, we need to inject a Projection for them // below the TopN/Sort. var PostTransformationBatch = TransformationRuleBatch{ - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleEliminateProjection(), NewRuleMergeAdjacentProjection(), }, - memo.OperandAggregation: { + pattern.OperandAggregation: { NewRuleInjectProjectionBelowAgg(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRuleInjectProjectionBelowTopN(), }, } type baseRule struct { - pattern *memo.Pattern + pattern *pattern.Pattern } // Match implements Transformation Interface. @@ -164,7 +165,7 @@ func (*baseRule) Match(_ *memo.ExprIter) bool { } // GetPattern implements Transformation Interface. -func (r *baseRule) GetPattern() *memo.Pattern { +func (r *baseRule) GetPattern() *pattern.Pattern { return r.pattern } @@ -177,8 +178,8 @@ type PushSelDownTableScan struct { // The pattern of this rule is: `Selection -> TableScan` func NewRulePushSelDownTableScan() Transformation { rule := &PushSelDownTableScan{} - ts := memo.NewPattern(memo.OperandTableScan, memo.EngineTiKVOrTiFlash) - p := memo.BuildPattern(memo.OperandSelection, memo.EngineTiKVOrTiFlash, ts) + ts := pattern.NewPattern(pattern.OperandTableScan, pattern.EngineTiKVOrTiFlash) + p := pattern.BuildPattern(pattern.OperandSelection, pattern.EngineTiKVOrTiFlash, ts) rule.pattern = p return rule } @@ -230,10 +231,10 @@ type PushSelDownIndexScan struct { // The pattern of this rule is `Selection -> IndexScan`. func NewRulePushSelDownIndexScan() Transformation { rule := &PushSelDownIndexScan{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiKVOnly, - memo.NewPattern(memo.OperandIndexScan, memo.EngineTiKVOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiKVOnly, + pattern.NewPattern(pattern.OperandIndexScan, pattern.EngineTiKVOnly), ) return rule } @@ -311,9 +312,9 @@ type PushSelDownTiKVSingleGather struct { // NewRulePushSelDownTiKVSingleGather creates a new Transformation PushSelDownTiKVSingleGather. // The pattern of this rule is `Selection -> TiKVSingleGather -> Any`. func NewRulePushSelDownTiKVSingleGather() Transformation { - any1 := memo.NewPattern(memo.OperandAny, memo.EngineTiKVOrTiFlash) - tg := memo.BuildPattern(memo.OperandTiKVSingleGather, memo.EngineTiDBOnly, any1) - p := memo.BuildPattern(memo.OperandSelection, memo.EngineTiDBOnly, tg) + any1 := pattern.NewPattern(pattern.OperandAny, pattern.EngineTiKVOrTiFlash) + tg := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, any1) + p := pattern.BuildPattern(pattern.OperandSelection, pattern.EngineTiDBOnly, tg) rule := &PushSelDownTiKVSingleGather{} rule.pattern = p @@ -367,7 +368,7 @@ type EnumeratePaths struct { // The pattern of this rule is: `DataSource`. func NewRuleEnumeratePaths() Transformation { rule := &EnumeratePaths{} - rule.pattern = memo.NewPattern(memo.OperandDataSource, memo.EngineTiDBOnly) + rule.pattern = pattern.NewPattern(pattern.OperandDataSource, pattern.EngineTiDBOnly) return rule } @@ -377,7 +378,7 @@ func (*EnumeratePaths) OnTransform(old *memo.ExprIter) (newExprs []*memo.GroupEx gathers := ds.Convert2Gathers() for _, gather := range gathers { expr := memo.Convert2GroupExpr(gather) - expr.Children[0].SetEngineType(memo.EngineTiKV) + expr.Children[0].SetEngineType(pattern.EngineTiKV) newExprs = append(newExprs, expr) } return newExprs, true, false, nil @@ -393,10 +394,10 @@ type PushAggDownGather struct { // The pattern of this rule is: `Aggregation -> TiKVSingleGather`. func NewRulePushAggDownGather() Transformation { rule := &PushAggDownGather{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandTiKVSingleGather, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly), ) return rule } @@ -420,7 +421,7 @@ func (r *PushAggDownGather) Match(expr *memo.ExprIter) bool { } } childEngine := expr.Children[0].GetExpr().Children[0].EngineType - if childEngine != memo.EngineTiKV { + if childEngine != pattern.EngineTiKV { // TODO: Remove this check when we have implemented TiFlashAggregation. return false } @@ -491,10 +492,10 @@ type PushSelDownSort struct { // The pattern of this rule is: `Selection -> Sort`. func NewRulePushSelDownSort() Transformation { rule := &PushSelDownSort{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandSort, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandSort, pattern.EngineTiDBOnly), ) return rule } @@ -524,10 +525,10 @@ type PushSelDownProjection struct { // The pattern of this rule is: `Selection -> Projection`. func NewRulePushSelDownProjection() Transformation { rule := &PushSelDownProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandProjection, pattern.EngineTiDBOnly), ) return rule } @@ -586,10 +587,10 @@ type PushSelDownAggregation struct { // The pattern of this rule is `Selection -> Aggregation`. func NewRulePushSelDownAggregation() Transformation { rule := &PushSelDownAggregation{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineAll, - memo.NewPattern(memo.OperandAggregation, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineAll, + pattern.NewPattern(pattern.OperandAggregation, pattern.EngineAll), ) return rule } @@ -664,10 +665,10 @@ type PushSelDownWindow struct { // The pattern of this rule is `Selection -> Window`. func NewRulePushSelDownWindow() Transformation { rule := &PushSelDownWindow{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandWindow, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandWindow, pattern.EngineAll), ) return rule } @@ -727,10 +728,10 @@ type TransformLimitToTopN struct { // The pattern of this rule is `Limit -> Sort`. func NewRuleTransformLimitToTopN() Transformation { rule := &TransformLimitToTopN{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandSort, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandSort, pattern.EngineTiDBOnly), ) return rule } @@ -760,10 +761,10 @@ type PushLimitDownProjection struct { // The pattern of this rule is `Limit->Projection->X` to `Projection->Limit->X`. func NewRulePushLimitDownProjection() Transformation { rule := &PushLimitDownProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandProjection, pattern.EngineTiDBOnly), ) return rule } @@ -803,10 +804,10 @@ type PushLimitDownUnionAll struct { // The pattern of this rule is `Limit->UnionAll->X`. func NewRulePushLimitDownUnionAll() Transformation { rule := &PushLimitDownUnionAll{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandUnionAll, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandUnionAll, pattern.EngineTiDBOnly), ) return rule } @@ -955,10 +956,10 @@ type PushSelDownJoin struct { // The pattern of this rule is `Selection -> Join`. func NewRulePushSelDownJoin() Transformation { rule := &PushSelDownJoin{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly), ) return rule } @@ -1025,7 +1026,7 @@ type TransformJoinCondToSel struct { // The pattern of this rule is: `Join`. func NewRuleTransformJoinCondToSel() Transformation { rule := &TransformJoinCondToSel{} - rule.pattern = memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly) + rule.pattern = pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly) return rule } @@ -1069,10 +1070,10 @@ type PushSelDownUnionAll struct { // The pattern of this rule is `Selection -> UnionAll`. func NewRulePushSelDownUnionAll() Transformation { rule := &PushSelDownUnionAll{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandUnionAll, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandUnionAll, pattern.EngineTiDBOnly), ) return rule } @@ -1104,10 +1105,10 @@ type EliminateProjection struct { // The pattern of this rule is `Projection -> Any`. func NewRuleEliminateProjection() Transformation { rule := &EliminateProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandProjection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandAny, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandProjection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandAny, pattern.EngineTiDBOnly), ) return rule } @@ -1147,10 +1148,10 @@ type MergeAdjacentProjection struct { // The pattern of this rule is `Projection -> Projection`. func NewRuleMergeAdjacentProjection() Transformation { rule := &MergeAdjacentProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandProjection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandProjection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandProjection, pattern.EngineTiDBOnly), ) return rule } @@ -1195,10 +1196,10 @@ type PushTopNDownOuterJoin struct { // The pattern of this rule is: `TopN -> Join`. func NewRulePushTopNDownOuterJoin() Transformation { rule := &PushTopNDownOuterJoin{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly), ) return rule } @@ -1278,10 +1279,10 @@ type PushTopNDownProjection struct { // The pattern of this rule is `TopN->Projection->X` to `Projection->TopN->X`. func NewRulePushTopNDownProjection() Transformation { rule := &PushTopNDownProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandProjection, pattern.EngineTiDBOnly), ) return rule } @@ -1342,10 +1343,10 @@ type PushTopNDownUnionAll struct { // The pattern of this rule is `TopN->UnionAll->X`. func NewRulePushTopNDownUnionAll() Transformation { rule := &PushTopNDownUnionAll{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandUnionAll, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandUnionAll, pattern.EngineTiDBOnly), ) return rule } @@ -1392,10 +1393,10 @@ type PushTopNDownTiKVSingleGather struct { // The pattern of this rule is `TopN -> TiKVSingleGather`. func NewRulePushTopNDownTiKVSingleGather() Transformation { rule := &PushTopNDownTiKVSingleGather{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandTiKVSingleGather, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly), ) return rule } @@ -1441,10 +1442,10 @@ type MergeAdjacentTopN struct { // The pattern of this rule is `TopN->TopN->X`. func NewRuleMergeAdjacentTopN() Transformation { rule := &MergeAdjacentTopN{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineAll, - memo.NewPattern(memo.OperandTopN, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineAll, + pattern.NewPattern(pattern.OperandTopN, pattern.EngineAll), ) return rule } @@ -1503,10 +1504,10 @@ type MergeAggregationProjection struct { // The pattern of this rule is: `Aggregation -> Projection`. func NewRuleMergeAggregationProjection() Transformation { rule := &MergeAggregationProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandProjection, pattern.EngineTiDBOnly), ) return rule } @@ -1559,10 +1560,10 @@ type EliminateSingleMaxMin struct { // The pattern of this rule is `max/min->X`. func NewRuleEliminateSingleMaxMin() Transformation { rule := &EliminateSingleMaxMin{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandAny, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandAny, pattern.EngineTiDBOnly), ) return rule } @@ -1660,10 +1661,10 @@ type MergeAdjacentSelection struct { // The pattern of this rule is `Selection->Selection->X`. func NewRuleMergeAdjacentSelection() Transformation { rule := &MergeAdjacentSelection{} - rule.pattern = memo.BuildPattern( - memo.OperandSelection, - memo.EngineAll, - memo.NewPattern(memo.OperandSelection, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandSelection, + pattern.EngineAll, + pattern.NewPattern(pattern.OperandSelection, pattern.EngineAll), ) return rule } @@ -1693,10 +1694,10 @@ type MergeAdjacentLimit struct { // The pattern of this rule is `Limit->Limit->X`. func NewRuleMergeAdjacentLimit() Transformation { rule := &MergeAdjacentLimit{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineAll, - memo.NewPattern(memo.OperandLimit, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineAll, + pattern.NewPattern(pattern.OperandLimit, pattern.EngineAll), ) return rule } @@ -1735,9 +1736,9 @@ type TransformLimitToTableDual struct { // The pattern of this rule is `Limit->X`. func NewRuleTransformLimitToTableDual() Transformation { rule := &TransformLimitToTableDual{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineAll, + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineAll, ) return rule } @@ -1767,10 +1768,10 @@ type PushLimitDownOuterJoin struct { // The pattern of this rule is `Limit -> Join`. func NewRulePushLimitDownOuterJoin() Transformation { rule := &PushLimitDownOuterJoin{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly), ) return rule } @@ -1828,10 +1829,10 @@ type PushLimitDownTiKVSingleGather struct { // The pattern of this rule is `Limit -> TiKVSingleGather`. func NewRulePushLimitDownTiKVSingleGather() Transformation { rule := &PushLimitDownTiKVSingleGather{} - rule.pattern = memo.BuildPattern( - memo.OperandLimit, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandTiKVSingleGather, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandLimit, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly), ) return rule } @@ -1923,10 +1924,10 @@ type EliminateOuterJoinBelowAggregation struct { // The pattern of this rule is `Aggregation->Join->X`. func NewRuleEliminateOuterJoinBelowAggregation() Transformation { rule := &EliminateOuterJoinBelowAggregation{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly), ) return rule } @@ -1985,10 +1986,10 @@ type EliminateOuterJoinBelowProjection struct { // The pattern of this rule is `Projection->Join->X`. func NewRuleEliminateOuterJoinBelowProjection() Transformation { rule := &EliminateOuterJoinBelowProjection{} - rule.pattern = memo.BuildPattern( - memo.OperandProjection, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly), + rule.pattern = pattern.BuildPattern( + pattern.OperandProjection, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandJoin, pattern.EngineTiDBOnly), ) return rule } @@ -2039,9 +2040,9 @@ type TransformAggregateCaseToSelection struct { // The pattern of this rule is `Agg->X`. func NewRuleTransformAggregateCaseToSelection() Transformation { rule := &TransformAggregateCaseToSelection{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, ) return rule } @@ -2159,9 +2160,9 @@ type TransformAggToProj struct { // The pattern of this rule is `Agg`. func NewRuleTransformAggToProj() Transformation { rule := &TransformAggToProj{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, ) return rule } @@ -2222,9 +2223,9 @@ type InjectProjectionBelowTopN struct { // The pattern of this rule is: a single TopN func NewRuleInjectProjectionBelowTopN() Transformation { rule := &InjectProjectionBelowTopN{} - rule.pattern = memo.BuildPattern( - memo.OperandTopN, - memo.EngineTiDBOnly, + rule.pattern = pattern.BuildPattern( + pattern.OperandTopN, + pattern.EngineTiDBOnly, ) return rule } @@ -2317,9 +2318,9 @@ type InjectProjectionBelowAgg struct { // The pattern of this rule is: a single Aggregation. func NewRuleInjectProjectionBelowAgg() Transformation { rule := &InjectProjectionBelowAgg{} - rule.pattern = memo.BuildPattern( - memo.OperandAggregation, - memo.EngineTiDBOnly, + rule.pattern = pattern.BuildPattern( + pattern.OperandAggregation, + pattern.EngineTiDBOnly, ) return rule } @@ -2430,7 +2431,7 @@ type TransformApplyToJoin struct { // The pattern of this rule is: `Apply -> (X, Y)`. func NewRuleTransformApplyToJoin() Transformation { rule := &TransformApplyToJoin{} - rule.pattern = memo.NewPattern(memo.OperandApply, memo.EngineTiDBOnly) + rule.pattern = pattern.NewPattern(pattern.OperandApply, pattern.EngineTiDBOnly) return rule } @@ -2481,11 +2482,11 @@ type PullSelectionUpApply struct { // The pattern of this rule is: `Apply -> (Any, Selection)`. func NewRulePullSelectionUpApply() Transformation { rule := &PullSelectionUpApply{} - rule.pattern = memo.BuildPattern( - memo.OperandApply, - memo.EngineTiDBOnly, - memo.NewPattern(memo.OperandAny, memo.EngineTiDBOnly), // outer child - memo.NewPattern(memo.OperandSelection, memo.EngineTiDBOnly), // inner child + rule.pattern = pattern.BuildPattern( + pattern.OperandApply, + pattern.EngineTiDBOnly, + pattern.NewPattern(pattern.OperandAny, pattern.EngineTiDBOnly), // outer child + pattern.NewPattern(pattern.OperandSelection, pattern.EngineTiDBOnly), // inner child ) return rule } @@ -2524,10 +2525,10 @@ type MergeAdjacentWindow struct { // The pattern of this rule is `Window -> Window`. func NewRuleMergeAdjacentWindow() Transformation { rule := &MergeAdjacentWindow{} - rule.pattern = memo.BuildPattern( - memo.OperandWindow, - memo.EngineAll, - memo.NewPattern(memo.OperandWindow, memo.EngineAll), + rule.pattern = pattern.BuildPattern( + pattern.OperandWindow, + pattern.EngineAll, + pattern.NewPattern(pattern.OperandWindow, pattern.EngineAll), ) return rule } diff --git a/pkg/planner/cascades/transformation_rules_test.go b/pkg/planner/cascades/transformation_rules_test.go index 44af39a46d000..5be02f43f66ec 100644 --- a/pkg/planner/cascades/transformation_rules_test.go +++ b/pkg/planner/cascades/transformation_rules_test.go @@ -16,6 +16,7 @@ package cascades import ( "context" + "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -67,10 +68,10 @@ func testGroupToString(t *testing.T, input []string, output []struct { func TestAggPushDownGather(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules(TransformationRuleBatch{ - memo.OperandAggregation: { + pattern.OperandAggregation: { NewRulePushAggDownGather(), }, - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }) @@ -123,7 +124,7 @@ func TestPredicatePushDown(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules( TransformationRuleBatch{ // TiDB layer - memo.OperandSelection: { + pattern.OperandSelection: { NewRulePushSelDownSort(), NewRulePushSelDownProjection(), NewRulePushSelDownAggregation(), @@ -132,17 +133,17 @@ func TestPredicatePushDown(t *testing.T) { NewRulePushSelDownWindow(), NewRuleMergeAdjacentSelection(), }, - memo.OperandJoin: { + pattern.OperandJoin: { NewRuleTransformJoinCondToSel(), }, }, TransformationRuleBatch{ // TiKV layer - memo.OperandSelection: { + pattern.OperandSelection: { NewRulePushSelDownTableScan(), NewRulePushSelDownTiKVSingleGather(), NewRulePushSelDownIndexScan(), }, - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }, @@ -164,27 +165,27 @@ func TestTopNRules(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules( TransformationRuleBatch{ // TiDB layer - memo.OperandLimit: { + pattern.OperandLimit: { NewRuleTransformLimitToTopN(), NewRulePushLimitDownProjection(), NewRulePushLimitDownUnionAll(), NewRulePushLimitDownOuterJoin(), NewRuleMergeAdjacentLimit(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRulePushTopNDownProjection(), NewRulePushTopNDownOuterJoin(), NewRulePushTopNDownUnionAll(), }, }, TransformationRuleBatch{ // TiKV layer - memo.OperandLimit: { + pattern.OperandLimit: { NewRulePushLimitDownTiKVSingleGather(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRulePushTopNDownTiKVSingleGather(), }, - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }, @@ -202,7 +203,7 @@ func TestTopNRules(t *testing.T) { func TestProjectionElimination(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules(TransformationRuleBatch{ - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleEliminateProjection(), NewRuleMergeAdjacentProjection(), }, @@ -221,8 +222,8 @@ func TestProjectionElimination(t *testing.T) { func TestEliminateMaxMin(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleEliminateSingleMaxMin(), }, }) @@ -240,8 +241,8 @@ func TestEliminateMaxMin(t *testing.T) { func TestMergeAggregationProjection(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleMergeAggregationProjection(), }, }) @@ -259,15 +260,15 @@ func TestMergeAggregationProjection(t *testing.T) { func TestMergeAdjacentTopN(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandLimit: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandLimit: { NewRuleTransformLimitToTopN(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRulePushTopNDownProjection(), NewRuleMergeAdjacentTopN(), }, - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleMergeAdjacentProjection(), }, }) @@ -286,7 +287,7 @@ func TestMergeAdjacentTopN(t *testing.T) { func TestMergeAdjacentLimit(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules(TransformationRuleBatch{ - memo.OperandLimit: { + pattern.OperandLimit: { NewRulePushLimitDownProjection(), NewRuleMergeAdjacentLimit(), }, @@ -306,7 +307,7 @@ func TestMergeAdjacentLimit(t *testing.T) { func TestTransformLimitToTableDual(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules(TransformationRuleBatch{ - memo.OperandLimit: { + pattern.OperandLimit: { NewRuleTransformLimitToTableDual(), }, }) @@ -325,7 +326,7 @@ func TestTransformLimitToTableDual(t *testing.T) { func TestPostTransformationRules(t *testing.T) { optimizer := NewOptimizer() optimizer.ResetTransformationRules(TransformationRuleBatch{ - memo.OperandLimit: { + pattern.OperandLimit: { NewRuleTransformLimitToTopN(), }, }, PostTransformationBatch) @@ -343,14 +344,14 @@ func TestPostTransformationRules(t *testing.T) { func TestPushLimitDownTiKVSingleGather(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandLimit: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandLimit: { NewRulePushLimitDownTiKVSingleGather(), }, - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleEliminateProjection(), }, - memo.OperandDataSource: { + pattern.OperandDataSource: { NewRuleEnumeratePaths(), }, }) @@ -368,11 +369,11 @@ func TestPushLimitDownTiKVSingleGather(t *testing.T) { func TestEliminateOuterJoin(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleEliminateOuterJoinBelowAggregation(), }, - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleEliminateOuterJoinBelowProjection(), }, }) @@ -390,8 +391,8 @@ func TestEliminateOuterJoin(t *testing.T) { func TestTransformAggregateCaseToSelection(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleTransformAggregateCaseToSelection(), }, }) @@ -409,11 +410,11 @@ func TestTransformAggregateCaseToSelection(t *testing.T) { func TestTransformAggToProj(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleTransformAggToProj(), }, - memo.OperandProjection: { + pattern.OperandProjection: { NewRuleMergeAdjacentProjection(), }, }) @@ -431,8 +432,8 @@ func TestTransformAggToProj(t *testing.T) { func TestDecorrelate(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandApply: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandApply: { NewRulePullSelectionUpApply(), NewRuleTransformApplyToJoin(), }, @@ -451,15 +452,15 @@ func TestDecorrelate(t *testing.T) { func TestInjectProj(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandLimit: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandLimit: { NewRuleTransformLimitToTopN(), }, - }, map[memo.Operand][]Transformation{ - memo.OperandAggregation: { + }, map[pattern.Operand][]Transformation{ + pattern.OperandAggregation: { NewRuleInjectProjectionBelowAgg(), }, - memo.OperandTopN: { + pattern.OperandTopN: { NewRuleInjectProjectionBelowTopN(), }, }) @@ -477,12 +478,12 @@ func TestInjectProj(t *testing.T) { func TestMergeAdjacentWindow(t *testing.T) { optimizer := NewOptimizer() - optimizer.ResetTransformationRules(map[memo.Operand][]Transformation{ - memo.OperandProjection: { + optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ + pattern.OperandProjection: { NewRuleMergeAdjacentProjection(), NewRuleEliminateProjection(), }, - memo.OperandWindow: { + pattern.OperandWindow: { NewRuleMergeAdjacentWindow(), }, }) diff --git a/pkg/planner/memo/BUILD.bazel b/pkg/planner/memo/BUILD.bazel index dd538beb3c894..720862b8983ba 100644 --- a/pkg/planner/memo/BUILD.bazel +++ b/pkg/planner/memo/BUILD.bazel @@ -7,13 +7,13 @@ go_library( "group.go", "group_expr.go", "implementation.go", - "pattern.go", ], importpath = "github.com/pingcap/tidb/pkg/planner/memo", visibility = ["//visibility:public"], deps = [ "//pkg/expression", "//pkg/planner/core", + "//pkg/planner/pattern", "//pkg/planner/property", ], ) @@ -26,11 +26,10 @@ go_test( "group_expr_test.go", "group_test.go", "main_test.go", - "pattern_test.go", ], embed = [":memo"], flaky = True, - shard_count = 22, + shard_count = 17, deps = [ "//pkg/domain", "//pkg/expression", @@ -38,6 +37,7 @@ go_test( "//pkg/parser", "//pkg/parser/model", "//pkg/planner/core", + "//pkg/planner/pattern", "//pkg/planner/property", "//pkg/sessionctx/variable", "//pkg/testkit/testsetup", diff --git a/pkg/planner/memo/expr_iterator.go b/pkg/planner/memo/expr_iterator.go index 39e5ae20f873f..4d9911d2fbd24 100644 --- a/pkg/planner/memo/expr_iterator.go +++ b/pkg/planner/memo/expr_iterator.go @@ -16,6 +16,7 @@ package memo import ( "container/list" + "github.com/pingcap/tidb/pkg/planner/pattern" ) // ExprIter enumerates all the equivalent expressions in the Group according to @@ -32,7 +33,7 @@ type ExprIter struct { // Pattern describes the node of pattern tree. // The Operand type of the Group expression and the EngineType of the Group // must be matched with it. - *Pattern + *pattern.Pattern // Children is used to iterate the child expressions. Children []*ExprIter @@ -57,7 +58,7 @@ func (iter *ExprIter) Next() (found bool) { } // It's root node or leaf ANY node. - if iter.Group == nil || iter.Operand == OperandAny { + if iter.Group == nil || iter.Operand == pattern.OperandAny { return false } @@ -65,7 +66,7 @@ func (iter *ExprIter) Next() (found bool) { for elem := iter.Element.Next(); elem != nil; elem = elem.Next() { expr := elem.Value.(*GroupExpr) - if !iter.Operand.Match(GetOperand(expr.ExprNode)) { + if !iter.Operand.Match(pattern.GetOperand(expr.ExprNode)) { // All the Equivalents which have the same Operand are continuously // stored in the list. Once the current equivalent can not Match // the Operand, the rest can not, either. @@ -114,7 +115,7 @@ func (iter *ExprIter) Reset() (findMatch bool) { for elem := iter.Group.GetFirstElem(iter.Operand); elem != nil; elem = elem.Next() { expr := elem.Value.(*GroupExpr) - if !iter.Pattern.Match(GetOperand(expr.ExprNode), expr.Group.EngineType) { + if !iter.Pattern.Match(pattern.GetOperand(expr.ExprNode), expr.Group.EngineType) { break } @@ -161,9 +162,9 @@ func (iter *ExprIter) GetExpr() *GroupExpr { } // NewExprIterFromGroupElem creates the iterator on the Group Element. -func NewExprIterFromGroupElem(elem *list.Element, p *Pattern) *ExprIter { +func NewExprIterFromGroupElem(elem *list.Element, p *pattern.Pattern) *ExprIter { expr := elem.Value.(*GroupExpr) - if !p.Match(GetOperand(expr.ExprNode), expr.Group.EngineType) { + if !p.Match(pattern.GetOperand(expr.ExprNode), expr.Group.EngineType) { return nil } iter := newExprIterFromGroupExpr(expr, p) @@ -174,7 +175,7 @@ func NewExprIterFromGroupElem(elem *list.Element, p *Pattern) *ExprIter { } // newExprIterFromGroupExpr creates the iterator on the Group expression. -func newExprIterFromGroupExpr(expr *GroupExpr, p *Pattern) *ExprIter { +func newExprIterFromGroupExpr(expr *GroupExpr, p *pattern.Pattern) *ExprIter { if len(p.Children) != 0 && len(p.Children) != len(expr.Children) { return nil } @@ -190,13 +191,13 @@ func newExprIterFromGroupExpr(expr *GroupExpr, p *Pattern) *ExprIter { } // newExprIterFromGroup creates the iterator on the Group. -func newExprIterFromGroup(g *Group, p *Pattern) *ExprIter { +func newExprIterFromGroup(g *Group, p *pattern.Pattern) *ExprIter { if p.MatchOperandAny(g.EngineType) { return &ExprIter{Group: g, Pattern: p, matched: true} } for elem := g.GetFirstElem(p.Operand); elem != nil; elem = elem.Next() { expr := elem.Value.(*GroupExpr) - if !p.Match(GetOperand(expr.ExprNode), g.EngineType) { + if !p.Match(pattern.GetOperand(expr.ExprNode), g.EngineType) { return nil } iter := newExprIterFromGroupExpr(expr, p) diff --git a/pkg/planner/memo/expr_iterator_test.go b/pkg/planner/memo/expr_iterator_test.go index e5cd97223dc9f..1ba7330bcf8cd 100644 --- a/pkg/planner/memo/expr_iterator_test.go +++ b/pkg/planner/memo/expr_iterator_test.go @@ -15,6 +15,7 @@ package memo import ( + "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -47,26 +48,28 @@ func TestNewExprIterFromGroupElem(t *testing.T) { expr.Children = append(expr.Children, g1) g2 := NewGroupWithSchema(expr, schema) - pattern := BuildPattern(OperandJoin, EngineAll, BuildPattern(OperandProjection, EngineAll), BuildPattern(OperandSelection, EngineAll)) - iter := NewExprIterFromGroupElem(g2.Equivalents.Front(), pattern) + pat := pattern.BuildPattern(pattern.OperandJoin, pattern.EngineAll, + pattern.BuildPattern(pattern.OperandProjection, pattern.EngineAll), + pattern.BuildPattern(pattern.OperandSelection, pattern.EngineAll)) + iter := NewExprIterFromGroupElem(g2.Equivalents.Front(), pat) require.NotNil(t, iter) require.Nil(t, iter.Group) require.Equal(t, g2.Equivalents.Front(), iter.Element) require.True(t, iter.matched) - require.Equal(t, OperandJoin, iter.Operand) + require.Equal(t, pattern.OperandJoin, iter.Operand) require.Len(t, iter.Children, 2) require.Equal(t, g0, iter.Children[0].Group) - require.Equal(t, g0.GetFirstElem(OperandProjection), iter.Children[0].Element) + require.Equal(t, g0.GetFirstElem(pattern.OperandProjection), iter.Children[0].Element) require.True(t, iter.Children[0].matched) - require.Equal(t, OperandProjection, iter.Children[0].Operand) + require.Equal(t, pattern.OperandProjection, iter.Children[0].Operand) require.Len(t, iter.Children[0].Children, 0) require.Equal(t, g1, iter.Children[1].Group) - require.Equal(t, g1.GetFirstElem(OperandSelection), iter.Children[1].Element) + require.Equal(t, g1.GetFirstElem(pattern.OperandSelection), iter.Children[1].Element) require.True(t, iter.Children[1].matched) - require.Equal(t, OperandSelection, iter.Children[1].Operand) + require.Equal(t, pattern.OperandSelection, iter.Children[1].Operand) require.Len(t, iter.Children[0].Children, 0) } @@ -95,8 +98,10 @@ func TestExprIterNext(t *testing.T) { expr.Children = append(expr.Children, g1) g2 := NewGroupWithSchema(expr, schema) - pattern := BuildPattern(OperandJoin, EngineAll, BuildPattern(OperandProjection, EngineAll), BuildPattern(OperandSelection, EngineAll)) - iter := NewExprIterFromGroupElem(g2.Equivalents.Front(), pattern) + pat := pattern.BuildPattern(pattern.OperandJoin, pattern.EngineAll, + pattern.BuildPattern(pattern.OperandProjection, pattern.EngineAll), + pattern.BuildPattern(pattern.OperandSelection, pattern.EngineAll)) + iter := NewExprIterFromGroupElem(g2.Equivalents.Front(), pat) require.NotNil(t, iter) count := 0 @@ -104,17 +109,17 @@ func TestExprIterNext(t *testing.T) { count++ require.Nil(t, iter.Group) require.True(t, iter.matched) - require.Equal(t, OperandJoin, iter.Operand) + require.Equal(t, pattern.OperandJoin, iter.Operand) require.Len(t, iter.Children, 2) require.Equal(t, g0, iter.Children[0].Group) require.True(t, iter.Children[0].matched) - require.Equal(t, OperandProjection, iter.Children[0].Operand) + require.Equal(t, pattern.OperandProjection, iter.Children[0].Operand) require.Len(t, iter.Children[0].Children, 0) require.Equal(t, g1, iter.Children[1].Group) require.True(t, iter.Children[1].matched) - require.Equal(t, OperandSelection, iter.Children[1].Operand) + require.Equal(t, pattern.OperandSelection, iter.Children[1].Operand) require.Len(t, iter.Children[1].Children, 0) } @@ -162,12 +167,13 @@ func TestExprIterReset(t *testing.T) { sel3.Children = append(sel3.Children, g2) // create a pattern: join(proj, sel(limit)) - lhsPattern := BuildPattern(OperandProjection, EngineAll) - rhsPattern := BuildPattern(OperandSelection, EngineAll, BuildPattern(OperandLimit, EngineAll)) - pattern := BuildPattern(OperandJoin, EngineAll, lhsPattern, rhsPattern) + lhsPattern := pattern.BuildPattern(pattern.OperandProjection, pattern.EngineAll) + rhsPattern := pattern.BuildPattern(pattern.OperandSelection, pattern.EngineAll, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineAll)) + pat := pattern.BuildPattern(pattern.OperandJoin, pattern.EngineAll, lhsPattern, rhsPattern) // create expression iterator for the pattern on join - iter := NewExprIterFromGroupElem(g3.Equivalents.Front(), pattern) + iter := NewExprIterFromGroupElem(g3.Equivalents.Front(), pat) require.NotNil(t, iter) count := 0 @@ -175,22 +181,22 @@ func TestExprIterReset(t *testing.T) { count++ require.Nil(t, iter.Group) require.True(t, iter.matched) - require.Equal(t, OperandJoin, iter.Operand) + require.Equal(t, pattern.OperandJoin, iter.Operand) require.Len(t, iter.Children, 2) require.Equal(t, g0, iter.Children[0].Group) require.True(t, iter.Children[0].matched) - require.Equal(t, OperandProjection, iter.Children[0].Operand) + require.Equal(t, pattern.OperandProjection, iter.Children[0].Operand) require.Len(t, iter.Children[0].Children, 0) require.Equal(t, g1, iter.Children[1].Group) require.True(t, iter.Children[1].matched) - require.Equal(t, OperandSelection, iter.Children[1].Operand) + require.Equal(t, pattern.OperandSelection, iter.Children[1].Operand) require.Len(t, iter.Children[1].Children, 1) require.Equal(t, g2, iter.Children[1].Children[0].Group) require.True(t, iter.Children[1].Children[0].matched) - require.Equal(t, OperandLimit, iter.Children[1].Children[0].Operand) + require.Equal(t, pattern.OperandLimit, iter.Children[1].Children[0].Operand) require.Len(t, iter.Children[1].Children[0].Children, 0) } @@ -205,19 +211,19 @@ func TestExprIterWithEngineType(t *testing.T) { do := domain.GetDomain(ctx) do.StatsHandle().Close() }() - g1 := NewGroupWithSchema(NewGroupExpr(plannercore.LogicalSelection{Conditions: []expression.Expression{expression.NewOne()}}.Init(ctx, 0)), schema).SetEngineType(EngineTiFlash) + g1 := NewGroupWithSchema(NewGroupExpr(plannercore.LogicalSelection{Conditions: []expression.Expression{expression.NewOne()}}.Init(ctx, 0)), schema).SetEngineType(pattern.EngineTiFlash) g1.Insert(NewGroupExpr(plannercore.LogicalLimit{Count: 1}.Init(ctx, 0))) g1.Insert(NewGroupExpr(plannercore.LogicalProjection{Exprs: []expression.Expression{expression.NewOne()}}.Init(ctx, 0))) g1.Insert(NewGroupExpr(plannercore.LogicalLimit{Count: 2}.Init(ctx, 0))) - g2 := NewGroupWithSchema(NewGroupExpr(plannercore.LogicalSelection{Conditions: []expression.Expression{expression.NewOne()}}.Init(ctx, 0)), schema).SetEngineType(EngineTiKV) + g2 := NewGroupWithSchema(NewGroupExpr(plannercore.LogicalSelection{Conditions: []expression.Expression{expression.NewOne()}}.Init(ctx, 0)), schema).SetEngineType(pattern.EngineTiKV) g2.Insert(NewGroupExpr(plannercore.LogicalLimit{Count: 2}.Init(ctx, 0))) g2.Insert(NewGroupExpr(plannercore.LogicalProjection{Exprs: []expression.Expression{expression.NewOne()}}.Init(ctx, 0))) g2.Insert(NewGroupExpr(plannercore.LogicalLimit{Count: 3}.Init(ctx, 0))) flashGather := NewGroupExpr(plannercore.TiKVSingleGather{}.Init(ctx, 0)) flashGather.Children = append(flashGather.Children, g1) - g3 := NewGroupWithSchema(flashGather, schema).SetEngineType(EngineTiDB) + g3 := NewGroupWithSchema(flashGather, schema).SetEngineType(pattern.EngineTiDB) tikvGather := NewGroupExpr(plannercore.TiKVSingleGather{}.Init(ctx, 0)) tikvGather.Children = append(tikvGather.Children, g2) @@ -225,7 +231,7 @@ func TestExprIterWithEngineType(t *testing.T) { join := NewGroupExpr(plannercore.LogicalJoin{}.Init(ctx, 0)) join.Children = append(join.Children, g3, g3) - g4 := NewGroupWithSchema(join, schema).SetEngineType(EngineTiDB) + g4 := NewGroupWithSchema(join, schema).SetEngineType(pattern.EngineTiDB) // The Groups look like this: // Group 4 @@ -244,51 +250,62 @@ func TestExprIterWithEngineType(t *testing.T) { // Limit // Limit - p0 := BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOnly)) + p0 := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOnly)) require.Equal(t, 2, countMatchedIter(g3, p0)) - p1 := BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiFlashOnly)) + p1 := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiFlashOnly)) require.Equal(t, 2, countMatchedIter(g3, p1)) - p2 := BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOrTiFlash)) + p2 := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOrTiFlash)) require.Equal(t, 4, countMatchedIter(g3, p2)) - p3 := BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandSelection, EngineTiFlashOnly)) + p3 := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandSelection, pattern.EngineTiFlashOnly)) require.Equal(t, 1, countMatchedIter(g3, p3)) - p4 := BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandProjection, EngineTiKVOnly)) + p4 := pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandProjection, pattern.EngineTiKVOnly)) require.Equal(t, 1, countMatchedIter(g3, p4)) - p5 := BuildPattern( - OperandJoin, - EngineTiDBOnly, - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOnly)), - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOnly)), + p5 := pattern.BuildPattern( + pattern.OperandJoin, + pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOnly)), + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOnly)), ) require.Equal(t, 4, countMatchedIter(g4, p5)) - p6 := BuildPattern( - OperandJoin, - EngineTiDBOnly, - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiFlashOnly)), - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOnly)), + p6 := pattern.BuildPattern( + pattern.OperandJoin, + pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiFlashOnly)), + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOnly)), ) require.Equal(t, 4, countMatchedIter(g4, p6)) - p7 := BuildPattern( - OperandJoin, - EngineTiDBOnly, - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOrTiFlash)), - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly, BuildPattern(OperandLimit, EngineTiKVOrTiFlash)), + p7 := pattern.BuildPattern( + pattern.OperandJoin, + pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOrTiFlash)), + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandLimit, pattern.EngineTiKVOrTiFlash)), ) require.Equal(t, 16, countMatchedIter(g4, p7)) // This is not a test case for EngineType. This case is to test // the Pattern without a leaf AnyOperand. It is more efficient to // test it here. - p8 := BuildPattern( - OperandJoin, - EngineTiDBOnly, - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly), - BuildPattern(OperandTiKVSingleGather, EngineTiDBOnly), + p8 := pattern.BuildPattern( + pattern.OperandJoin, + pattern.EngineTiDBOnly, + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly), + pattern.BuildPattern(pattern.OperandTiKVSingleGather, pattern.EngineTiDBOnly), ) require.Equal(t, 4, countMatchedIter(g4, p8)) } -func countMatchedIter(group *Group, pattern *Pattern) int { +func countMatchedIter(group *Group, pattern *pattern.Pattern) int { count := 0 for elem := group.Equivalents.Front(); elem != nil; elem = elem.Next() { iter := NewExprIterFromGroupElem(elem, pattern) diff --git a/pkg/planner/memo/group.go b/pkg/planner/memo/group.go index 62b69c16e3ee4..9013ab815e6dc 100644 --- a/pkg/planner/memo/group.go +++ b/pkg/planner/memo/group.go @@ -17,61 +17,13 @@ package memo import ( "container/list" "fmt" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/expression" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/property" ) -// EngineType is determined by whether it's above or below `Gather`s. -// Plan will choose the different engine to be implemented/executed on according to its EngineType. -// Different engine may support different operators with different cost, so we should design -// different transformation and implementation rules for each engine. -type EngineType uint - -const ( - // EngineTiDB stands for groups which is above `Gather`s and will be executed in TiDB layer. - EngineTiDB EngineType = 1 << iota - // EngineTiKV stands for groups which is below `Gather`s and will be executed in TiKV layer. - EngineTiKV - // EngineTiFlash stands for groups which is below `Gather`s and will be executed in TiFlash layer. - EngineTiFlash -) - -// EngineTypeSet is the bit set of EngineTypes. -type EngineTypeSet uint - -const ( - // EngineTiDBOnly is the EngineTypeSet for EngineTiDB only. - EngineTiDBOnly = EngineTypeSet(EngineTiDB) - // EngineTiKVOnly is the EngineTypeSet for EngineTiKV only. - EngineTiKVOnly = EngineTypeSet(EngineTiKV) - // EngineTiFlashOnly is the EngineTypeSet for EngineTiFlash only. - EngineTiFlashOnly = EngineTypeSet(EngineTiFlash) - // EngineTiKVOrTiFlash is the EngineTypeSet for (EngineTiKV | EngineTiFlash). - EngineTiKVOrTiFlash = EngineTypeSet(EngineTiKV | EngineTiFlash) - // EngineAll is the EngineTypeSet for all of the EngineTypes. - EngineAll = EngineTypeSet(EngineTiDB | EngineTiKV | EngineTiFlash) -) - -// Contains checks whether the EngineTypeSet contains the EngineType. -func (e EngineTypeSet) Contains(tp EngineType) bool { - return uint(e)&uint(tp) != 0 -} - -// String implements fmt.Stringer interface. -func (e EngineType) String() string { - switch e { - case EngineTiDB: - return "EngineTiDB" - case EngineTiKV: - return "EngineTiKV" - case EngineTiFlash: - return "EngineTiFlash" - } - return "UnknownEngineType" -} - // ExploreMark is uses to mark whether a Group or GroupExpr has // been fully explored by a transformation rule batch. type ExploreMark int @@ -96,13 +48,13 @@ func (m *ExploreMark) Explored(round int) bool { type Group struct { Equivalents *list.List - FirstExpr map[Operand]*list.Element + FirstExpr map[pattern.Operand]*list.Element Fingerprints map[string]*list.Element ImplMap map[string]Implementation Prop *property.LogicalProperty - EngineType EngineType + EngineType pattern.EngineType SelfFingerprint string @@ -123,17 +75,17 @@ func NewGroupWithSchema(e *GroupExpr, s *expression.Schema) *Group { g := &Group{ Equivalents: list.New(), Fingerprints: make(map[string]*list.Element), - FirstExpr: make(map[Operand]*list.Element), + FirstExpr: make(map[pattern.Operand]*list.Element), ImplMap: make(map[string]Implementation), Prop: prop, - EngineType: EngineTiDB, + EngineType: pattern.EngineTiDB, } g.Insert(e) return g } // SetEngineType sets the engine type of the group. -func (g *Group) SetEngineType(e EngineType) *Group { +func (g *Group) SetEngineType(e pattern.EngineType) *Group { g.EngineType = e return g } @@ -152,7 +104,7 @@ func (g *Group) Insert(e *GroupExpr) bool { return false } - operand := GetOperand(e.ExprNode) + operand := pattern.GetOperand(e.ExprNode) var newEquiv *list.Element mark, hasMark := g.FirstExpr[operand] if hasMark { @@ -174,12 +126,12 @@ func (g *Group) Delete(e *GroupExpr) { return // Can not find the target GroupExpr. } - operand := GetOperand(equiv.Value.(*GroupExpr).ExprNode) + operand := pattern.GetOperand(equiv.Value.(*GroupExpr).ExprNode) if g.FirstExpr[operand] == equiv { // The target GroupExpr is the first Element of the same Operand. // We need to change the FirstExpr to the next Expr, or delete the FirstExpr. nextElem := equiv.Next() - if nextElem != nil && GetOperand(nextElem.Value.(*GroupExpr).ExprNode) == operand { + if nextElem != nil && pattern.GetOperand(nextElem.Value.(*GroupExpr).ExprNode) == operand { g.FirstExpr[operand] = nextElem } else { // There is no more GroupExpr of the Operand, so we should @@ -197,7 +149,7 @@ func (g *Group) Delete(e *GroupExpr) { func (g *Group) DeleteAll() { g.Equivalents = list.New() g.Fingerprints = make(map[string]*list.Element) - g.FirstExpr = make(map[Operand]*list.Element) + g.FirstExpr = make(map[pattern.Operand]*list.Element) g.SelfFingerprint = "" } @@ -209,8 +161,8 @@ func (g *Group) Exists(e *GroupExpr) bool { // GetFirstElem returns the first Group expression which matches the Operand. // Return a nil pointer if there isn't. -func (g *Group) GetFirstElem(operand Operand) *list.Element { - if operand == OperandAny { +func (g *Group) GetFirstElem(operand pattern.Operand) *list.Element { + if operand == pattern.OperandAny { return g.Equivalents.Front() } return g.FirstExpr[operand] diff --git a/pkg/planner/memo/group_test.go b/pkg/planner/memo/group_test.go index 14d9ec1d1aef1..f373edad6dd05 100644 --- a/pkg/planner/memo/group_test.go +++ b/pkg/planner/memo/group_test.go @@ -16,6 +16,7 @@ package memo import ( "context" + "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -73,12 +74,12 @@ func TestGroupDeleteAll(t *testing.T) { require.True(t, g.Insert(NewGroupExpr(plannercore.LogicalLimit{}.Init(ctx, 0)))) require.True(t, g.Insert(NewGroupExpr(plannercore.LogicalProjection{}.Init(ctx, 0)))) require.Equal(t, 3, g.Equivalents.Len()) - require.NotNil(t, g.GetFirstElem(OperandProjection)) + require.NotNil(t, g.GetFirstElem(pattern.OperandProjection)) require.True(t, g.Exists(expr)) g.DeleteAll() require.Equal(t, 0, g.Equivalents.Len()) - require.Nil(t, g.GetFirstElem(OperandProjection)) + require.Nil(t, g.GetFirstElem(pattern.OperandProjection)) require.False(t, g.Exists(expr)) } @@ -170,9 +171,9 @@ func TestGroupGetFirstElem(t *testing.T) { g.Insert(expr3) g.Insert(expr4) - require.Equal(t, expr0, g.GetFirstElem(OperandProjection).Value.(*GroupExpr)) - require.Equal(t, expr1, g.GetFirstElem(OperandLimit).Value.(*GroupExpr)) - require.Equal(t, expr0, g.GetFirstElem(OperandAny).Value.(*GroupExpr)) + require.Equal(t, expr0, g.GetFirstElem(pattern.OperandProjection).Value.(*GroupExpr)) + require.Equal(t, expr1, g.GetFirstElem(pattern.OperandLimit).Value.(*GroupExpr)) + require.Equal(t, expr0, g.GetFirstElem(pattern.OperandAny).Value.(*GroupExpr)) } type fakeImpl struct { @@ -204,28 +205,6 @@ func TestGetInsertGroupImpl(t *testing.T) { require.Nil(t, g.GetImpl(orderProp)) } -func TestEngineTypeSet(t *testing.T) { - require.True(t, EngineAll.Contains(EngineTiDB)) - require.True(t, EngineAll.Contains(EngineTiKV)) - require.True(t, EngineAll.Contains(EngineTiFlash)) - - require.True(t, EngineTiDBOnly.Contains(EngineTiDB)) - require.False(t, EngineTiDBOnly.Contains(EngineTiKV)) - require.False(t, EngineTiDBOnly.Contains(EngineTiFlash)) - - require.False(t, EngineTiKVOnly.Contains(EngineTiDB)) - require.True(t, EngineTiKVOnly.Contains(EngineTiKV)) - require.False(t, EngineTiKVOnly.Contains(EngineTiFlash)) - - require.False(t, EngineTiFlashOnly.Contains(EngineTiDB)) - require.False(t, EngineTiFlashOnly.Contains(EngineTiKV)) - require.True(t, EngineTiFlashOnly.Contains(EngineTiFlash)) - - require.False(t, EngineTiKVOrTiFlash.Contains(EngineTiDB)) - require.True(t, EngineTiKVOrTiFlash.Contains(EngineTiKV)) - require.True(t, EngineTiKVOrTiFlash.Contains(EngineTiFlash)) -} - func TestFirstElemAfterDelete(t *testing.T) { ctx := plannercore.MockContext() defer func() { @@ -236,13 +215,13 @@ func TestFirstElemAfterDelete(t *testing.T) { g := NewGroupWithSchema(oldExpr, expression.NewSchema()) newExpr := NewGroupExpr(plannercore.LogicalLimit{Count: 20}.Init(ctx, 0)) g.Insert(newExpr) - require.NotNil(t, g.GetFirstElem(OperandLimit)) - require.Equal(t, oldExpr, g.GetFirstElem(OperandLimit).Value) + require.NotNil(t, g.GetFirstElem(pattern.OperandLimit)) + require.Equal(t, oldExpr, g.GetFirstElem(pattern.OperandLimit).Value) g.Delete(oldExpr) - require.NotNil(t, g.GetFirstElem(OperandLimit)) - require.Equal(t, newExpr, g.GetFirstElem(OperandLimit).Value) + require.NotNil(t, g.GetFirstElem(pattern.OperandLimit)) + require.Equal(t, newExpr, g.GetFirstElem(pattern.OperandLimit).Value) g.Delete(newExpr) - require.Nil(t, g.GetFirstElem(OperandLimit)) + require.Nil(t, g.GetFirstElem(pattern.OperandLimit)) } func TestBuildKeyInfo(t *testing.T) { diff --git a/pkg/planner/pattern/BUILD.bazel b/pkg/planner/pattern/BUILD.bazel new file mode 100644 index 0000000000000..7bc73170d8a81 --- /dev/null +++ b/pkg/planner/pattern/BUILD.bazel @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "pattern", + srcs = [ + "engine.go", + "pattern.go", + ], + importpath = "github.com/pingcap/tidb/pkg/planner/pattern", + visibility = ["//visibility:public"], + deps = ["//pkg/planner/core"], +) + +go_test( + name = "pattern_test", + timeout = "short", + srcs = [ + "engine_test.go", + "pattern_test.go", + ], + embed = [":pattern"], + flaky = True, + shard_count = 5, + deps = [ + "//pkg/planner/core", + "@com_github_stretchr_testify//require", + ], +) diff --git a/pkg/planner/pattern/engine.go b/pkg/planner/pattern/engine.go new file mode 100644 index 0000000000000..85f56e51135bb --- /dev/null +++ b/pkg/planner/pattern/engine.go @@ -0,0 +1,64 @@ +// Copyright 2024 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, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pattern + +// EngineType is determined by whether it's above or below `Gather`s. +// Plan will choose the different engine to be implemented/executed on according to its EngineType. +// Different engine may support different operators with different cost, so we should design +// different transformation and implementation rules for each engine. +type EngineType uint + +const ( + // EngineTiDB stands for groups which is above `Gather`s and will be executed in TiDB layer. + EngineTiDB EngineType = 1 << iota + // EngineTiKV stands for groups which is below `Gather`s and will be executed in TiKV layer. + EngineTiKV + // EngineTiFlash stands for groups which is below `Gather`s and will be executed in TiFlash layer. + EngineTiFlash +) + +// EngineTypeSet is the bit set of EngineTypes. +type EngineTypeSet uint + +const ( + // EngineTiDBOnly is the EngineTypeSet for EngineTiDB only. + EngineTiDBOnly = EngineTypeSet(EngineTiDB) + // EngineTiKVOnly is the EngineTypeSet for EngineTiKV only. + EngineTiKVOnly = EngineTypeSet(EngineTiKV) + // EngineTiFlashOnly is the EngineTypeSet for EngineTiFlash only. + EngineTiFlashOnly = EngineTypeSet(EngineTiFlash) + // EngineTiKVOrTiFlash is the EngineTypeSet for (EngineTiKV | EngineTiFlash). + EngineTiKVOrTiFlash = EngineTypeSet(EngineTiKV | EngineTiFlash) + // EngineAll is the EngineTypeSet for all of the EngineTypes. + EngineAll = EngineTypeSet(EngineTiDB | EngineTiKV | EngineTiFlash) +) + +// Contains checks whether the EngineTypeSet contains the EngineType. +func (e EngineTypeSet) Contains(tp EngineType) bool { + return uint(e)&uint(tp) != 0 +} + +// String implements fmt.Stringer interface. +func (e EngineType) String() string { + switch e { + case EngineTiDB: + return "EngineTiDB" + case EngineTiKV: + return "EngineTiKV" + case EngineTiFlash: + return "EngineTiFlash" + } + return "UnknownEngineType" +} diff --git a/pkg/planner/pattern/engine_test.go b/pkg/planner/pattern/engine_test.go new file mode 100644 index 0000000000000..07de20a8ff412 --- /dev/null +++ b/pkg/planner/pattern/engine_test.go @@ -0,0 +1,43 @@ +// Copyright 2024 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, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pattern + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEngineTypeSet(t *testing.T) { + require.True(t, EngineAll.Contains(EngineTiDB)) + require.True(t, EngineAll.Contains(EngineTiKV)) + require.True(t, EngineAll.Contains(EngineTiFlash)) + + require.True(t, EngineTiDBOnly.Contains(EngineTiDB)) + require.False(t, EngineTiDBOnly.Contains(EngineTiKV)) + require.False(t, EngineTiDBOnly.Contains(EngineTiFlash)) + + require.False(t, EngineTiKVOnly.Contains(EngineTiDB)) + require.True(t, EngineTiKVOnly.Contains(EngineTiKV)) + require.False(t, EngineTiKVOnly.Contains(EngineTiFlash)) + + require.False(t, EngineTiFlashOnly.Contains(EngineTiDB)) + require.False(t, EngineTiFlashOnly.Contains(EngineTiKV)) + require.True(t, EngineTiFlashOnly.Contains(EngineTiFlash)) + + require.False(t, EngineTiKVOrTiFlash.Contains(EngineTiDB)) + require.True(t, EngineTiKVOrTiFlash.Contains(EngineTiKV)) + require.True(t, EngineTiKVOrTiFlash.Contains(EngineTiFlash)) +} diff --git a/pkg/planner/memo/pattern.go b/pkg/planner/pattern/pattern.go similarity index 99% rename from pkg/planner/memo/pattern.go rename to pkg/planner/pattern/pattern.go index 018240364b4d5..1b6b712add972 100644 --- a/pkg/planner/memo/pattern.go +++ b/pkg/planner/pattern/pattern.go @@ -1,4 +1,4 @@ -// Copyright 2018 PingCAP, Inc. +// Copyright 2024 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package memo +package pattern import ( plannercore "github.com/pingcap/tidb/pkg/planner/core" diff --git a/pkg/planner/memo/pattern_test.go b/pkg/planner/pattern/pattern_test.go similarity index 99% rename from pkg/planner/memo/pattern_test.go rename to pkg/planner/pattern/pattern_test.go index 6a30ae414e6d6..29ad04f7acde7 100644 --- a/pkg/planner/memo/pattern_test.go +++ b/pkg/planner/pattern/pattern_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package memo +package pattern import ( "testing" From 289a2cff021c95c92abe1ac8e42ea0c599c9bb9a Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Tue, 26 Mar 2024 20:15:55 +0800 Subject: [PATCH 2/3] fmt import Signed-off-by: AilinKid <314806019@qq.com> --- pkg/planner/cascades/enforcer_rules.go | 2 +- pkg/planner/cascades/implementation_rules.go | 2 +- pkg/planner/cascades/optimize.go | 2 +- pkg/planner/cascades/optimize_test.go | 2 +- pkg/planner/cascades/stringer_test.go | 2 +- pkg/planner/cascades/transformation_rules_test.go | 2 +- pkg/planner/memo/expr_iterator.go | 1 + pkg/planner/memo/expr_iterator_test.go | 2 +- pkg/planner/memo/group.go | 2 +- pkg/planner/memo/group_test.go | 2 +- 10 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pkg/planner/cascades/enforcer_rules.go b/pkg/planner/cascades/enforcer_rules.go index 1a41c3f895b3b..ba2c6363b5187 100644 --- a/pkg/planner/cascades/enforcer_rules.go +++ b/pkg/planner/cascades/enforcer_rules.go @@ -15,12 +15,12 @@ package cascades import ( - "github.com/pingcap/tidb/pkg/planner/pattern" "math" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/implementation" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" "github.com/pingcap/tidb/pkg/planner/util" ) diff --git a/pkg/planner/cascades/implementation_rules.go b/pkg/planner/cascades/implementation_rules.go index 9b1485b406e34..a03d918b19695 100644 --- a/pkg/planner/cascades/implementation_rules.go +++ b/pkg/planner/cascades/implementation_rules.go @@ -15,13 +15,13 @@ package cascades import ( - "github.com/pingcap/tidb/pkg/planner/pattern" "math" "github.com/pingcap/tidb/pkg/expression" plannercore "github.com/pingcap/tidb/pkg/planner/core" impl "github.com/pingcap/tidb/pkg/planner/implementation" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" "github.com/pingcap/tidb/pkg/util/dbterror/plannererrors" ) diff --git a/pkg/planner/cascades/optimize.go b/pkg/planner/cascades/optimize.go index d685540623cf9..71a832b7f2350 100644 --- a/pkg/planner/cascades/optimize.go +++ b/pkg/planner/cascades/optimize.go @@ -16,12 +16,12 @@ package cascades import ( "container/list" - "github.com/pingcap/tidb/pkg/planner/pattern" "math" "github.com/pingcap/tidb/pkg/expression" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" "github.com/pingcap/tidb/pkg/util/dbterror/plannererrors" ) diff --git a/pkg/planner/cascades/optimize_test.go b/pkg/planner/cascades/optimize_test.go index a947b7a16537d..e9f4f3929525e 100644 --- a/pkg/planner/cascades/optimize_test.go +++ b/pkg/planner/cascades/optimize_test.go @@ -16,7 +16,6 @@ package cascades import ( "context" - "github.com/pingcap/tidb/pkg/planner/pattern" "math" "testing" @@ -27,6 +26,7 @@ import ( "github.com/pingcap/tidb/pkg/parser/model" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" "github.com/stretchr/testify/require" ) diff --git a/pkg/planner/cascades/stringer_test.go b/pkg/planner/cascades/stringer_test.go index 768f2ff92258f..b34a1ec044ea6 100644 --- a/pkg/planner/cascades/stringer_test.go +++ b/pkg/planner/cascades/stringer_test.go @@ -16,7 +16,6 @@ package cascades import ( "context" - "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -25,6 +24,7 @@ import ( "github.com/pingcap/tidb/pkg/parser/model" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/testkit/testdata" "github.com/stretchr/testify/require" ) diff --git a/pkg/planner/cascades/transformation_rules_test.go b/pkg/planner/cascades/transformation_rules_test.go index 5be02f43f66ec..a0a499d2b1bb9 100644 --- a/pkg/planner/cascades/transformation_rules_test.go +++ b/pkg/planner/cascades/transformation_rules_test.go @@ -16,7 +16,6 @@ package cascades import ( "context" - "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -25,6 +24,7 @@ import ( "github.com/pingcap/tidb/pkg/parser/model" plannercore "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/memo" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/testkit/testdata" "github.com/stretchr/testify/require" ) diff --git a/pkg/planner/memo/expr_iterator.go b/pkg/planner/memo/expr_iterator.go index 4d9911d2fbd24..8190306a5a76e 100644 --- a/pkg/planner/memo/expr_iterator.go +++ b/pkg/planner/memo/expr_iterator.go @@ -16,6 +16,7 @@ package memo import ( "container/list" + "github.com/pingcap/tidb/pkg/planner/pattern" ) diff --git a/pkg/planner/memo/expr_iterator_test.go b/pkg/planner/memo/expr_iterator_test.go index 1ba7330bcf8cd..9a869341012fb 100644 --- a/pkg/planner/memo/expr_iterator_test.go +++ b/pkg/planner/memo/expr_iterator_test.go @@ -15,12 +15,12 @@ package memo import ( - "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" "github.com/pingcap/tidb/pkg/expression" plannercore "github.com/pingcap/tidb/pkg/planner/core" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/stretchr/testify/require" "go.opencensus.io/stats/view" ) diff --git a/pkg/planner/memo/group.go b/pkg/planner/memo/group.go index 9013ab815e6dc..7f2549949df0c 100644 --- a/pkg/planner/memo/group.go +++ b/pkg/planner/memo/group.go @@ -17,10 +17,10 @@ package memo import ( "container/list" "fmt" - "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/expression" plannercore "github.com/pingcap/tidb/pkg/planner/core" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" ) diff --git a/pkg/planner/memo/group_test.go b/pkg/planner/memo/group_test.go index f373edad6dd05..ae4e676b17df7 100644 --- a/pkg/planner/memo/group_test.go +++ b/pkg/planner/memo/group_test.go @@ -16,7 +16,6 @@ package memo import ( "context" - "github.com/pingcap/tidb/pkg/planner/pattern" "testing" "github.com/pingcap/tidb/pkg/domain" @@ -25,6 +24,7 @@ import ( "github.com/pingcap/tidb/pkg/parser" "github.com/pingcap/tidb/pkg/parser/model" plannercore "github.com/pingcap/tidb/pkg/planner/core" + "github.com/pingcap/tidb/pkg/planner/pattern" "github.com/pingcap/tidb/pkg/planner/property" "github.com/pingcap/tidb/pkg/sessionctx/variable" "github.com/stretchr/testify/require" From 2a23a1a59d1d0a1a0aea6ea09f8ac9670a390459 Mon Sep 17 00:00:00 2001 From: AilinKid <314806019@qq.com> Date: Wed, 27 Mar 2024 10:43:20 +0800 Subject: [PATCH 3/3] . Signed-off-by: AilinKid <314806019@qq.com> --- pkg/planner/cascades/optimize_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/planner/cascades/optimize_test.go b/pkg/planner/cascades/optimize_test.go index e9f4f3929525e..7276cf3a0d08b 100644 --- a/pkg/planner/cascades/optimize_test.go +++ b/pkg/planner/cascades/optimize_test.go @@ -213,7 +213,7 @@ func TestAppliedRuleSet(t *testing.T) { optimizer := NewOptimizer() rule := fakeTransformation{} - rule.pattern = pattern.NewPattern(pattern.OperandProjection, memo.EngineAll) + rule.pattern = pattern.NewPattern(pattern.OperandProjection, pattern.EngineAll) optimizer.ResetTransformationRules(map[pattern.Operand][]Transformation{ pattern.OperandProjection: { &rule,