From 5ee7206c857493f66977782214e2a075c62fdf44 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Tue, 18 May 2021 15:31:58 +0800 Subject: [PATCH 01/15] refine name --- planner/core/exhaust_physical_plans.go | 26 ++++++++++---------- planner/core/find_best_task.go | 10 ++++---- planner/core/task.go | 34 +++++++++++++------------- planner/property/physical_property.go | 28 ++++++++++----------- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index 0d8b183a6900a..02a714b060d42 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -1687,7 +1687,7 @@ func (p *LogicalJoin) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]P if prop.IsFlashProp() && ((p.preferJoinType&preferBCJoin) == 0 && p.preferJoinType > 0) { return nil, false, nil } - if prop.PartitionTp == property.BroadcastType { + if prop.MPPPartitionTp == property.BroadcastType { return nil, false, nil } joins := make([]PhysicalPlan, 0, 8) @@ -1785,7 +1785,7 @@ func (p *LogicalJoin) tryToGetMppHashJoin(prop *property.PhysicalProperty, useBC return nil } - if prop.PartitionTp == property.BroadcastType { + if prop.MPPPartitionTp == property.BroadcastType { return nil } if !canExprsInJoinPushdown(p, kv.TiFlash) { @@ -1828,27 +1828,27 @@ func (p *LogicalJoin) tryToGetMppHashJoin(prop *property.PhysicalProperty, useBC baseJoin.InnerChildIdx = preferredBuildIndex childrenProps := make([]*property.PhysicalProperty, 2) if useBCJ { - childrenProps[preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.BroadcastType, CanAddEnforcer: true} + childrenProps[preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.BroadcastType, CanAddEnforcer: true} expCnt := math.MaxFloat64 if prop.ExpectedCnt < p.stats.RowCount { expCntScale := prop.ExpectedCnt / p.stats.RowCount expCnt = p.children[1-preferredBuildIndex].statsInfo().RowCount * expCntScale } - if prop.PartitionTp == property.HashType { + if prop.MPPPartitionTp == property.HashType { hashKeys := rkeys if preferredBuildIndex == 1 { hashKeys = lkeys } if matches := prop.IsSubsetOf(hashKeys); len(matches) != 0 { - childrenProps[1-preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: expCnt, PartitionTp: property.HashType, PartitionCols: prop.PartitionCols} + childrenProps[1-preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: expCnt, MPPPartitionTp: property.HashType, MPPPartitionCols: prop.MPPPartitionCols} } else { return nil } } else { - childrenProps[1-preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: expCnt, PartitionTp: property.AnyType} + childrenProps[1-preferredBuildIndex] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: expCnt, MPPPartitionTp: property.AnyType} } } else { - if prop.PartitionTp == property.HashType { + if prop.MPPPartitionTp == property.HashType { var matches []int if matches = prop.IsSubsetOf(lkeys); len(matches) == 0 { matches = prop.IsSubsetOf(rkeys) @@ -1859,8 +1859,8 @@ func (p *LogicalJoin) tryToGetMppHashJoin(prop *property.PhysicalProperty, useBC lkeys = chooseSubsetOfJoinKeys(lkeys, matches) rkeys = chooseSubsetOfJoinKeys(rkeys, matches) } - childrenProps[0] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.HashType, PartitionCols: lkeys, CanAddEnforcer: true} - childrenProps[1] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.HashType, PartitionCols: rkeys, CanAddEnforcer: true} + childrenProps[0] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.HashType, MPPPartitionCols: lkeys, CanAddEnforcer: true} + childrenProps[1] = &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.HashType, MPPPartitionCols: rkeys, CanAddEnforcer: true} } join := PhysicalHashJoin{ basePhysicalJoin: baseJoin, @@ -2344,13 +2344,13 @@ func (la *LogicalAggregation) tryToGetMppHashAggs(prop *property.PhysicalPropert if prop.TaskTp != property.RootTaskType && prop.TaskTp != property.MppTaskType { return nil } - if prop.PartitionTp == property.BroadcastType { + if prop.MPPPartitionTp == property.BroadcastType { return nil } if len(la.GroupByItems) > 0 { partitionCols := la.GetGroupByCols() // trying to match the required parititions. - if prop.PartitionTp == property.HashType { + if prop.MPPPartitionTp == property.HashType { if matches := prop.IsSubsetOf(partitionCols); len(matches) != 0 { partitionCols = chooseSubsetOfJoinKeys(partitionCols, matches) } else { @@ -2363,7 +2363,7 @@ func (la *LogicalAggregation) tryToGetMppHashAggs(prop *property.PhysicalPropert // If there are no available partition cols, but still have group by items, that means group by items are all expressions or constants. // To avoid mess, we don't do any one-phase aggregation in this case. if len(partitionCols) != 0 { - childProp := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.HashType, PartitionCols: partitionCols, CanAddEnforcer: true} + childProp := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.HashType, MPPPartitionCols: partitionCols, CanAddEnforcer: true} agg := NewPhysicalHashAgg(la, la.stats.ScaleByExpectCnt(prop.ExpectedCnt), childProp) agg.SetSchema(la.schema.Clone()) agg.MppRunMode = Mpp1Phase @@ -2371,7 +2371,7 @@ func (la *LogicalAggregation) tryToGetMppHashAggs(prop *property.PhysicalPropert } // 2-phase agg - childProp := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.AnyType} + childProp := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.AnyType} agg := NewPhysicalHashAgg(la, la.stats.ScaleByExpectCnt(prop.ExpectedCnt), childProp) agg.SetSchema(la.schema.Clone()) agg.MppRunMode = Mpp2Phase diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index a9d82d308acc5..2495208a247f6 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -328,8 +328,8 @@ func (p *baseLogicalPlan) findBestTask(prop *property.PhysicalProperty, planCoun // try to get the task with an enforced sort. newProp.SortItems = []property.SortItem{} newProp.ExpectedCnt = math.MaxFloat64 - newProp.PartitionCols = nil - newProp.PartitionTp = property.AnyType + newProp.MPPPartitionCols = nil + newProp.MPPPartitionTp = property.AnyType var hintCanWork bool plansNeedEnforce, hintCanWork, err = p.self.exhaustPhysicalPlans(newProp) if err != nil { @@ -644,8 +644,8 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter } // Next, get the bestTask with enforced prop prop.SortItems = []property.SortItem{} - prop.PartitionTp = property.AnyType - } else if prop.PartitionTp != property.AnyType { + prop.MPPPartitionTp = property.AnyType + } else if prop.MPPPartitionTp != property.AnyType { return invalidTask, 0, nil } defer func() { @@ -1546,7 +1546,7 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid if ts.KeepOrder { return &mppTask{}, nil } - if prop.PartitionTp != property.AnyType || ts.isPartition { + if prop.MPPPartitionTp != property.AnyType || ts.isPartition { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. return &mppTask{}, nil } diff --git a/planner/core/task.go b/planner/core/task.go index c1b925451ca1b..afd5df49e0adf 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -728,9 +728,9 @@ func (p *PhysicalHashJoin) convertPartitionKeysIfNeed(lTask, rTask *mppTask) (*m nlTask := lTask.copy().(*mppTask) nlTask.p = lProj nlTask = nlTask.enforceExchangerImpl(&property.PhysicalProperty{ - TaskTp: property.MppTaskType, - PartitionTp: property.HashType, - PartitionCols: lPartKeys, + TaskTp: property.MppTaskType, + MPPPartitionTp: property.HashType, + MPPPartitionCols: lPartKeys, }) nlTask.cst = lTask.cst lProj.cost = nlTask.cst @@ -740,9 +740,9 @@ func (p *PhysicalHashJoin) convertPartitionKeysIfNeed(lTask, rTask *mppTask) (*m nrTask := rTask.copy().(*mppTask) nrTask.p = rProj nrTask = nrTask.enforceExchangerImpl(&property.PhysicalProperty{ - TaskTp: property.MppTaskType, - PartitionTp: property.HashType, - PartitionCols: rPartKeys, + TaskTp: property.MppTaskType, + MPPPartitionTp: property.HashType, + MPPPartitionCols: rPartKeys, }) nrTask.cst = rTask.cst rProj.cost = nrTask.cst @@ -1890,7 +1890,7 @@ func (p *PhysicalHashAgg) attach2TaskForMpp(tasks ...task) task { } } partialAgg.SetCost(mpp.cost()) - prop := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, PartitionTp: property.HashType, PartitionCols: partitionCols} + prop := &property.PhysicalProperty{TaskTp: property.MppTaskType, ExpectedCnt: math.MaxFloat64, MPPPartitionTp: property.HashType, MPPPartitionCols: partitionCols} newMpp := mpp.enforceExchangerImpl(prop) if newMpp.invalid() { return newMpp @@ -2021,7 +2021,7 @@ type mppTask struct { p PhysicalPlan cst float64 - partTp property.PartitionType + partTp property.MPPPartitionType hashCols []*expression.Column } @@ -2079,7 +2079,7 @@ func (t *mppTask) convertToRootTaskImpl(ctx sessionctx.Context) *rootTask { } func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { - switch prop.PartitionTp { + switch prop.MPPPartitionTp { case property.AnyType: return false case property.BroadcastType: @@ -2089,10 +2089,10 @@ func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { return true } // TODO: consider equalivant class - if len(prop.PartitionCols) != len(t.hashCols) { + if len(prop.MPPPartitionCols) != len(t.hashCols) { return true } - for i, col := range prop.PartitionCols { + for i, col := range prop.MPPPartitionCols { if !col.Equal(nil, t.hashCols[i]) { return true } @@ -2112,8 +2112,8 @@ func (t *mppTask) enforceExchanger(prop *property.PhysicalProperty) *mppTask { } func (t *mppTask) enforceExchangerImpl(prop *property.PhysicalProperty) *mppTask { - if collate.NewCollationEnabled() && prop.PartitionTp == property.HashType { - for _, col := range prop.PartitionCols { + if collate.NewCollationEnabled() && prop.MPPPartitionTp == property.HashType { + for _, col := range prop.MPPPartitionCols { if types.IsString(col.RetType.Tp) { return &mppTask{cst: math.MaxFloat64} } @@ -2121,8 +2121,8 @@ func (t *mppTask) enforceExchangerImpl(prop *property.PhysicalProperty) *mppTask } ctx := t.p.SCtx() sender := PhysicalExchangeSender{ - ExchangeType: tipb.ExchangeType(prop.PartitionTp), - HashCols: prop.PartitionCols, + ExchangeType: tipb.ExchangeType(prop.MPPPartitionTp), + HashCols: prop.MPPPartitionCols, }.Init(ctx, t.p.statsInfo()) sender.SetChildren(t.p) receiver := PhysicalExchangeReceiver{}.Init(ctx, t.p.statsInfo()) @@ -2133,7 +2133,7 @@ func (t *mppTask) enforceExchangerImpl(prop *property.PhysicalProperty) *mppTask return &mppTask{ p: receiver, cst: cst, - partTp: prop.PartitionTp, - hashCols: prop.PartitionCols, + partTp: prop.MPPPartitionTp, + hashCols: prop.MPPPartitionCols, } } diff --git a/planner/property/physical_property.go b/planner/property/physical_property.go index 8ddb1a6212437..51cf72572fc9d 100644 --- a/planner/property/physical_property.go +++ b/planner/property/physical_property.go @@ -30,12 +30,12 @@ type SortItem struct { Desc bool } -// PartitionType is the way to partition during mpp data exchanging. -type PartitionType int +// MPPPartitionType is the way to partition during mpp data exchanging. +type MPPPartitionType int const ( // AnyType will not require any special partition types. - AnyType PartitionType = iota + AnyType MPPPartitionType = iota // BroadcastType requires current task to broadcast its data. BroadcastType // HashType requires current task to shuffle its data according to some columns. @@ -70,10 +70,10 @@ type PhysicalProperty struct { CanAddEnforcer bool // If the partition type is hash, the data should be reshuffled by partition cols. - PartitionCols []*expression.Column + MPPPartitionCols []*expression.Column // which types the exchange sender belongs to, only take effects when it's a mpp task. - PartitionTp PartitionType + MPPPartitionTp MPPPartitionType } // NewPhysicalProperty builds property from columns. @@ -97,11 +97,11 @@ func SortItemsFromCols(cols []*expression.Column, desc bool) []SortItem { // IsSubsetOf check if the keys can match the needs of partition. func (p *PhysicalProperty) IsSubsetOf(keys []*expression.Column) []int { - if len(p.PartitionCols) > len(keys) { + if len(p.MPPPartitionCols) > len(keys) { return nil } matches := make([]int, 0, len(keys)) - for _, partCol := range p.PartitionCols { + for _, partCol := range p.MPPPartitionCols { found := false for i, key := range keys { if partCol.Equal(nil, key) { @@ -183,8 +183,8 @@ func (p *PhysicalProperty) HashCode() []byte { } } if p.TaskTp == MppTaskType { - p.hashcode = codec.EncodeInt(p.hashcode, int64(p.PartitionTp)) - for _, col := range p.PartitionCols { + p.hashcode = codec.EncodeInt(p.hashcode, int64(p.MPPPartitionTp)) + for _, col := range p.MPPPartitionCols { p.hashcode = append(p.hashcode, col.HashCode(nil)...) } } @@ -200,11 +200,11 @@ func (p *PhysicalProperty) String() string { // property, specifically, `CanAddEnforcer` should not be included. func (p *PhysicalProperty) CloneEssentialFields() *PhysicalProperty { prop := &PhysicalProperty{ - SortItems: p.SortItems, - TaskTp: p.TaskTp, - ExpectedCnt: p.ExpectedCnt, - PartitionTp: p.PartitionTp, - PartitionCols: p.PartitionCols, + SortItems: p.SortItems, + TaskTp: p.TaskTp, + ExpectedCnt: p.ExpectedCnt, + MPPPartitionTp: p.MPPPartitionTp, + MPPPartitionCols: p.MPPPartitionCols, } return prop } From 1cba06f204de95543fdf2086f14b8ea80d17c032 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Fri, 4 Jun 2021 15:16:57 +0800 Subject: [PATCH 02/15] name refine --- planner/core/exhaust_physical_plans.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index 02a714b060d42..e2270b734ac49 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -2552,7 +2552,7 @@ func (p *LogicalUnionAll) exhaustPhysicalPlans(prop *property.PhysicalProperty) return nil, true, nil } // TODO: UnionAll can pass partition info, but for briefness, we prevent it from pushing down. - if prop.TaskTp == property.MppTaskType && prop.PartitionTp != property.AnyType { + if prop.TaskTp == property.MppTaskType && prop.MPPPartitionTp != property.AnyType { return nil, true, nil } canUseMpp := p.ctx.GetSessionVars().IsMPPAllowed() && p.canPushToCop(kv.TiFlash) From a32a342480b285ecaa660d779118b8724ff0c35f Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Mon, 7 Jun 2021 11:56:36 +0800 Subject: [PATCH 03/15] middle stash --- planner/core/exhaust_physical_plans.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index d088233cd0593..4da96cd9776de 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -16,6 +16,7 @@ package core import ( "bytes" "fmt" + "github.com/pingcap/errors" "math" "sort" @@ -41,6 +42,9 @@ import ( func (p *LogicalUnionScan) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { + if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `UnionScan` is not supported now.")) + } return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2096,6 +2100,9 @@ func (la *LogicalApply) GetHashJoin(prop *property.PhysicalProperty) *PhysicalHa func (la *LogicalApply) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.AllColsFromSchema(la.children[0].Schema()) || prop.IsFlashProp() { // for convenient, we don't pass through any prop + if vars := la.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Apply` is not supported now.")) + } return nil, true, nil } disableAggPushDownToCop(la.children[0]) @@ -2142,6 +2149,9 @@ func disableAggPushDownToCop(p LogicalPlan) { } func (p *LogicalWindow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { + if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Window` is not supported now.")) + } if prop.IsFlashProp() { return nil, true, nil } @@ -2181,13 +2191,16 @@ func (p *baseLogicalPlan) canPushToCop(storeTp kv.StoreType) bool { } } ret = ret && validDs - case *LogicalAggregation, *LogicalProjection, *LogicalSelection, *LogicalJoin, *LogicalUnionAll: + case *LogicalAggregation, *LogicalProjection, *LogicalSelection, *LogicalJoin, *LogicalUnionAll, *LogicalLimit, *LogicalTopN: if storeTp == kv.TiFlash { ret = ret && c.canPushToCop(storeTp) } else { return false } default: + if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `" + c.TP() + "` is not supported now.")) + } return false } } @@ -2411,7 +2424,7 @@ func (la *LogicalAggregation) getHashAggs(prop *property.PhysicalProperty) []Phy taskTypes = append(taskTypes, property.CopTiFlashLocalReadTaskType) } canPushDownToTiFlash := la.canPushToCop(kv.TiFlash) - canPushDownToMPP := la.ctx.GetSessionVars().IsMPPAllowed() && la.checkCanPushDownToMPP() && canPushDownToTiFlash + canPushDownToMPP := canPushDownToTiFlash && la.ctx.GetSessionVars().IsMPPAllowed() && la.checkCanPushDownToMPP() if la.HasDistinct() { // TODO: remove after the cost estimation of distinct pushdown is implemented. if !la.ctx.GetSessionVars().AllowDistinctAggPushDown { @@ -2539,6 +2552,9 @@ func (p *LogicalLimit) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalLock) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { + if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Lock` is not supported now.")) + } return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2632,6 +2648,9 @@ func (ls *LogicalSort) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalMaxOneRow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.IsEmpty() || prop.IsFlashProp() { + if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `MaxOneRow` is not supported now.")) + } return nil, true, nil } mor := PhysicalMaxOneRow{}.Init(p.ctx, p.stats, p.blockOffset, &property.PhysicalProperty{ExpectedCnt: 2}) From 025b66559167270870f503629f5b3d3093c00beb Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Mon, 7 Jun 2021 11:57:11 +0800 Subject: [PATCH 04/15] middle stash --- planner/core/find_best_task.go | 6 ++++++ planner/core/task.go | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index 0c3a92b85dbc7..0c16c3d6dd239 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -1548,10 +1548,16 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } if prop.MPPPartitionTp != property.AnyType || ts.isPartition { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. + if vars := ds.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because this table is a partition table.")) + } return &mppTask{}, nil } for _, col := range ts.schema.Columns { if col.VirtualExpr != nil { + if vars := ds.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because column `" + col.OrigName + "` is virtual.")) + } return &mppTask{}, nil } } diff --git a/planner/core/task.go b/planner/core/task.go index 7b6f2109aaf6c..6f9ab17b7520f 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -1392,6 +1392,9 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc for _, aggFunc := range aggFuncs { // if the aggFunc contain VirtualColumn or CorrelatedColumn, it can not be pushed down. if expression.ContainVirtualColumn(aggFunc.Args) || expression.ContainCorrelatedColumn(aggFunc.Args) { + if sctx.GetSessionVars().IsMPPEnforced() && sc.InExplainStmt { + sc.AppendWarning(errors.New("Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column.")) + } return false } pb := aggregation.AggFuncToPBExpr(sc, client, aggFunc) @@ -1413,6 +1416,9 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc } } if expression.ContainVirtualColumn(groupByItems) { + if sctx.GetSessionVars().IsMPPEnforced() && sc.InExplainStmt { + sc.AppendWarning(errors.New("Can't use mpp mode because groupByItems contain virtual column.")) + } return false } return expression.CanExprsPushDown(sc, groupByItems, client, storeType) @@ -2113,6 +2119,9 @@ func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { func (t *mppTask) enforceExchanger(prop *property.PhysicalProperty) *mppTask { if len(prop.SortItems) != 0 { + if vars := t.p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { + vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because sorted item is not supported now.")) + } return &mppTask{} } if !t.needEnforce(prop) { From 8d610e96ef4225153be9216b8e5a9cdfc04a5291 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Tue, 8 Jun 2021 14:08:22 +0800 Subject: [PATCH 05/15] change `set 0` to `divide 1e9` in order to keep order. --- planner/core/task.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/task.go b/planner/core/task.go index 6f9ab17b7520f..83659690fc8ba 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -2085,7 +2085,7 @@ func (t *mppTask) convertToRootTaskImpl(ctx sessionctx.Context) *rootTask { cst := t.cst + t.count()*ctx.GetSessionVars().GetNetworkFactor(nil) p.cost = cst / p.ctx.GetSessionVars().CopTiFlashConcurrencyFactor if p.ctx.GetSessionVars().IsMPPEnforced() { - p.cost = 0 + p.cost = cst / 1000000000 } rt := &rootTask{ p: p, From f1bc5ea2d118963b333e920f6251f8f312cb5859 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Tue, 8 Jun 2021 14:38:12 +0800 Subject: [PATCH 06/15] refine variables. --- sessionctx/variable/session.go | 18 +++++++++++++----- sessionctx/variable/sysvar.go | 13 +++++++++++-- sessionctx/variable/tidb_vars.go | 14 +++++++++++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 93db60de55e50..8b2b38015321d 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -508,9 +508,16 @@ type SessionVars struct { // Value set to 2 means to force to send batch cop for any query. Value set to 0 means never use batch cop. AllowBatchCop int - // AllowMPPExecution means if we should use mpp way to execute query. Default value is "ON", means to be determined by the optimizer. - // Value set to "ENFORCE" means to use mpp whenever possible. Value set to means never use mpp. - allowMPPExecution string + // allowMPPExecution means if we should use mpp way to execute query. + // Default value is `true`, means to be determined by the optimizer. + // Value set to `false` means never use mpp. + allowMPPExecution bool + + // enforceMPPExecution means if we should enforce mpp way to execute query. + // Default value is `false`, means to be determined by variable `allowMPPExecution`. + // Value set to `true` means enforce use mpp. + // Note if you want to set `enforceMPPExecution` to `true`, you must set `allowMPPExecution` to `true` first. + enforceMPPExecution bool // TiDBAllowAutoRandExplicitInsert indicates whether explicit insertion on auto_random column is allowed. AllowAutoRandExplicitInsert bool @@ -857,12 +864,12 @@ func (s *SessionVars) AllocMPPTaskID(startTS uint64) int64 { // IsMPPAllowed returns whether mpp execution is allowed. func (s *SessionVars) IsMPPAllowed() bool { - return s.allowMPPExecution != "OFF" + return s.allowMPPExecution } // IsMPPEnforced returns whether mpp execution is enforced. func (s *SessionVars) IsMPPEnforced() bool { - return s.allowMPPExecution == "ENFORCE" + return s.allowMPPExecution && s.enforceMPPExecution } // CheckAndGetTxnScope will return the transaction scope we should use in the current session. @@ -1093,6 +1100,7 @@ func NewSessionVars() *SessionVars { vars.AllowBatchCop = DefTiDBAllowBatchCop vars.allowMPPExecution = DefTiDBAllowMPPExecution + vars.enforceMPPExecution = DefTiDBEnforceMPPExecution var enableChunkRPC string if config.GetGlobalConfig().TiKVClient.EnableChunkRPC { diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 4c4bd38b14d5b..07764aeddc541 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -836,8 +836,17 @@ var defaultSysVars = []*SysVar{ } return normalizedValue, nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBAllowMPPExecution, Value: On, Type: TypeEnum, PossibleValues: []string{"OFF", "ON", "ENFORCE"}, SetSession: func(s *SessionVars, val string) error { - s.allowMPPExecution = val + {Scope: ScopeGlobal | ScopeSession, Name: TiDBAllowMPPExecution, Type: TypeBool, Value: BoolToOnOff(DefTiDBAllowMPPExecution), SetSession: func(s *SessionVars, val string) error { + s.allowMPPExecution = TiDBOptOn(val) + return nil + }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnforceMPPExecution, Type: TypeBool, Value: BoolToOnOff(DefTiDBEnforceMPPExecution), Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + if TiDBOptOn(normalizedValue) && !vars.allowMPPExecution { + return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs("Can't set tidb_enforce_mpp to 1 but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.") + } + return normalizedValue, nil + }, SetSession: func(s *SessionVars, val string) error { + s.enforceMPPExecution = TiDBOptOn(val) return nil }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBBCJThresholdCount, Value: strconv.Itoa(DefBroadcastJoinThresholdCount), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt64, SetSession: func(s *SessionVars, val string) error { diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index e93414bc5e26e..8382eb8c9fc24 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -299,10 +299,17 @@ const ( // The default value is 0 TiDBAllowBatchCop = "tidb_allow_batch_cop" - // TiDBAllowMPPExecution means if we should use mpp way to execute query. Default value is 1 (or 'ON'), means to be determined by the optimizer. - // Value set to 2 (or 'ENFORCE') which means to use mpp whenever possible. Value set to 2 (or 'OFF') means never use mpp. + // TiDBAllowMPPExecution means if we should use mpp way to execute query. + // Default value is `true`, means to be determined by the optimizer. + // Value set to `false` means never use mpp. TiDBAllowMPPExecution = "tidb_allow_mpp" + // TiDBEnforceMPPExecution means if we should enforce mpp way to execute query. + // Default value is `false`, means to be determined by variable `tidb_allow_mpp`. + // Value set to `true` means enforce use mpp. + // Note if you want to set `tidb_enforce_mpp` to `true`, you must set `tidb_allow_mpp` to `true` first. + TiDBEnforceMPPExecution = "tidb_enforce_mpp" + // TiDBInitChunkSize is used to control the init chunk size during query execution. TiDBInitChunkSize = "tidb_init_chunk_size" @@ -642,7 +649,8 @@ const ( DefBroadcastJoinThresholdCount = 10 * 1024 DefTiDBOptimizerSelectivityLevel = 0 DefTiDBAllowBatchCop = 1 - DefTiDBAllowMPPExecution = "ON" + DefTiDBAllowMPPExecution = true + DefTiDBEnforceMPPExecution = false DefTiDBTxnMode = "" DefTiDBRowFormatV1 = 1 DefTiDBRowFormatV2 = 2 From 45cd9442316e0b0c9a8d1140a4d0b1f6737a5cde Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Tue, 8 Jun 2021 18:00:17 +0800 Subject: [PATCH 07/15] refine call. --- planner/core/exhaust_physical_plans.go | 30 ++++++++++---------------- planner/core/find_best_task.go | 8 ++----- planner/core/task.go | 13 ++++------- sessionctx/variable/session.go | 10 +++++++++ 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index 4da96cd9776de..451415aecc444 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -16,7 +16,6 @@ package core import ( "bytes" "fmt" - "github.com/pingcap/errors" "math" "sort" @@ -42,9 +41,8 @@ import ( func (p *LogicalUnionScan) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { - if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `UnionScan` is not supported now.")) - } + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because operator `UnionScan` is not supported now.") return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2100,9 +2098,8 @@ func (la *LogicalApply) GetHashJoin(prop *property.PhysicalProperty) *PhysicalHa func (la *LogicalApply) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.AllColsFromSchema(la.children[0].Schema()) || prop.IsFlashProp() { // for convenient, we don't pass through any prop - if vars := la.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Apply` is not supported now.")) - } + la.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because operator `Apply` is not supported now.") return nil, true, nil } disableAggPushDownToCop(la.children[0]) @@ -2149,9 +2146,8 @@ func disableAggPushDownToCop(p LogicalPlan) { } func (p *LogicalWindow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { - if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Window` is not supported now.")) - } + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because operator `Window` is not supported now.") if prop.IsFlashProp() { return nil, true, nil } @@ -2198,9 +2194,8 @@ func (p *baseLogicalPlan) canPushToCop(storeTp kv.StoreType) bool { return false } default: - if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `" + c.TP() + "` is not supported now.")) - } + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because operator `" + c.TP() + "` is not supported now.") return false } } @@ -2552,9 +2547,8 @@ func (p *LogicalLimit) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalLock) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { - if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `Lock` is not supported now.")) - } + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because operator `Lock` is not supported now.") return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2648,9 +2642,7 @@ func (ls *LogicalSort) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalMaxOneRow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.IsEmpty() || prop.IsFlashProp() { - if vars := p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because operator `MaxOneRow` is not supported now.")) - } + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because operator `MaxOneRow` is not supported now.") return nil, true, nil } mor := PhysicalMaxOneRow{}.Init(p.ctx, p.stats, p.blockOffset, &property.PhysicalProperty{ExpectedCnt: 2}) diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index 0c16c3d6dd239..8ac8800091fc9 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -1548,16 +1548,12 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } if prop.MPPPartitionTp != property.AnyType || ts.isPartition { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. - if vars := ds.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because this table is a partition table.")) - } + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because this table is a partition table.") return &mppTask{}, nil } for _, col := range ts.schema.Columns { if col.VirtualExpr != nil { - if vars := ds.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because column `" + col.OrigName + "` is virtual.")) - } + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because column `" + col.OrigName + "` is virtual.") return &mppTask{}, nil } } diff --git a/planner/core/task.go b/planner/core/task.go index 83659690fc8ba..0cc89a10dda58 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -1392,9 +1392,8 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc for _, aggFunc := range aggFuncs { // if the aggFunc contain VirtualColumn or CorrelatedColumn, it can not be pushed down. if expression.ContainVirtualColumn(aggFunc.Args) || expression.ContainCorrelatedColumn(aggFunc.Args) { - if sctx.GetSessionVars().IsMPPEnforced() && sc.InExplainStmt { - sc.AppendWarning(errors.New("Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column.")) - } + sctx.GetSessionVars().RaiseWarningWhenMPPEnforced( + "Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column.") return false } pb := aggregation.AggFuncToPBExpr(sc, client, aggFunc) @@ -1416,9 +1415,7 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc } } if expression.ContainVirtualColumn(groupByItems) { - if sctx.GetSessionVars().IsMPPEnforced() && sc.InExplainStmt { - sc.AppendWarning(errors.New("Can't use mpp mode because groupByItems contain virtual column.")) - } + sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because groupByItems contain virtual column.") return false } return expression.CanExprsPushDown(sc, groupByItems, client, storeType) @@ -2119,9 +2116,7 @@ func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { func (t *mppTask) enforceExchanger(prop *property.PhysicalProperty) *mppTask { if len(prop.SortItems) != 0 { - if vars := t.p.SCtx().GetSessionVars(); vars.IsMPPEnforced() && vars.StmtCtx.InExplainStmt { - vars.StmtCtx.AppendWarning(errors.New("Can't use mpp mode because sorted item is not supported now.")) - } + t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because sorted item is not supported now.") return &mppTask{} } if !t.needEnforce(prop) { diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 8b2b38015321d..98126a39845bb 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -18,6 +18,7 @@ import ( "crypto/tls" "encoding/binary" "fmt" + "github.com/pingcap/errors" "math" "math/rand" "net" @@ -872,6 +873,15 @@ func (s *SessionVars) IsMPPEnforced() bool { return s.allowMPPExecution && s.enforceMPPExecution } +// RaiseWarningWhenMPPEnforced will raise a warning when mpp mode is enforced and executing explain statement. +// TODO: Confirm whether this function will be inlined and +// omit the overhead of string construction when calling with false condition. +func (s *SessionVars) RaiseWarningWhenMPPEnforced(warning string) { + if s.IsMPPEnforced() && s.StmtCtx.InExplainStmt { + s.StmtCtx.AppendWarning(errors.New(warning)) + } +} + // CheckAndGetTxnScope will return the transaction scope we should use in the current session. func (s *SessionVars) CheckAndGetTxnScope() string { if s.InRestrictedSQL { From e8d0b83507577e78179208bc0003dc58de737bf3 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Wed, 9 Jun 2021 17:25:29 +0800 Subject: [PATCH 08/15] add warning. --- planner/core/logical_plan_builder.go | 2 ++ planner/core/planbuilder.go | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index e575bb79e7135..84e00ecda5d12 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -619,6 +619,8 @@ func (ds *DataSource) setPreferredStoreType(hintInfo *tableHintInfo) { ds.DBName.O, ds.table.Meta().Name.O, kv.TiKV.Name(), ds.ctx.GetSessionVars().GetIsolationReadEngines()) warning := ErrInternal.GenWithStack(errMsg) ds.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) + } else { + ds.ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("can't use mpp mode because you set a hint to read table `" + hintTbl.tblName.O + "` from TiKV.") } } if hintTbl := hintInfo.ifPreferTiFlash(alias); hintTbl != nil { diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 6b4d4118379f8..a2a94432d37da 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -973,10 +973,16 @@ func getPossibleAccessPaths(ctx sessionctx.Context, tableHints *tableHintInfo, i tablePath := &util.AccessPath{StoreType: tp} fillContentForTablePath(tablePath, tblInfo) publicPaths = append(publicPaths, tablePath) - if tblInfo.TiFlashReplica != nil && tblInfo.TiFlashReplica.Available { + + if tblInfo.TiFlashReplica == nil { + ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because there aren't tiflash replicas of table `" + tblInfo.Name.O + "`.") + } else if !tblInfo.TiFlashReplica.Available { + ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because tiflash replicas of table `" + tblInfo.Name.O + "` not ready.") + } else { publicPaths = append(publicPaths, genTiFlashPath(tblInfo, false)) publicPaths = append(publicPaths, genTiFlashPath(tblInfo, true)) } + optimizerUseInvisibleIndexes := ctx.GetSessionVars().OptimizerUseInvisibleIndexes check = check && ctx.GetSessionVars().ConnectionID > 0 @@ -1110,11 +1116,15 @@ func filterPathByIsolationRead(ctx sessionctx.Context, paths []*util.AccessPath, } } var err error + engineVals, _ := ctx.GetSessionVars().GetSystemVar(variable.TiDBIsolationReadEngines) if len(paths) == 0 { - engineVals, _ := ctx.GetSessionVars().GetSystemVar(variable.TiDBIsolationReadEngines) err = ErrInternal.GenWithStackByArgs(fmt.Sprintf("Can not find access path matching '%v'(value: '%v'). Available values are '%v'.", variable.TiDBIsolationReadEngines, engineVals, availableEngineStr)) } + if _, ok := isolationReadEngines[kv.TiFlash]; !ok { + ctx.GetSessionVars().RaiseWarningWhenMPPEnforced( + fmt.Sprintf("Can't use mpp mode because '%v'(value: '%v') not match, need 'tiflash'.", variable.TiDBIsolationReadEngines, engineVals)) + } return paths, err } From e1ea2abdc9afb334da8cb627fff90da81b26f42a Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Wed, 9 Jun 2021 19:46:00 +0800 Subject: [PATCH 09/15] refine. --- planner/core/exhaust_physical_plans.go | 4 ++-- planner/core/find_best_task.go | 4 ++-- planner/core/logical_plan_builder.go | 2 +- planner/core/task.go | 6 +++--- sessionctx/variable/session.go | 2 +- sessionctx/variable/sysvar.go | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index d8a6fc5c674b6..0e36551b21d68 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -2191,7 +2191,7 @@ func (p *baseLogicalPlan) canPushToCopImpl(storeTp kv.StoreType, considerDual bo } } ret = ret && validDs - case *LogicalUnionAll, *LogicalLimit, *LogicalTopN: + case *LogicalUnionAll: if storeTp == kv.TiFlash { ret = ret && c.canPushToCopImpl(storeTp, true) } else { @@ -2205,7 +2205,7 @@ func (p *baseLogicalPlan) canPushToCopImpl(storeTp kv.StoreType, considerDual bo } case *LogicalTableDual: return storeTp == kv.TiFlash && considerDual - case *LogicalAggregation, *LogicalSelection, *LogicalJoin: + case *LogicalAggregation, *LogicalSelection, *LogicalJoin, *LogicalLimit, *LogicalTopN: if storeTp == kv.TiFlash { ret = ret && c.canPushToCop(storeTp) } else { diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index b0b95d5aaff32..bd5892be3134f 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -1548,12 +1548,12 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } if prop.MPPPartitionTp != property.AnyType || ts.isPartition { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. - ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because this table is a partition table.") + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because table `" + ds.tableInfo.Name.O + "`is a partition table which is not supported when `@@tidb_partition_prune_mode=static`.") return &mppTask{}, nil } for _, col := range ts.schema.Columns { if col.VirtualExpr != nil { - ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because column `" + col.OrigName + "` is virtual.") + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because column `" + col.OrigName + "` is a virtual column which is not supported now.") return &mppTask{}, nil } } diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 84e00ecda5d12..3087b6b229973 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -620,7 +620,7 @@ func (ds *DataSource) setPreferredStoreType(hintInfo *tableHintInfo) { warning := ErrInternal.GenWithStack(errMsg) ds.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) } else { - ds.ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("can't use mpp mode because you set a hint to read table `" + hintTbl.tblName.O + "` from TiKV.") + ds.ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because you have set a hint to read table `" + hintTbl.tblName.O + "` from TiKV.") } } if hintTbl := hintInfo.ifPreferTiFlash(alias); hintTbl != nil { diff --git a/planner/core/task.go b/planner/core/task.go index 4f511ce68e5e1..0f75d448c645a 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -1405,7 +1405,7 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc // if the aggFunc contain VirtualColumn or CorrelatedColumn, it can not be pushed down. if expression.ContainVirtualColumn(aggFunc.Args) || expression.ContainCorrelatedColumn(aggFunc.Args) { sctx.GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column.") + "Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column, which is not supported now.") return false } pb := aggregation.AggFuncToPBExpr(sc, client, aggFunc) @@ -1427,7 +1427,7 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc } } if expression.ContainVirtualColumn(groupByItems) { - sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because groupByItems contain virtual column.") + sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because groupByItems contain virtual column, which is not supported now.") return false } return expression.CanExprsPushDown(sc, groupByItems, client, storeType) @@ -2128,7 +2128,7 @@ func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { func (t *mppTask) enforceExchanger(prop *property.PhysicalProperty) *mppTask { if len(prop.SortItems) != 0 { - t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because sorted item is not supported now.") + t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because operator `Sort` is not supported now.") return &mppTask{} } if !t.needEnforce(prop) { diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 69b53c074c29e..da9e1f5dbff77 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -18,7 +18,6 @@ import ( "crypto/tls" "encoding/binary" "fmt" - "github.com/pingcap/errors" "math" "math/rand" "net" @@ -29,6 +28,7 @@ import ( "sync/atomic" "time" + "github.com/pingcap/errors" "github.com/pingcap/parser" "github.com/pingcap/parser/ast" "github.com/pingcap/parser/auth" diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 500a71a234fc4..9bae95f91d300 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -842,7 +842,7 @@ var defaultSysVars = []*SysVar{ }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnforceMPPExecution, Type: TypeBool, Value: BoolToOnOff(DefTiDBEnforceMPPExecution), Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { if TiDBOptOn(normalizedValue) && !vars.allowMPPExecution { - return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs("Can't set tidb_enforce_mpp to 1 but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.") + return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs("tidb_enforce_mpp", "1' but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.") } return normalizedValue, nil }, SetSession: func(s *SessionVars, val string) error { From 04ac456d6a7cf0133ba312f8f777b52439333ea4 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 13:35:07 +0800 Subject: [PATCH 10/15] address comment. --- planner/core/exhaust_physical_plans.go | 5 ++++- sessionctx/variable/tidb_vars.go | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index 0e36551b21d68..eee2fe2d8336b 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -2205,12 +2205,15 @@ func (p *baseLogicalPlan) canPushToCopImpl(storeTp kv.StoreType, considerDual bo } case *LogicalTableDual: return storeTp == kv.TiFlash && considerDual - case *LogicalAggregation, *LogicalSelection, *LogicalJoin, *LogicalLimit, *LogicalTopN: + case *LogicalAggregation, *LogicalSelection, *LogicalJoin: if storeTp == kv.TiFlash { ret = ret && c.canPushToCop(storeTp) } else { return false } + // These operators can be partially push down to TiFlash, so we don't raise warning for them. + case *LogicalLimit, *LogicalTopN: + return false default: p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( "Can't use mpp mode because operator `" + c.TP() + "` is not supported now.") diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 00c5aa0a557e8..1bc9b3ebaa33f 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -299,12 +299,12 @@ const ( // The default value is 0 TiDBAllowBatchCop = "tidb_allow_batch_cop" - // TiDBAllowMPPExecution means if we should use mpp way to execute query. + // TiDBAllowMPPExecution means if we should use mpp way to execute query or not. // Default value is `true`, means to be determined by the optimizer. // Value set to `false` means never use mpp. TiDBAllowMPPExecution = "tidb_allow_mpp" - // TiDBEnforceMPPExecution means if we should enforce mpp way to execute query. + // TiDBEnforceMPPExecution means if we should enforce mpp way to execute query or not. // Default value is `false`, means to be determined by variable `tidb_allow_mpp`. // Value set to `true` means enforce use mpp. // Note if you want to set `tidb_enforce_mpp` to `true`, you must set `tidb_allow_mpp` to `true` first. From c575b99c07bbfacbfad804a8df9a12ba36eea1fe Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 14:28:20 +0800 Subject: [PATCH 11/15] refine statement. --- planner/core/exhaust_physical_plans.go | 12 ++++++------ planner/core/find_best_task.go | 4 ++-- planner/core/logical_plan_builder.go | 2 +- planner/core/planbuilder.go | 6 +++--- planner/core/task.go | 8 +++++--- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index eee2fe2d8336b..eef51465a072d 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -42,7 +42,7 @@ import ( func (p *LogicalUnionScan) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because operator `UnionScan` is not supported now.") + "MPP mode may be blocked because operator `UnionScan` is not supported now.") return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2099,7 +2099,7 @@ func (la *LogicalApply) GetHashJoin(prop *property.PhysicalProperty) *PhysicalHa func (la *LogicalApply) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.AllColsFromSchema(la.children[0].Schema()) || prop.IsFlashProp() { // for convenient, we don't pass through any prop la.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because operator `Apply` is not supported now.") + "MPP mode may be blocked because operator `Apply` is not supported now.") return nil, true, nil } disableAggPushDownToCop(la.children[0]) @@ -2147,7 +2147,7 @@ func disableAggPushDownToCop(p LogicalPlan) { func (p *LogicalWindow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because operator `Window` is not supported now.") + "MPP mode may be blocked because operator `Window` is not supported now.") if prop.IsFlashProp() { return nil, true, nil } @@ -2216,7 +2216,7 @@ func (p *baseLogicalPlan) canPushToCopImpl(storeTp kv.StoreType, considerDual bo return false default: p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because operator `" + c.TP() + "` is not supported now.") + "MPP mode may be blocked because operator `" + c.TP() + "` is not supported now.") return false } } @@ -2569,7 +2569,7 @@ func (p *LogicalLimit) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalLock) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if prop.IsFlashProp() { p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because operator `Lock` is not supported now.") + "MPP mode may be blocked because operator `Lock` is not supported now.") return nil, true, nil } childProp := prop.CloneEssentialFields() @@ -2663,7 +2663,7 @@ func (ls *LogicalSort) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([] func (p *LogicalMaxOneRow) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]PhysicalPlan, bool, error) { if !prop.IsEmpty() || prop.IsFlashProp() { - p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because operator `MaxOneRow` is not supported now.") + p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because operator `MaxOneRow` is not supported now.") return nil, true, nil } mor := PhysicalMaxOneRow{}.Init(p.ctx, p.stats, p.blockOffset, &property.PhysicalProperty{ExpectedCnt: 2}) diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index bd5892be3134f..4d8112eb42523 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -1548,12 +1548,12 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } if prop.MPPPartitionTp != property.AnyType || ts.isPartition { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. - ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because table `" + ds.tableInfo.Name.O + "`is a partition table which is not supported when `@@tidb_partition_prune_mode=static`.") + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because table `" + ds.tableInfo.Name.O + "`is a partition table which is not supported when `@@tidb_partition_prune_mode=static`.") return &mppTask{}, nil } for _, col := range ts.schema.Columns { if col.VirtualExpr != nil { - ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because column `" + col.OrigName + "` is a virtual column which is not supported now.") + ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because column `" + col.OrigName + "` is a virtual column which is not supported now.") return &mppTask{}, nil } } diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 3087b6b229973..8389f0be4cade 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -620,7 +620,7 @@ func (ds *DataSource) setPreferredStoreType(hintInfo *tableHintInfo) { warning := ErrInternal.GenWithStack(errMsg) ds.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) } else { - ds.ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because you have set a hint to read table `" + hintTbl.tblName.O + "` from TiKV.") + ds.ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because you have set a hint to read table `" + hintTbl.tblName.O + "` from TiKV.") } } if hintTbl := hintInfo.ifPreferTiFlash(alias); hintTbl != nil { diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 7cc409504a257..eeb969c0adcd5 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -975,9 +975,9 @@ func getPossibleAccessPaths(ctx sessionctx.Context, tableHints *tableHintInfo, i publicPaths = append(publicPaths, tablePath) if tblInfo.TiFlashReplica == nil { - ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because there aren't tiflash replicas of table `" + tblInfo.Name.O + "`.") + ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because there aren't tiflash replicas of table `" + tblInfo.Name.O + "`.") } else if !tblInfo.TiFlashReplica.Available { - ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because tiflash replicas of table `" + tblInfo.Name.O + "` not ready.") + ctx.GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because tiflash replicas of table `" + tblInfo.Name.O + "` not ready.") } else { publicPaths = append(publicPaths, genTiFlashPath(tblInfo, false)) publicPaths = append(publicPaths, genTiFlashPath(tblInfo, true)) @@ -1123,7 +1123,7 @@ func filterPathByIsolationRead(ctx sessionctx.Context, paths []*util.AccessPath, } if _, ok := isolationReadEngines[kv.TiFlash]; !ok { ctx.GetSessionVars().RaiseWarningWhenMPPEnforced( - fmt.Sprintf("Can't use mpp mode because '%v'(value: '%v') not match, need 'tiflash'.", variable.TiDBIsolationReadEngines, engineVals)) + fmt.Sprintf("MPP mode may be blocked because '%v'(value: '%v') not match, need 'tiflash'.", variable.TiDBIsolationReadEngines, engineVals)) } return paths, err } diff --git a/planner/core/task.go b/planner/core/task.go index 0f75d448c645a..26261836f5e07 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -1405,11 +1405,12 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc // if the aggFunc contain VirtualColumn or CorrelatedColumn, it can not be pushed down. if expression.ContainVirtualColumn(aggFunc.Args) || expression.ContainCorrelatedColumn(aggFunc.Args) { sctx.GetSessionVars().RaiseWarningWhenMPPEnforced( - "Can't use mpp mode because expressions of aggFunc `" + aggFunc.Name + "` contain virtual column or correlated column, which is not supported now.") + "MPP mode may be blocked because expressions of AggFunc `" + aggFunc.Name + "` contain virtual column or correlated column, which is not supported now.") return false } pb := aggregation.AggFuncToPBExpr(sc, client, aggFunc) if pb == nil { + sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because AggFunc `" + aggFunc.Name + "` is not supported now.") return false } if !aggregation.CheckAggPushDown(aggFunc, storeType) { @@ -1427,7 +1428,7 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc } } if expression.ContainVirtualColumn(groupByItems) { - sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because groupByItems contain virtual column, which is not supported now.") + sctx.GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because groupByItems contain virtual column, which is not supported now.") return false } return expression.CanExprsPushDown(sc, groupByItems, client, storeType) @@ -2128,7 +2129,7 @@ func (t *mppTask) needEnforce(prop *property.PhysicalProperty) bool { func (t *mppTask) enforceExchanger(prop *property.PhysicalProperty) *mppTask { if len(prop.SortItems) != 0 { - t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("Can't use mpp mode because operator `Sort` is not supported now.") + t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because operator `Sort` is not supported now.") return &mppTask{} } if !t.needEnforce(prop) { @@ -2141,6 +2142,7 @@ func (t *mppTask) enforceExchangerImpl(prop *property.PhysicalProperty) *mppTask if collate.NewCollationEnabled() && prop.MPPPartitionTp == property.HashType { for _, col := range prop.MPPPartitionCols { if types.IsString(col.RetType.Tp) { + t.p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because when `new_collation_enabled` is true, HashJoin or HashAgg with string key is not supported now.") return &mppTask{cst: math.MaxFloat64} } } From f3abbf417fa94d20963d34793c35ef88e37ff1e3 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 17:05:06 +0800 Subject: [PATCH 12/15] stash test --- planner/core/enforce_mpp_test.go | 185 ++++++++++++++++++ planner/core/integration_test.go | 126 ------------ .../core/testdata/enforce_mpp_suite_in.json | 24 +++ .../core/testdata/enforce_mpp_suite_out.json | 165 ++++++++++++++++ 4 files changed, 374 insertions(+), 126 deletions(-) create mode 100644 planner/core/enforce_mpp_test.go create mode 100644 planner/core/testdata/enforce_mpp_suite_in.json create mode 100644 planner/core/testdata/enforce_mpp_suite_out.json diff --git a/planner/core/enforce_mpp_test.go b/planner/core/enforce_mpp_test.go new file mode 100644 index 0000000000000..cd563799eb7c9 --- /dev/null +++ b/planner/core/enforce_mpp_test.go @@ -0,0 +1,185 @@ +// Copyright 2019 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 core_test + +import ( + "strings" + + . "github.com/pingcap/check" + "github.com/pingcap/parser/model" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/util/testkit" + "github.com/pingcap/tidb/util/testutil" +) + +var _ = SerialSuites(&testEnforceMPPSuite{}) + +type testEnforceMPPSuite struct { + testData testutil.TestData + store kv.Storage + dom *domain.Domain +} + +func (s *testEnforceMPPSuite) SetUpSuite(c *C) { + var err error + s.testData, err = testutil.LoadTestSuiteData("testdata", "enforce_mpp_suite") + c.Assert(err, IsNil) +} + +func (s *testEnforceMPPSuite) TearDownSuite(c *C) { + c.Assert(s.testData.GenerateOutputIfNeeded(), IsNil) +} + +func (s *testEnforceMPPSuite) SetUpTest(c *C) { + var err error + s.store, s.dom, err = newStoreWithBootstrap() + c.Assert(err, IsNil) +} + +func (s *testEnforceMPPSuite) TearDownTest(c *C) { + s.dom.Close() + err := s.store.Close() + c.Assert(err, IsNil) +} + +func (s *testEnforceMPPSuite) TestSetVariables(c *C) { + tk := testkit.NewTestKit(c, s.store) + + // test value limit of tidb_opt_tiflash_concurrency_factor + err := tk.ExecToErr("set @@tidb_opt_tiflash_concurrency_factor = 0") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_opt_tiflash_concurrency_factor' can't be set to the value of '0'`) + + // test set tidb_enforce_mpp when tidb_allow_mpp=false; + err = tk.ExecToErr("set @@tidb_allow_mpp = 0; set @@tidb_enforce_mpp = 1;") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_enforce_mpp' can't be set to the value of '1' but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.'`) + + err = tk.ExecToErr("set @@tidb_allow_mpp = 1; set @@tidb_enforce_mpp = 1;") + c.Assert(err, IsNil) + + err = tk.ExecToErr("set @@tidb_allow_mpp = 0;") + c.Assert(err, IsNil) +} + +func (s *testEnforceMPPSuite) TestEnforceMPP(c *C) { + tk := testkit.NewTestKit(c, s.store) + + // test query + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int)") + tk.MustExec("create index idx on t(a)") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + c.Assert(exists, IsTrue) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + var input []string + var output[]struct { + SQL string + Plan []string + Warn []string + } + s.testData.GetTestCases(c, &input, &output) + for i, tt := range input { + if strings.HasPrefix(tt, "set") { + tk.MustExec(tt) + continue + } + s.testData.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) + } +} + +func (s *testEnforceMPPSuite) TestEnforceMPPWarningForReplica(c *C) { + tk := testkit.NewTestKit(c, s.store) + + // test query + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int)") + tk.MustExec("create index idx on t(a)") + + var input []string + var output[]struct { + SQL string + Plan []string + Warn []string + } + s.testData.GetTestCases(c, &input, &output) + for i, tt := range input { + if strings.HasPrefix(tt, "set") { + tk.MustExec(tt) + continue + } + if strings.HasPrefix(tt, "cmd: create-replica") { + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + c.Assert(exists, IsTrue) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: false, + } + } + } + continue + } + if strings.HasPrefix(tt, "cmd: enable-replica") { + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + c.Assert(exists, IsTrue) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + continue + } + s.testData.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) + } +} diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 9c95d5026f79b..394d5c02b0c1e 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -3889,129 +3889,3 @@ func (s *testIntegrationSerialSuite) TestMergeContinuousSelections(c *C) { res.Check(testkit.Rows(output[i].Plan...)) } } - -func (s *testIntegrationSerialSuite) TestEnforceMPP(c *C) { - tk := testkit.NewTestKit(c, s.store) - - // test value limit of tidb_opt_tiflash_concurrency_factor - err := tk.ExecToErr("set @@tidb_opt_tiflash_concurrency_factor = 0") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_opt_tiflash_concurrency_factor' can't be set to the value of '0'`) - - tk.MustExec("set @@tidb_opt_tiflash_concurrency_factor = 1") - tk.MustQuery("select @@tidb_opt_tiflash_concurrency_factor").Check(testkit.Rows("1")) - tk.MustExec("set @@tidb_opt_tiflash_concurrency_factor = 24") - tk.MustQuery("select @@tidb_opt_tiflash_concurrency_factor").Check(testkit.Rows("24")) - - // test set tidb_allow_mpp - tk.MustExec("set @@session.tidb_allow_mpp = 0") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("OFF")) - tk.MustExec("set @@session.tidb_allow_mpp = 1") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ON")) - tk.MustExec("set @@session.tidb_allow_mpp = 2") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ENFORCE")) - - tk.MustExec("set @@session.tidb_allow_mpp = off") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("OFF")) - tk.MustExec("set @@session.tidb_allow_mpp = oN") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ON")) - tk.MustExec("set @@session.tidb_allow_mpp = enForcE") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ENFORCE")) - - tk.MustExec("set @@global.tidb_allow_mpp = faLsE") - tk.MustQuery("select @@global.tidb_allow_mpp").Check(testkit.Rows("OFF")) - tk.MustExec("set @@global.tidb_allow_mpp = True") - tk.MustQuery("select @@global.tidb_allow_mpp").Check(testkit.Rows("ON")) - - err = tk.ExecToErr("set @@global.tidb_allow_mpp = enforceWithTypo") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_allow_mpp' can't be set to the value of 'enforceWithTypo'`) - - // test query - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int)") - tk.MustExec("create index idx on t(a)") - - // Create virtual tiflash replica info. - dom := domain.GetDomain(tk.Se) - is := dom.InfoSchema() - db, exists := is.SchemaByName(model.NewCIStr("test")) - c.Assert(exists, IsTrue) - for _, tblInfo := range db.Tables { - if tblInfo.Name.L == "t" { - tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ - Count: 1, - Available: true, - } - } - } - - // ban mpp - tk.MustExec("set @@session.tidb_allow_mpp = 0") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("OFF")) - - // read from tiflash, batch cop. - tk.MustQuery("explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1").Check(testkit.Rows( - "StreamAgg_20 1.00 285050.00 root funcs:count(Column#5)->Column#3", - "└─TableReader_21 1.00 19003.88 root data:StreamAgg_9", - " └─StreamAgg_9 1.00 19006.88 batchCop[tiflash] funcs:count(1)->Column#5", - " └─Selection_19 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_18 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo")) - - // open mpp - tk.MustExec("set @@session.tidb_allow_mpp = 1") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ON")) - - // should use tikv to index read - tk.MustQuery("explain format='verbose' select count(*) from t where a=1;").Check(testkit.Rows( - "StreamAgg_30 1.00 485.00 root funcs:count(Column#6)->Column#3", - "└─IndexReader_31 1.00 32.88 root index:StreamAgg_10", - " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_29 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo")) - - // read from tikv, indexRead - tk.MustQuery("explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1;").Check(testkit.Rows( - "StreamAgg_18 1.00 485.00 root funcs:count(Column#5)->Column#3", - "└─IndexReader_19 1.00 32.88 root index:StreamAgg_10", - " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#5", - " └─IndexRangeScan_17 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo")) - - // read from tiflash, mpp with large cost - tk.MustQuery("explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1").Check(testkit.Rows( - "HashAgg_21 1.00 11910.73 root funcs:count(Column#5)->Column#3", - "└─TableReader_23 1.00 11877.13 root data:ExchangeSender_22", - " └─ExchangeSender_22 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", - " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#5", - " └─Selection_20 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_19 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo")) - - // enforce mpp - tk.MustExec("set @@session.tidb_allow_mpp = 2") - tk.MustQuery("select @@session.tidb_allow_mpp").Check(testkit.Rows("ENFORCE")) - - // should use mpp - tk.MustQuery("explain format='verbose' select count(*) from t where a=1;").Check(testkit.Rows( - "HashAgg_24 1.00 33.60 root funcs:count(Column#5)->Column#3", - "└─TableReader_26 1.00 0.00 root data:ExchangeSender_25", - " └─ExchangeSender_25 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", - " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#5", - " └─Selection_23 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_22 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo")) - - // read from tikv, indexRead - tk.MustQuery("explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1;").Check(testkit.Rows( - "StreamAgg_18 1.00 485.00 root funcs:count(Column#5)->Column#3", - "└─IndexReader_19 1.00 32.88 root index:StreamAgg_10", - " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#5", - " └─IndexRangeScan_17 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo")) - - // read from tiflash, mpp with little cost - tk.MustQuery("explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1").Check(testkit.Rows( - "HashAgg_21 1.00 33.60 root funcs:count(Column#5)->Column#3", - "└─TableReader_23 1.00 0.00 root data:ExchangeSender_22", - " └─ExchangeSender_22 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", - " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#5", - " └─Selection_20 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_19 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo")) -} diff --git a/planner/core/testdata/enforce_mpp_suite_in.json b/planner/core/testdata/enforce_mpp_suite_in.json new file mode 100644 index 0000000000000..63f8c63dc774b --- /dev/null +++ b/planner/core/testdata/enforce_mpp_suite_in.json @@ -0,0 +1,24 @@ +[ + { + "name": "TestEnforceMPP", + "cases": [ + "set @@tidb_allow_mpp=0", + "explain format='verbose' select count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "set @@tidb_allow_mpp=1;", + "set @@tidb_enforce_mpp=0;", + "explain format='verbose' select count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "set @@tidb_opt_tiflash_concurrency_factor = 1000000", + "explain format='verbose' select count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "set @@tidb_enforce_mpp=1;", + "explain format='verbose' select count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1" + ] + } +] diff --git a/planner/core/testdata/enforce_mpp_suite_out.json b/planner/core/testdata/enforce_mpp_suite_out.json new file mode 100644 index 0000000000000..c8eff5d449d61 --- /dev/null +++ b/planner/core/testdata/enforce_mpp_suite_out.json @@ -0,0 +1,165 @@ +[ + { + "Name": "TestEnforceMPP", + "Cases": [ + { + "SQL": "", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain format='verbose' select count(*) from t where a=1", + "Plan": [ + "StreamAgg_24 1.00 485.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader_25 1.00 32.88 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_23 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "Plan": [ + "StreamAgg_17 1.00 485.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader_18 1.00 32.88 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_16 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "Plan": [ + "StreamAgg_20 1.00 285050.00 root funcs:count(Column#6)->Column#4", + "└─TableReader_21 1.00 19003.88 root data:StreamAgg_9", + " └─StreamAgg_9 1.00 19006.88 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_19 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_18 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "", + "Plan": null, + "Warn": null + }, + { + "SQL": "", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain format='verbose' select count(*) from t where a=1", + "Plan": [ + "StreamAgg_30 1.00 485.00 root funcs:count(Column#7)->Column#4", + "└─IndexReader_31 1.00 32.88 root index:StreamAgg_10", + " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_29 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "Plan": [ + "StreamAgg_18 1.00 485.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader_19 1.00 32.88 root index:StreamAgg_10", + " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_17 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "Plan": [ + "HashAgg_21 1.00 11910.73 root funcs:count(Column#6)->Column#4", + "└─TableReader_23 1.00 11877.13 root data:ExchangeSender_22", + " └─ExchangeSender_22 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_20 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_19 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain format='verbose' select count(*) from t where a=1", + "Plan": [ + "HashAgg_24 1.00 33.89 root funcs:count(Column#6)->Column#4", + "└─TableReader_26 1.00 0.29 root data:ExchangeSender_25", + " └─ExchangeSender_25 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_23 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_22 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "Plan": [ + "StreamAgg_18 1.00 485.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader_19 1.00 32.88 root index:StreamAgg_10", + " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_17 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "Plan": [ + "HashAgg_21 1.00 33.89 root funcs:count(Column#6)->Column#4", + "└─TableReader_23 1.00 0.29 root data:ExchangeSender_22", + " └─ExchangeSender_22 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_20 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_19 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain format='verbose' select count(*) from t where a=1", + "Plan": [ + "HashAgg_24 1.00 33.60 root funcs:count(Column#6)->Column#4", + "└─TableReader_26 1.00 0.00 root data:ExchangeSender_25", + " └─ExchangeSender_25 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_23 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_22 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", + "Plan": [ + "StreamAgg_18 1.00 485.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader_19 1.00 32.88 root index:StreamAgg_10", + " └─StreamAgg_10 1.00 35.88 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_17 10.00 455.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because you have set a hint to read table `t` from TiKV." + ] + }, + { + "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", + "Plan": [ + "HashAgg_21 1.00 33.60 root funcs:count(Column#6)->Column#4", + "└─TableReader_23 1.00 0.00 root data:ExchangeSender_22", + " └─ExchangeSender_22 1.00 285050.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_9 1.00 285050.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_20 10.00 285020.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_19 10000.00 255020.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + } +] From 310403144044c1bf62d57183477558e8c85a3db9 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 22:19:53 +0800 Subject: [PATCH 13/15] add tests --- planner/core/enforce_mpp_test.go | 129 +++++++- .../core/testdata/enforce_mpp_suite_in.json | 45 +++ .../core/testdata/enforce_mpp_suite_out.json | 283 +++++++++++++++++- sessionctx/variable/sysvar.go | 2 +- 4 files changed, 448 insertions(+), 11 deletions(-) diff --git a/planner/core/enforce_mpp_test.go b/planner/core/enforce_mpp_test.go index cd563799eb7c9..30f6805eaaaa0 100644 --- a/planner/core/enforce_mpp_test.go +++ b/planner/core/enforce_mpp_test.go @@ -14,6 +14,7 @@ package core_test import ( + "github.com/pingcap/tidb/util/collate" "strings" . "github.com/pingcap/check" @@ -65,7 +66,7 @@ func (s *testEnforceMPPSuite) TestSetVariables(c *C) { // test set tidb_enforce_mpp when tidb_allow_mpp=false; err = tk.ExecToErr("set @@tidb_allow_mpp = 0; set @@tidb_enforce_mpp = 1;") c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_enforce_mpp' can't be set to the value of '1' but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.'`) + c.Assert(err.Error(), Equals, `[variable:1231]Variable 'tidb_enforce_mpp' can't be set to the value of '1' but tidb_allow_mpp is 0, please activate tidb_allow_mpp at first.'`) err = tk.ExecToErr("set @@tidb_allow_mpp = 1; set @@tidb_enforce_mpp = 1;") c.Assert(err, IsNil) @@ -98,13 +99,16 @@ func (s *testEnforceMPPSuite) TestEnforceMPP(c *C) { } var input []string - var output[]struct { + var output []struct { SQL string Plan []string Warn []string } s.testData.GetTestCases(c, &input, &output) for i, tt := range input { + s.testData.OnRecord(func() { + output[i].SQL = tt + }) if strings.HasPrefix(tt, "set") { tk.MustExec(tt) continue @@ -120,23 +124,27 @@ func (s *testEnforceMPPSuite) TestEnforceMPP(c *C) { } } -func (s *testEnforceMPPSuite) TestEnforceMPPWarningForReplica(c *C) { +// general cases. +func (s *testEnforceMPPSuite) TestEnforceMPPWarning1(c *C) { tk := testkit.NewTestKit(c, s.store) // test query tk.MustExec("use test") tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int)") + tk.MustExec("create table t(a int, b int as (a+1), c time)") tk.MustExec("create index idx on t(a)") var input []string - var output[]struct { + var output []struct { SQL string Plan []string Warn []string } s.testData.GetTestCases(c, &input, &output) for i, tt := range input { + s.testData.OnRecord(func() { + output[i].SQL = tt + }) if strings.HasPrefix(tt, "set") { tk.MustExec(tt) continue @@ -183,3 +191,114 @@ func (s *testEnforceMPPSuite) TestEnforceMPPWarningForReplica(c *C) { c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) } } + +// partition table. +func (s *testEnforceMPPSuite) TestEnforceMPPWarning2(c *C) { + tk := testkit.NewTestKit(c, s.store) + + // test query + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE t (a int, b char(20)) PARTITION BY HASH(a)") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + c.Assert(exists, IsTrue) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + s.testData.GetTestCases(c, &input, &output) + for i, tt := range input { + s.testData.OnRecord(func() { + output[i].SQL = tt + }) + if strings.HasPrefix(tt, "set") { + tk.MustExec(tt) + continue + } + s.testData.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) + } +} + +// new collation. +func (s *testEnforceMPPSuite) TestEnforceMPPWarning3(c *C) { + tk := testkit.NewTestKit(c, s.store) + + // test query + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE t (a int, b char(20))") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + c.Assert(exists, IsTrue) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + s.testData.GetTestCases(c, &input, &output) + for i, tt := range input { + s.testData.OnRecord(func() { + output[i].SQL = tt + }) + if strings.HasPrefix(tt, "set") || strings.HasPrefix(tt, "UPDATE") { + tk.MustExec(tt) + continue + } + if strings.HasPrefix(tt, "cmd: enable-new-collation") { + collate.SetNewCollationEnabledForTest(true) + continue + } + if strings.HasPrefix(tt, "cmd: disable-new-collation") { + collate.SetNewCollationEnabledForTest(false) + continue + } + s.testData.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) + } +} + +// +//parition +//collation +//"EXPLAIN SELECT t1.b FROM t t1 join t t2 where t1.a=t2.a; -- 6. virtual column", diff --git a/planner/core/testdata/enforce_mpp_suite_in.json b/planner/core/testdata/enforce_mpp_suite_in.json index 63f8c63dc774b..da1ca6f6bfedf 100644 --- a/planner/core/testdata/enforce_mpp_suite_in.json +++ b/planner/core/testdata/enforce_mpp_suite_in.json @@ -2,6 +2,9 @@ { "name": "TestEnforceMPP", "cases": [ + "select @@tidb_allow_mpp", + "select @@tidb_enforce_mpp", + "select @@tidb_opt_tiflash_concurrency_factor", "set @@tidb_allow_mpp=0", "explain format='verbose' select count(*) from t where a=1", "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", @@ -20,5 +23,47 @@ "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1" ] + }, + { + "name": "TestEnforceMPPWarning1", + "cases": [ + "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "explain select count(*) from t where a=1 -- 1. no replica", + "cmd: create-replica", + "explain select count(*) from t where a=1 -- 2. replica not ready", + "cmd: enable-replica", + "set @@session.tidb_isolation_read_engines = 'tikv';", + "explain select count(*) from t where a=1 -- 3. isolation_engine not match", + "set @@session.tidb_isolation_read_engines = 'tikv, tiflash';", + "explain select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1 -- 4. hint use tikv", + "explain SELECT a, ROW_NUMBER() OVER (ORDER BY a) FROM t; -- 5. window unsupported", + "EXPLAIN SELECT t1.b FROM t t1 join t t2 where t1.a=t2.a; -- 6. virtual column", + "EXPLAIN SELECT count(b) from t where a=1; -- 7. agg func has virtual column", + "EXPLAIN SELECT count(*) from t group by b; -- 8. group by virtual column", + "EXPLAIN SELECT group_concat(a) from t; -- 9. agg func not supported", + "EXPLAIN SELECT count(a) from t group by md5(a); -- 10. scalar func not supported", + "EXPLAIN SELECT count(a) from t where c=1; -- 11. type not supported" + ] + }, + { + "name": "TestEnforceMPPWarning2", + "cases": [ + "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "set @@tidb_partition_prune_mode=static;", + "EXPLAIN SELECT count(*) from t where a=1; -- 12. static partition prune", + "set @@tidb_partition_prune_mode=dynamic;" + + ] + }, + { + "name": "TestEnforceMPPWarning3", + "cases": [ + "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "cmd: enable-new-collation", + "EXPLAIN SELECT count(*) from t group by b; -- 13. new collation FIXME", + "EXPLAIN SELECT * from t t1 join t t2 on t1.b=t2.b; -- 13. new collation FIXME" + ] } + + ] diff --git a/planner/core/testdata/enforce_mpp_suite_out.json b/planner/core/testdata/enforce_mpp_suite_out.json index c8eff5d449d61..372a69d73513f 100644 --- a/planner/core/testdata/enforce_mpp_suite_out.json +++ b/planner/core/testdata/enforce_mpp_suite_out.json @@ -3,7 +3,28 @@ "Name": "TestEnforceMPP", "Cases": [ { - "SQL": "", + "SQL": "select @@tidb_allow_mpp", + "Plan": [ + "1" + ], + "Warn": null + }, + { + "SQL": "select @@tidb_enforce_mpp", + "Plan": [ + "0" + ], + "Warn": null + }, + { + "SQL": "select @@tidb_opt_tiflash_concurrency_factor", + "Plan": [ + "24" + ], + "Warn": null + }, + { + "SQL": "set @@tidb_allow_mpp=0", "Plan": null, "Warn": null }, @@ -39,12 +60,12 @@ "Warn": null }, { - "SQL": "", + "SQL": "set @@tidb_allow_mpp=1;", "Plan": null, "Warn": null }, { - "SQL": "", + "SQL": "set @@tidb_enforce_mpp=0;", "Plan": null, "Warn": null }, @@ -81,7 +102,7 @@ "Warn": null }, { - "SQL": "", + "SQL": "set @@tidb_opt_tiflash_concurrency_factor = 1000000", "Plan": null, "Warn": null }, @@ -120,7 +141,7 @@ "Warn": null }, { - "SQL": "", + "SQL": "set @@tidb_enforce_mpp=1;", "Plan": null, "Warn": null }, @@ -161,5 +182,257 @@ "Warn": null } ] + }, + { + "Name": "TestEnforceMPPWarning1", + "Cases": [ + { + "SQL": "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select count(*) from t where a=1 -- 1. no replica", + "Plan": [ + "StreamAgg_17 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader_18 1.00 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_16 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because there aren't tiflash replicas of table `t`." + ] + }, + { + "SQL": "cmd: create-replica", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select count(*) from t where a=1 -- 2. replica not ready", + "Plan": [ + "StreamAgg_17 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader_18 1.00 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_16 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because tiflash replicas of table `t` not ready." + ] + }, + { + "SQL": "cmd: enable-replica", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_isolation_read_engines = 'tikv';", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select count(*) from t where a=1 -- 3. isolation_engine not match", + "Plan": [ + "StreamAgg_17 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader_18 1.00 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_16 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because 'tidb_isolation_read_engines'(value: 'tikv') not match, need 'tiflash'." + ] + }, + { + "SQL": "set @@session.tidb_isolation_read_engines = 'tikv, tiflash';", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1 -- 4. hint use tikv", + "Plan": [ + "StreamAgg_18 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader_19 1.00 root index:StreamAgg_10", + " └─StreamAgg_10 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_17 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because you have set a hint to read table `t` from TiKV." + ] + }, + { + "SQL": "explain SELECT a, ROW_NUMBER() OVER (ORDER BY a) FROM t; -- 5. window unsupported", + "Plan": [ + "Window_7 10000.00 root row_number()->Column#6 over(order by test.t.a rows between current row and current row)", + "└─IndexReader_9 10000.00 root index:IndexFullScan_8", + " └─IndexFullScan_8 10000.00 cop[tikv] table:t, index:idx(a) keep order:true, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because operator `Window` is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT t1.b FROM t t1 join t t2 where t1.a=t2.a; -- 6. virtual column", + "Plan": [ + "HashJoin_35 12487.50 root inner join, equal:[eq(test.t.a, test.t.a)]", + "├─TableReader_55(Build) 9990.00 root data:Selection_54", + "│ └─Selection_54 9990.00 cop[tiflash] not(isnull(test.t.a))", + "│ └─TableFullScan_53 10000.00 cop[tiflash] table:t2 keep order:false, stats:pseudo", + "└─TableReader_49(Probe) 9990.00 root data:Selection_48", + " └─Selection_48 9990.00 cop[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_47 10000.00 cop[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because column `test.t.b` is a virtual column which is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT count(b) from t where a=1; -- 7. agg func has virtual column", + "Plan": [ + "StreamAgg_10 1.00 root funcs:count(test.t.b)->Column#5", + "└─IndexLookUp_41 10.00 root ", + " ├─IndexRangeScan_39(Build) 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan_40(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because expressions of AggFunc `count` contain virtual column or correlated column, which is not supported now.", + "MPP mode may be blocked because expressions of AggFunc `count` contain virtual column or correlated column, which is not supported now.", + "MPP mode may be blocked because expressions of AggFunc `count` contain virtual column or correlated column, which is not supported now.", + "MPP mode may be blocked because expressions of AggFunc `count` contain virtual column or correlated column, which is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT count(*) from t group by b; -- 8. group by virtual column", + "Plan": [ + "HashAgg_5 8000.00 root group by:test.t.b, funcs:count(1)->Column#5", + "└─Projection_11 10000.00 root test.t.b", + " └─TableReader_10 10000.00 root data:TableFullScan_9", + " └─TableFullScan_9 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because groupByItems contain virtual column, which is not supported now.", + "MPP mode may be blocked because groupByItems contain virtual column, which is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT group_concat(a) from t; -- 9. agg func not supported", + "Plan": [ + "HashAgg_5 1.00 root funcs:group_concat(Column#6 separator \",\")->Column#5", + "└─Projection_30 10000.00 root cast(test.t.a, var_string(20))->Column#6", + " └─TableReader_13 10000.00 root data:TableFullScan_11", + " └─TableFullScan_11 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because AggFunc `group_concat` is not supported now.", + "MPP mode may be blocked because AggFunc `group_concat` is not supported now.", + "MPP mode may be blocked because AggFunc `group_concat` is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT count(a) from t group by md5(a); -- 10. scalar func not supported", + "Plan": [ + "HashAgg_5 8000.00 root group by:Column#7, funcs:count(Column#6)->Column#5", + "└─Projection_18 10000.00 root test.t.a, md5(cast(test.t.a, var_string(20)))->Column#7", + " └─TableReader_11 10000.00 root data:TableFullScan_9", + " └─TableFullScan_9 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Scalar function 'md5'(signature: MD5) can not be pushed to tiflash", + "Scalar function 'md5'(signature: MD5) can not be pushed to tiflash" + ] + }, + { + "SQL": "EXPLAIN SELECT count(a) from t where c=1; -- 11. type not supported", + "Plan": [ + "HashAgg_6 1.00 root funcs:count(test.t.a)->Column#5", + "└─Selection_16 10000.00 root eq(test.t.c, 00:00:01.000000)", + " └─TableReader_15 10000.00 root data:TableFullScan_14", + " └─TableFullScan_14 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Expr 'test.t.c' can not be pushed to TiFlash because it contains Duration type", + "Expr 'test.t.c' can not be pushed to TiFlash because it contains Duration type", + "Expr 'test.t.c' can not be pushed to TiFlash because it contains Duration type", + "Expr 'test.t.c' can not be pushed to TiFlash because it contains Duration type", + "Expr 'test.t.c' can not be pushed to TiFlash because it contains Duration type" + ] + } + ] + }, + { + "Name": "TestEnforceMPPWarning2", + "Cases": [ + { + "SQL": "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@tidb_partition_prune_mode=static;", + "Plan": null, + "Warn": null + }, + { + "SQL": "EXPLAIN SELECT count(*) from t where a=1; -- 12. static partition prune", + "Plan": [ + "StreamAgg_31 1.00 root funcs:count(Column#6)->Column#4", + "└─TableReader_32 1.00 root data:StreamAgg_12", + " └─StreamAgg_12 1.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─Selection_30 10.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_29 10000.00 batchCop[tiflash] table:t, partition:p0 keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because table `t`is a partition table which is not supported when `@@tidb_partition_prune_mode=static`." + ] + }, + { + "SQL": "set @@tidb_partition_prune_mode=dynamic;", + "Plan": null, + "Warn": null + } + ] + }, + { + "Name": "TestEnforceMPPWarning3", + "Cases": [ + { + "SQL": "set @@tidb_allow_mpp=1;set @@tidb_enforce_mpp=1;", + "Plan": null, + "Warn": null + }, + { + "SQL": "cmd: enable-new-collation", + "Plan": null, + "Warn": null + }, + { + "SQL": "EXPLAIN SELECT count(*) from t group by b; -- 13. new collation FIXME", + "Plan": [ + "HashAgg_23 8000.00 root group by:test.t.b, funcs:count(Column#7)->Column#4", + "└─TableReader_25 8000.00 root data:ExchangeSender_24", + " └─ExchangeSender_24 8000.00 batchCop[tiflash] ExchangeType: PassThrough", + " └─HashAgg_10 8000.00 batchCop[tiflash] group by:test.t.b, funcs:count(1)->Column#7", + " └─TableFullScan_20 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because when `new_collation_enabled` is true, HashJoin or HashAgg with string key is not supported now.", + "MPP mode may be blocked because when `new_collation_enabled` is true, HashJoin or HashAgg with string key is not supported now." + ] + }, + { + "SQL": "EXPLAIN SELECT * from t t1 join t t2 on t1.b=t2.b; -- 13. new collation FIXME", + "Plan": [ + "TableReader_18 12487.50 root data:ExchangeSender_17", + "└─ExchangeSender_17 12487.50 cop[tiflash] ExchangeType: PassThrough", + " └─HashJoin_8 12487.50 cop[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver_14(Build) 9990.00 cop[tiflash] ", + " │ └─ExchangeSender_13 9990.00 cop[tiflash] ExchangeType: Broadcast", + " │ └─Selection_12 9990.00 cop[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan_11 10000.00 cop[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection_16(Probe) 9990.00 cop[tiflash] not(isnull(test.t.b))", + " └─TableFullScan_15 10000.00 cop[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + } + ] } ] diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 4469ecd05f60d..841fabdbd7238 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -842,7 +842,7 @@ var defaultSysVars = []*SysVar{ }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnforceMPPExecution, Type: TypeBool, Value: BoolToOnOff(DefTiDBEnforceMPPExecution), Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { if TiDBOptOn(normalizedValue) && !vars.allowMPPExecution { - return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs("tidb_enforce_mpp", "1' but tidb_allow_mpp is 0, please active tidb_allow_mpp at first.") + return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs("tidb_enforce_mpp", "1' but tidb_allow_mpp is 0, please activate tidb_allow_mpp at first.") } return normalizedValue, nil }, SetSession: func(s *SessionVars, val string) error { From 32c3eccf7aa1c63868db643abf87b5437949e133 Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 22:52:58 +0800 Subject: [PATCH 14/15] make fmt --- planner/core/enforce_mpp_test.go | 7 +------ planner/core/testdata/enforce_mpp_suite_in.json | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/planner/core/enforce_mpp_test.go b/planner/core/enforce_mpp_test.go index 30f6805eaaaa0..b2ba38cb515de 100644 --- a/planner/core/enforce_mpp_test.go +++ b/planner/core/enforce_mpp_test.go @@ -14,13 +14,13 @@ package core_test import ( - "github.com/pingcap/tidb/util/collate" "strings" . "github.com/pingcap/check" "github.com/pingcap/parser/model" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testutil" ) @@ -297,8 +297,3 @@ func (s *testEnforceMPPSuite) TestEnforceMPPWarning3(c *C) { c.Assert(s.testData.ConvertSQLWarnToStrings(tk.Se.GetSessionVars().StmtCtx.GetWarnings()), DeepEquals, output[i].Warn) } } - -// -//parition -//collation -//"EXPLAIN SELECT t1.b FROM t t1 join t t2 where t1.a=t2.a; -- 6. virtual column", diff --git a/planner/core/testdata/enforce_mpp_suite_in.json b/planner/core/testdata/enforce_mpp_suite_in.json index da1ca6f6bfedf..8f80d928190cf 100644 --- a/planner/core/testdata/enforce_mpp_suite_in.json +++ b/planner/core/testdata/enforce_mpp_suite_in.json @@ -64,6 +64,4 @@ "EXPLAIN SELECT * from t t1 join t t2 on t1.b=t2.b; -- 13. new collation FIXME" ] } - - ] From 546c7de32b03b4829efdb96b211a05264e4b8bcb Mon Sep 17 00:00:00 2001 From: Zhi Qi Date: Thu, 10 Jun 2021 23:08:20 +0800 Subject: [PATCH 15/15] revert --- executor/tiflash_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/executor/tiflash_test.go b/executor/tiflash_test.go index d4a4f873e6db5..282410eb06472 100644 --- a/executor/tiflash_test.go +++ b/executor/tiflash_test.go @@ -300,7 +300,7 @@ func (s *tiflashTestSuite) TestTiFlashPartitionTableShuffledHashJoin(c *C) { tk.MustExec(fmt.Sprintf("analyze table %v", tbl)) } - tk.MustExec("SET tidb_allow_mpp=2") + tk.MustExec("SET tidb_enforce_mpp=1") tk.MustExec("SET tidb_opt_broadcast_join=0") tk.MustExec("SET tidb_broadcast_join_threshold_count=0") tk.MustExec("SET tidb_broadcast_join_threshold_size=0") @@ -378,7 +378,7 @@ func (s *tiflashTestSuite) TestTiFlashPartitionTableReader(c *C) { tk.MustExec(fmt.Sprintf("insert into %v values %v", tbl, strings.Join(vals, ", "))) } - tk.MustExec("SET tidb_allow_mpp=2") + tk.MustExec("SET tidb_enforce_mpp=1") tk.MustExec("set @@session.tidb_isolation_read_engines='tiflash'") for i := 0; i < 100; i++ { l, r := rand.Intn(400), rand.Intn(400) @@ -742,7 +742,7 @@ func (s *tiflashTestSuite) TestTiFlashPartitionTableShuffledHashAggregation(c *C tk.MustExec(fmt.Sprintf("analyze table %v", tbl)) } tk.MustExec("set @@session.tidb_isolation_read_engines='tiflash'") - tk.MustExec("set @@session.tidb_allow_mpp=2") + tk.MustExec("set @@session.tidb_enforce_mpp=1") // mock executor does not support use outer table as build side for outer join, so need to // force the inner table as build side tk.MustExec("set tidb_opt_mpp_outer_join_fixed_build_side=1") @@ -814,7 +814,7 @@ func (s *tiflashTestSuite) TestTiFlashPartitionTableBroadcastJoin(c *C) { tk.MustExec(fmt.Sprintf("analyze table %v", tbl)) } tk.MustExec("set @@session.tidb_isolation_read_engines='tiflash'") - tk.MustExec("set @@session.tidb_allow_mpp=2") + tk.MustExec("set @@session.tidb_enforce_mpp=1") tk.MustExec("set @@session.tidb_opt_broadcast_join=ON") // mock executor does not support use outer table as build side for outer join, so need to // force the inner table as build side