From 440eee57411eaa8f9b08a6fd78f124143f6e1d54 Mon Sep 17 00:00:00 2001 From: hanfei19910905 Date: Wed, 4 May 2016 11:07:44 +0800 Subject: [PATCH] push limit for incorrelate subquery. --- executor/subquery.go | 1 + optimizer/plan/planbuilder.go | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/executor/subquery.go b/executor/subquery.go index 121f04924c395..878f82f08a584 100644 --- a/executor/subquery.go +++ b/executor/subquery.go @@ -37,6 +37,7 @@ type subquery struct { func (sq *subquery) EvalRows(ctx context.Context, rowCount int) ([]types.Datum, error) { b := newExecutorBuilder(ctx, sq.is) plan.Refine(sq.plan) + plan.PushLimit(sq.plan, &ast.Limit{Count: 1}) e := b.build(sq.plan) if b.err != nil { return nil, errors.Trace(b.err) diff --git a/optimizer/plan/planbuilder.go b/optimizer/plan/planbuilder.go index 345665f5d4d15..bdc0e9646e1a5 100644 --- a/optimizer/plan/planbuilder.go +++ b/optimizer/plan/planbuilder.go @@ -266,7 +266,7 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) Plan { } if sel.Limit != nil { if canPushLimit { - pushLimit(p, sel.Limit) + PushLimit(p, sel.Limit) } p = b.buildLimit(p, sel.Limit) if b.err != nil { @@ -594,7 +594,8 @@ func buildResultField(tableName, name string, tp byte, size int) *ast.ResultFiel } } -func pushLimit(p Plan, limit *ast.Limit) { +// PushLimit tries to push limit count to the plan. +func PushLimit(p Plan, limit *ast.Limit) { switch x := p.(type) { case *IndexScan: limitCount := int64(limit.Offset + limit.Count) @@ -605,7 +606,7 @@ func pushLimit(p Plan, limit *ast.Limit) { default: child := x.GetChildByIndex(0) if child != nil { - pushLimit(child, limit) + PushLimit(child, limit) } } } @@ -812,7 +813,7 @@ func (b *planBuilder) buildUpdate(update *ast.UpdateStmt) Plan { } } if sel.Limit != nil { - pushLimit(p, sel.Limit) + PushLimit(p, sel.Limit) p = b.buildLimit(p, sel.Limit) if b.err != nil { return nil @@ -851,7 +852,7 @@ func (b *planBuilder) buildDelete(del *ast.DeleteStmt) Plan { } } if sel.Limit != nil { - pushLimit(p, sel.Limit) + PushLimit(p, sel.Limit) p = b.buildLimit(p, sel.Limit) if b.err != nil { return nil