From c4befe61bce4f174192e60d9385cdd0268a0a993 Mon Sep 17 00:00:00 2001 From: HuaiyuXu <391585975@qq.com> Date: Fri, 25 Oct 2019 16:43:13 +0800 Subject: [PATCH] =?UTF-8?q?planner/core:=20do=20not=20change=20window=20as?= =?UTF-8?q?t=20when=20building=20plan=20(#12=E2=80=A6=20(#12934)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- planner/core/logical_plan_builder.go | 10 +++--- planner/core/logical_plan_test.go | 50 +++++++++++++++++++--------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index b172635bc1dde..b196e36146b61 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -3350,7 +3350,10 @@ func (b *PlanBuilder) checkOriginWindowSpecs(funcs []*ast.WindowFuncExpr, orderB if f.FromLast { return ErrNotSupportedYet.GenWithStackByArgs("FROM LAST") } - spec := f.Spec + spec := &f.Spec + if f.Spec.Name.L != "" { + spec = b.windowSpecs[f.Spec.Name.L] + } if spec.Frame == nil { continue } @@ -3371,11 +3374,11 @@ func (b *PlanBuilder) checkOriginWindowSpecs(funcs []*ast.WindowFuncExpr, orderB return ErrWindowFrameIllegal.GenWithStackByArgs(getWindowName(spec.Name.O)) } - err := b.checkOriginWindowFrameBound(&start, &spec, orderByItems) + err := b.checkOriginWindowFrameBound(&start, spec, orderByItems) if err != nil { return err } - err = b.checkOriginWindowFrameBound(&end, &spec, orderByItems) + err = b.checkOriginWindowFrameBound(&end, spec, orderByItems) if err != nil { return err } @@ -3483,7 +3486,6 @@ func (b *PlanBuilder) groupWindowFuncs(windowFuncs []*ast.WindowFuncExpr) (map[* if !ok { return nil, ErrWindowNoSuchWindow.GenWithStackByArgs(windowFunc.Spec.Name.O) } - windowFunc.Spec = *spec newSpec, updated := b.handleDefaultFrame(spec, windowFunc.F) if !updated { groupedWindow[spec] = append(groupedWindow[spec], windowFunc) diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 47c7f24d58ca5..88446a70c998e 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -23,6 +23,7 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/parser" "github.com/pingcap/parser/ast" + "github.com/pingcap/parser/format" "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" @@ -2512,31 +2513,48 @@ func (s *testPlanSuite) TestWindowFunction(c *C) { ctx := context.TODO() for i, tt := range tests { comment := Commentf("case:%v sql:%s", i, tt.sql) - stmt, err := s.ParseOneStmt(tt.sql, "", "") - c.Assert(err, IsNil, comment) - Preprocess(s.ctx, stmt, s.is) - builder := &PlanBuilder{ - ctx: MockContext(), - is: s.is, - colMapper: make(map[*ast.ColumnNameExpr]int), - hintProcessor: &BlockHintProcessor{}, - } - p, err := builder.Build(ctx, stmt) + p, stmt, err := s.optimize(ctx, tt.sql) if err != nil { c.Assert(err.Error(), Equals, tt.result, comment) continue } + c.Assert(ToString(p), Equals, tt.result, comment) + + var sb strings.Builder + // After restore, the result should be the same. + err = stmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags, &sb)) c.Assert(err, IsNil) - p, err = logicalOptimize(ctx, builder.optFlag, p.(LogicalPlan)) - c.Assert(err, IsNil) - lp, ok := p.(LogicalPlan) - c.Assert(ok, IsTrue) - p, err = physicalOptimize(lp) - c.Assert(err, IsNil) + p, _, err = s.optimize(ctx, sb.String()) + if err != nil { + c.Assert(err.Error(), Equals, tt.result, comment) + continue + } c.Assert(ToString(p), Equals, tt.result, comment) } } +func (s *testPlanSuite) optimize(ctx context.Context, sql string) (PhysicalPlan, ast.Node, error) { + stmt, err := s.ParseOneStmt(sql, "", "") + if err != nil { + return nil, nil, err + } + err = Preprocess(s.ctx, stmt, s.is) + if err != nil { + return nil, nil, err + } + builder := NewPlanBuilder(MockContext(), s.is, &BlockHintProcessor{}) + p, err := builder.Build(ctx, stmt) + if err != nil { + return nil, nil, err + } + p, err = logicalOptimize(ctx, builder.optFlag, p.(LogicalPlan)) + if err != nil { + return nil, nil, err + } + p, err = physicalOptimize(p.(LogicalPlan)) + return p.(PhysicalPlan), stmt, err +} + func byItemsToProperty(byItems []*ByItems) *property.PhysicalProperty { pp := &property.PhysicalProperty{} for _, item := range byItems {