@@ -62,6 +62,9 @@ var HeavyFunctionNameMap = map[string]struct{}{
62
62
}
63
63
64
64
func attachPlan2Task (p base.PhysicalPlan , t base.Task ) base.Task {
65
+ // since almost all current physical plan will be attached to bottom encapsulated task.
66
+ // we do the stats inheritance here for all the index join inner task.
67
+ inheritStatsFromBottomTaskForIndexJoinInner (p , t )
65
68
switch v := t .(type ) {
66
69
case * CopTask :
67
70
if v .indexPlanFinished {
@@ -130,8 +133,8 @@ func (p *PhysicalUnionScan) Attach2Task(tasks ...base.Task) base.Task {
130
133
sel .SetChildren (pj .Children ()... )
131
134
p .SetChildren (sel )
132
135
p .SetStats (task .Plan ().StatsInfo ())
133
- rt , _ := task .(* RootTask )
134
- rt .SetPlan (p )
136
+ rt := task .(* RootTask )
137
+ rt .SetPlan (p ) // root task plan current is p headed.
135
138
pj .SetChildren (p )
136
139
return pj .Attach2Task (task )
137
140
}
@@ -160,6 +163,8 @@ func (p *PhysicalApply) Attach2Task(tasks ...base.Task) base.Task {
160
163
p .schema = BuildPhysicalJoinSchema (p .JoinType , p )
161
164
t := & RootTask {}
162
165
t .SetPlan (p )
166
+ // inherit left and right child's warnings.
167
+ t .warnings .CopyFrom (& lTask .(* RootTask ).warnings , & rTask .(* RootTask ).warnings )
163
168
return t
164
169
}
165
170
@@ -200,6 +205,7 @@ func indexHashJoinAttach2TaskV2(p *PhysicalIndexHashJoin, tasks ...base.Task) ba
200
205
}
201
206
t := & RootTask {}
202
207
t .SetPlan (p )
208
+ t .warnings .CopyFrom (& outerTask .(* RootTask ).warnings , & innerTask .(* RootTask ).warnings )
203
209
return t
204
210
}
205
211
@@ -232,6 +238,7 @@ func indexJoinAttach2TaskV2(p *PhysicalIndexJoin, tasks ...base.Task) base.Task
232
238
}
233
239
t := & RootTask {}
234
240
t .SetPlan (p )
241
+ t .warnings .CopyFrom (& outerTask .(* RootTask ).warnings , & innerTask .(* RootTask ).warnings )
235
242
return t
236
243
}
237
244
@@ -264,6 +271,7 @@ func (p *PhysicalHashJoin) Attach2Task(tasks ...base.Task) base.Task {
264
271
p .SetChildren (lTask .Plan (), rTask .Plan ())
265
272
task := & RootTask {}
266
273
task .SetPlan (p )
274
+ task .warnings .CopyFrom (& rTask .(* RootTask ).warnings , & lTask .(* RootTask ).warnings )
267
275
return task
268
276
}
269
277
@@ -504,6 +512,7 @@ func (p *PhysicalHashJoin) attach2TaskForMpp(tasks ...base.Task) base.Task {
504
512
partTp : outerTask .partTp ,
505
513
hashCols : outerTask .hashCols ,
506
514
}
515
+ task .warnings .CopyFrom (& rTask .warnings , & lTask .warnings )
507
516
// Current TiFlash doesn't support receive Join executors' schema info directly from TiDB.
508
517
// Instead, it calculates Join executors' output schema using algorithm like BuildPhysicalJoinSchema which
509
518
// produces full semantic schema.
@@ -594,6 +603,7 @@ func (p *PhysicalHashJoin) attach2TaskForTiFlash(tasks ...base.Task) base.Task {
594
603
indexPlanFinished : true ,
595
604
tablePlan : p ,
596
605
}
606
+ task .warnings .CopyFrom (& rTask .warnings , & lTask .warnings )
597
607
return task
598
608
}
599
609
@@ -604,6 +614,7 @@ func (p *PhysicalMergeJoin) Attach2Task(tasks ...base.Task) base.Task {
604
614
p .SetChildren (lTask .Plan (), rTask .Plan ())
605
615
t := & RootTask {}
606
616
t .SetPlan (p )
617
+ t .warnings .CopyFrom (& rTask .(* RootTask ).warnings , & lTask .(* RootTask ).warnings )
607
618
return t
608
619
}
609
620
@@ -1503,6 +1514,48 @@ func (sel *PhysicalSelection) Attach2Task(tasks ...base.Task) base.Task {
1503
1514
return attachPlan2Task (sel , t )
1504
1515
}
1505
1516
1517
+ func inheritStatsFromBottomElemForIndexJoinInner (p base.PhysicalPlan , indexJoinInfo * IndexJoinInfo , stats * property.StatsInfo ) {
1518
+ var isIndexJoin bool
1519
+ switch p .(type ) {
1520
+ case * PhysicalIndexJoin , * PhysicalIndexHashJoin , * PhysicalIndexMergeJoin :
1521
+ isIndexJoin = true
1522
+ default :
1523
+ }
1524
+ // indexJoinInfo != nil means the child Task comes from an index join inner side.
1525
+ // !isIndexJoin means the childTask only be passed through to indexJoin as an END.
1526
+ if ! isIndexJoin && indexJoinInfo != nil {
1527
+ switch p .(type ) {
1528
+ case * PhysicalSelection :
1529
+ // todo: for simplicity, we can just inherit it from child.
1530
+ p .StatsInfo ().ScaleByExpectCnt (stats .RowCount )
1531
+ case * PhysicalProjection :
1532
+ // mainly about the rowEst, proj doesn't change that.
1533
+ p .StatsInfo ().ScaleByExpectCnt (stats .RowCount )
1534
+ case * PhysicalHashAgg , * PhysicalStreamAgg :
1535
+ // todo: for simplicity, we can just inherit it from child.
1536
+ p .StatsInfo ().ScaleByExpectCnt (stats .RowCount )
1537
+ case * PhysicalUnionScan :
1538
+ // todo: for simplicity, we can just inherit it from child.
1539
+ p .StatsInfo ().ScaleByExpectCnt (stats .RowCount )
1540
+ default :
1541
+ p .StatsInfo ().ScaleByExpectCnt (stats .RowCount )
1542
+ }
1543
+ }
1544
+ }
1545
+
1546
+ func inheritStatsFromBottomTaskForIndexJoinInner (p base.PhysicalPlan , t base.Task ) {
1547
+ var indexJoinInfo * IndexJoinInfo
1548
+ switch v := t .(type ) {
1549
+ case * CopTask :
1550
+ indexJoinInfo = v .IndexJoinInfo
1551
+ case * RootTask :
1552
+ indexJoinInfo = v .IndexJoinInfo
1553
+ default :
1554
+ // index join's inner side couldn't be a mppTask, leave it.
1555
+ }
1556
+ inheritStatsFromBottomElemForIndexJoinInner (p , indexJoinInfo , t .Plan ().StatsInfo ())
1557
+ }
1558
+
1506
1559
// CheckAggCanPushCop checks whether the aggFuncs and groupByItems can
1507
1560
// be pushed down to coprocessor.
1508
1561
func CheckAggCanPushCop (sctx base.PlanContext , aggFuncs []* aggregation.AggFuncDesc , groupByItems []expression.Expression , storeType kv.StoreType ) bool {
@@ -2179,6 +2232,10 @@ func (p *PhysicalStreamAgg) Attach2Task(tasks ...base.Task) base.Task {
2179
2232
if partialAgg != nil {
2180
2233
if cop .tablePlan != nil {
2181
2234
cop .finishIndexPlan ()
2235
+ // the partialAgg attachment didn't follow the attachPlan2Task function, so here we actively call
2236
+ // inheritStatsFromBottomForIndexJoinInner(p, t) to inherit stats from the bottom plan for index
2237
+ // join inner side. note: partialAgg will share stats with finalAgg.
2238
+ inheritStatsFromBottomElemForIndexJoinInner (partialAgg , cop .IndexJoinInfo , cop .tablePlan .StatsInfo ())
2182
2239
partialAgg .SetChildren (cop .tablePlan )
2183
2240
cop .tablePlan = partialAgg
2184
2241
// If needExtraProj is true, a projection will be created above the PhysicalIndexLookUpReader to make sure
@@ -2189,10 +2246,15 @@ func (p *PhysicalStreamAgg) Attach2Task(tasks ...base.Task) base.Task {
2189
2246
// the partial agg, and the schema will be broken.
2190
2247
cop .needExtraProj = false
2191
2248
} else {
2249
+ // the partialAgg attachment didn't follow the attachPlan2Task function, so here we actively call
2250
+ // inheritStatsFromBottomForIndexJoinInner(p, t) to inherit stats from the bottom plan for index
2251
+ // join inner side. note: partialAgg will share stats with finalAgg.
2252
+ inheritStatsFromBottomElemForIndexJoinInner (partialAgg , cop .IndexJoinInfo , cop .indexPlan .StatsInfo ())
2192
2253
partialAgg .SetChildren (cop .indexPlan )
2193
2254
cop .indexPlan = partialAgg
2194
2255
}
2195
2256
}
2257
+ // COP Task -> Root Task, warnings inherited inside.
2196
2258
t = cop .ConvertToRootTask (p .SCtx ())
2197
2259
attachPlan2Task (finalAgg , t )
2198
2260
}
@@ -2680,6 +2742,10 @@ func (p *PhysicalHashAgg) Attach2Task(tasks ...base.Task) base.Task {
2680
2742
if partialAgg != nil {
2681
2743
if cop .tablePlan != nil {
2682
2744
cop .finishIndexPlan ()
2745
+ // the partialAgg attachment didn't follow the attachPlan2Task function, so here we actively call
2746
+ // inheritStatsFromBottomForIndexJoinInner(p, t) to inherit stats from the bottom plan for index
2747
+ // join inner side. note: partialAgg will share stats with finalAgg.
2748
+ inheritStatsFromBottomElemForIndexJoinInner (partialAgg , cop .IndexJoinInfo , cop .tablePlan .StatsInfo ())
2683
2749
partialAgg .SetChildren (cop .tablePlan )
2684
2750
cop .tablePlan = partialAgg
2685
2751
// If needExtraProj is true, a projection will be created above the PhysicalIndexLookUpReader to make sure
@@ -2690,6 +2756,10 @@ func (p *PhysicalHashAgg) Attach2Task(tasks ...base.Task) base.Task {
2690
2756
// the partial agg, and the schema will be broken.
2691
2757
cop .needExtraProj = false
2692
2758
} else {
2759
+ // the partialAgg attachment didn't follow the attachPlan2Task function, so here we actively call
2760
+ // inheritStatsFromBottomForIndexJoinInner(p, t) to inherit stats from the bottom plan for index
2761
+ // join inner side. note: partialAgg will share stats with finalAgg.
2762
+ inheritStatsFromBottomElemForIndexJoinInner (partialAgg , cop .IndexJoinInfo , cop .indexPlan .StatsInfo ())
2693
2763
partialAgg .SetChildren (cop .indexPlan )
2694
2764
cop .indexPlan = partialAgg
2695
2765
}
@@ -2744,17 +2814,20 @@ func (p *PhysicalCTEStorage) Attach2Task(tasks ...base.Task) base.Task {
2744
2814
t := tasks [0 ].Copy ()
2745
2815
if mpp , ok := t .(* MppTask ); ok {
2746
2816
p .SetChildren (t .Plan ())
2747
- return & MppTask {
2817
+ nt := & MppTask {
2748
2818
p : p ,
2749
2819
partTp : mpp .partTp ,
2750
2820
hashCols : mpp .hashCols ,
2751
2821
tblColHists : mpp .tblColHists ,
2752
2822
}
2823
+ nt .warnings .CopyFrom (& mpp .warnings )
2824
+ return nt
2753
2825
}
2754
2826
t .ConvertToRootTask (p .SCtx ())
2755
2827
p .SetChildren (t .Plan ())
2756
2828
ta := & RootTask {}
2757
2829
ta .SetPlan (p )
2830
+ ta .warnings .CopyFrom (& t .(* RootTask ).warnings )
2758
2831
return ta
2759
2832
}
2760
2833
@@ -2782,6 +2855,21 @@ func (p *PhysicalSequence) Attach2Task(tasks ...base.Task) base.Task {
2782
2855
hashCols : lastTask .hashCols ,
2783
2856
tblColHists : lastTask .tblColHists ,
2784
2857
}
2858
+ tmpWarnings := make ([]* simpleWarnings , 0 , len (tasks ))
2859
+ for _ , t := range tasks {
2860
+ if mpp , ok := t .(* MppTask ); ok {
2861
+ tmpWarnings = append (tmpWarnings , & mpp .warnings )
2862
+ continue
2863
+ }
2864
+ if root , ok := t .(* RootTask ); ok {
2865
+ tmpWarnings = append (tmpWarnings , & root .warnings )
2866
+ continue
2867
+ }
2868
+ if cop , ok := t .(* CopTask ); ok {
2869
+ tmpWarnings = append (tmpWarnings , & cop .warnings )
2870
+ }
2871
+ }
2872
+ mppTask .warnings .CopyFrom (tmpWarnings ... )
2785
2873
return mppTask
2786
2874
}
2787
2875
@@ -2880,11 +2968,13 @@ func (t *MppTask) enforceExchangerImpl(prop *property.PhysicalProperty) *MppTask
2880
2968
sender .SetChildren (t .p )
2881
2969
receiver := PhysicalExchangeReceiver {}.Init (ctx , t .p .StatsInfo ())
2882
2970
receiver .SetChildren (sender )
2883
- return & MppTask {
2971
+ nt := & MppTask {
2884
2972
p : receiver ,
2885
2973
partTp : prop .MPPPartitionTp ,
2886
2974
hashCols : prop .MPPPartitionCols ,
2887
2975
}
2976
+ nt .warnings .CopyFrom (& t .warnings )
2977
+ return nt
2888
2978
}
2889
2979
2890
2980
// IndexJoinInfo is generated by index join's inner ds, which will build their own index choice based
0 commit comments