From da8ef8b4564d75ce3b10a10a7a5c5623a2a55e91 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 12 Jul 2023 19:27:51 +0800 Subject: [PATCH] planner: fix bug in `PhysicalTableReader::Clone()` (#45302) (#45310) close pingcap/tidb#45299 --- planner/core/physical_plans.go | 5 ++--- planner/core/planbuilder_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/planner/core/physical_plans.go b/planner/core/physical_plans.go index 25e947ad3691d..41b30fb3cb1de 100644 --- a/planner/core/physical_plans.go +++ b/planner/core/physical_plans.go @@ -267,9 +267,8 @@ func (p *PhysicalTableReader) Clone() (PhysicalPlan, error) { if cloned.tablePlan, err = p.tablePlan.Clone(); err != nil { return nil, err } - if cloned.TablePlans, err = clonePhysicalPlan(p.TablePlans); err != nil { - return nil, err - } + // TablePlans are actually the flattened plans in tablePlan, so can't copy them, just need to extract from tablePlan + cloned.TablePlans = flattenPushDownPlan(cloned.tablePlan) return cloned, nil } diff --git a/planner/core/planbuilder_test.go b/planner/core/planbuilder_test.go index 8ad1d5c49c0e2..d4c4ab58f163a 100644 --- a/planner/core/planbuilder_test.go +++ b/planner/core/planbuilder_test.go @@ -220,6 +220,36 @@ func TestDeepClone(t *testing.T) { require.NoError(t, checkDeepClone(sort1, sort2)) } +func TestTablePlansAndTablePlanInPhysicalTableReaderClone(t *testing.T) { + ctx := mock.NewContext() + col, cst := &expression.Column{RetType: types.NewFieldType(mysql.TypeString)}, &expression.Constant{RetType: types.NewFieldType(mysql.TypeLonglong)} + schema := expression.NewSchema(col) + tblInfo := &model.TableInfo{} + hist := &statistics.Histogram{Bounds: chunk.New(nil, 0, 0)} + + // table scan + tableScan := &PhysicalTableScan{ + AccessCondition: []expression.Expression{col, cst}, + Table: tblInfo, + Hist: hist, + } + tableScan = tableScan.Init(ctx, 0) + tableScan.SetSchema(schema) + + // table reader + tableReader := &PhysicalTableReader{ + tablePlan: tableScan, + TablePlans: []PhysicalPlan{tableScan}, + StoreType: kv.TiFlash, + } + tableReader = tableReader.Init(ctx, 0) + clonedPlan, err := tableReader.Clone() + require.NoError(t, err) + newTableReader, ok := clonedPlan.(*PhysicalTableReader) + require.True(t, ok) + require.True(t, newTableReader.tablePlan == newTableReader.TablePlans[0]) +} + func TestPhysicalPlanClone(t *testing.T) { ctx := mock.NewContext() col, cst := &expression.Column{RetType: types.NewFieldType(mysql.TypeString)}, &expression.Constant{RetType: types.NewFieldType(mysql.TypeLonglong)}