Skip to content

Commit 9bd0c9b

Browse files
qw4990ti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#54985
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 20d24ab commit 9bd0c9b

File tree

2 files changed

+253
-0
lines changed

2 files changed

+253
-0
lines changed

pkg/planner/core/integration_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,108 @@ func TestIssue41458(t *testing.T) {
26852685
}
26862686
}
26872687

2688+
<<<<<<< HEAD
2689+
=======
2690+
func TestIssue48257(t *testing.T) {
2691+
store, dom := testkit.CreateMockStoreAndDomain(t)
2692+
tk := testkit.NewTestKit(t, store)
2693+
h := dom.StatsHandle()
2694+
oriLease := h.Lease()
2695+
h.SetLease(1)
2696+
defer func() {
2697+
h.SetLease(oriLease)
2698+
}()
2699+
tk.MustExec("use test")
2700+
2701+
// 1. test sync load
2702+
tk.MustExec("create table t(a int)")
2703+
tk.MustExec("insert into t value(1)")
2704+
require.NoError(t, h.DumpStatsDeltaToKV(true))
2705+
require.NoError(t, h.Update(context.Background(), dom.InfoSchema()))
2706+
tk.MustExec("analyze table t all columns")
2707+
tk.MustQuery("explain format = brief select * from t").Check(testkit.Rows(
2708+
"TableReader 1.00 root data:TableFullScan",
2709+
"└─TableFullScan 1.00 cop[tikv] table:t keep order:false",
2710+
))
2711+
tk.MustExec("insert into t value(1)")
2712+
require.NoError(t, h.DumpStatsDeltaToKV(true))
2713+
require.NoError(t, h.Update(context.Background(), dom.InfoSchema()))
2714+
tk.MustQuery("explain format = brief select * from t").Check(testkit.Rows(
2715+
"TableReader 2.00 root data:TableFullScan",
2716+
"└─TableFullScan 2.00 cop[tikv] table:t keep order:false",
2717+
))
2718+
tk.MustExec("set tidb_opt_objective='determinate'")
2719+
tk.MustQuery("explain format = brief select * from t").Check(testkit.Rows(
2720+
"TableReader 1.00 root data:TableFullScan",
2721+
"└─TableFullScan 1.00 cop[tikv] table:t keep order:false",
2722+
))
2723+
tk.MustExec("set tidb_opt_objective='moderate'")
2724+
2725+
// 2. test async load
2726+
tk.MustExec("set tidb_stats_load_sync_wait = 0")
2727+
tk.MustExec("create table t1(a int)")
2728+
tk.MustExec("insert into t1 value(1)")
2729+
require.NoError(t, h.DumpStatsDeltaToKV(true))
2730+
require.NoError(t, h.Update(context.Background(), dom.InfoSchema()))
2731+
tk.MustExec("analyze table t1 all columns")
2732+
tk.MustQuery("explain format = brief select * from t1").Check(testkit.Rows(
2733+
"TableReader 1.00 root data:TableFullScan",
2734+
"└─TableFullScan 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
2735+
))
2736+
tk.MustExec("insert into t1 value(1)")
2737+
require.NoError(t, h.DumpStatsDeltaToKV(true))
2738+
require.NoError(t, h.Update(context.Background(), dom.InfoSchema()))
2739+
tk.MustQuery("explain format = brief select * from t1").Check(testkit.Rows(
2740+
"TableReader 2.00 root data:TableFullScan",
2741+
"└─TableFullScan 2.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
2742+
))
2743+
tk.MustExec("set tidb_opt_objective='determinate'")
2744+
tk.MustQuery("explain format = brief select * from t1").Check(testkit.Rows(
2745+
"TableReader 10000.00 root data:TableFullScan",
2746+
"└─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
2747+
))
2748+
require.NoError(t, h.LoadNeededHistograms())
2749+
tk.MustQuery("explain format = brief select * from t1").Check(testkit.Rows(
2750+
"TableReader 1.00 root data:TableFullScan",
2751+
"└─TableFullScan 1.00 cop[tikv] table:t1 keep order:false",
2752+
))
2753+
}
2754+
2755+
func TestIssue54213(t *testing.T) {
2756+
store := testkit.CreateMockStore(t)
2757+
tk := testkit.NewTestKit(t, store)
2758+
2759+
tk.MustExec(`use test`)
2760+
tk.MustExec(`CREATE TABLE tb (
2761+
object_id bigint(20),
2762+
a bigint(20) ,
2763+
b bigint(20) ,
2764+
c bigint(20) ,
2765+
PRIMARY KEY (object_id),
2766+
KEY ab (a,b))`)
2767+
tk.MustQuery(`explain select count(1) from (select /*+ force_index(tb, ab) */ 1 from tb where a=1 and b=1 limit 100) a`).Check(
2768+
testkit.Rows("StreamAgg_11 1.00 root funcs:count(1)->Column#6",
2769+
"└─Limit_12 0.10 root offset:0, count:100",
2770+
" └─IndexReader_16 0.10 root index:Limit_15",
2771+
" └─Limit_15 0.10 cop[tikv] offset:0, count:100",
2772+
" └─IndexRangeScan_14 0.10 cop[tikv] table:tb, index:ab(a, b) range:[1 1,1 1], keep order:false, stats:pseudo"))
2773+
}
2774+
2775+
func TestIssue54870(t *testing.T) {
2776+
store := testkit.CreateMockStore(t)
2777+
tk := testkit.NewTestKit(t, store)
2778+
2779+
tk.MustExec("use test")
2780+
tk.MustExec(`create table t (id int,
2781+
deleted_at datetime(3) NOT NULL DEFAULT '1970-01-01 01:00:01.000',
2782+
is_deleted tinyint(1) GENERATED ALWAYS AS ((deleted_at > _utf8mb4'1970-01-01 01:00:01.000')) VIRTUAL NOT NULL,
2783+
key k(id, is_deleted))`)
2784+
tk.MustExec(`begin`)
2785+
tk.MustExec(`insert into t (id, deleted_at) values (1, now())`)
2786+
tk.MustHavePlan(`select 1 from t where id=1 and is_deleted=true`, "IndexRangeScan")
2787+
}
2788+
2789+
>>>>>>> f2abe99f30c (planner: push necessary predicates without virtual column down through UnionScan (#54985))
26882790
func TestIssue52472(t *testing.T) {
26892791
store := testkit.CreateMockStore(t)
26902792
tk := testkit.NewTestKit(t, store)
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright 2024 PingCAP, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package core
16+
17+
import (
18+
"bytes"
19+
"fmt"
20+
21+
"github.com/pingcap/tidb/pkg/expression"
22+
"github.com/pingcap/tidb/pkg/parser/model"
23+
"github.com/pingcap/tidb/pkg/planner/core/base"
24+
"github.com/pingcap/tidb/pkg/planner/core/operator/logicalop"
25+
"github.com/pingcap/tidb/pkg/planner/property"
26+
"github.com/pingcap/tidb/pkg/planner/util"
27+
"github.com/pingcap/tidb/pkg/planner/util/optimizetrace"
28+
"github.com/pingcap/tidb/pkg/util/plancodec"
29+
)
30+
31+
// LogicalUnionScan is used in non read-only txn or for scanning a local temporary table whose snapshot data is located in memory.
32+
type LogicalUnionScan struct {
33+
logicalop.BaseLogicalPlan
34+
35+
Conditions []expression.Expression
36+
37+
HandleCols util.HandleCols
38+
}
39+
40+
// Init initializes LogicalUnionScan.
41+
func (p LogicalUnionScan) Init(ctx base.PlanContext, qbOffset int) *LogicalUnionScan {
42+
p.BaseLogicalPlan = logicalop.NewBaseLogicalPlan(ctx, plancodec.TypeUnionScan, &p, qbOffset)
43+
return &p
44+
}
45+
46+
// *************************** start implementation of Plan interface ***************************
47+
48+
// ExplainInfo implements Plan interface.
49+
func (p *LogicalUnionScan) ExplainInfo() string {
50+
buffer := bytes.NewBufferString("")
51+
fmt.Fprintf(buffer, "conds:%s",
52+
expression.SortedExplainExpressionList(p.SCtx().GetExprCtx().GetEvalCtx(), p.Conditions))
53+
fmt.Fprintf(buffer, ", handle:%s", p.HandleCols)
54+
return buffer.String()
55+
}
56+
57+
// *************************** end implementation of Plan interface ***************************
58+
59+
// *************************** start implementation of logicalPlan interface ***************************
60+
61+
// HashCode inherits BaseLogicalPlan.LogicalPlan.<0th> implementation.
62+
63+
// PredicatePushDown implements base.LogicalPlan.<1st> interface.
64+
func (p *LogicalUnionScan) PredicatePushDown(predicates []expression.Expression, opt *optimizetrace.LogicalOptimizeOp) ([]expression.Expression, base.LogicalPlan) {
65+
var predicatesWithVCol, predicatesWithoutVCol []expression.Expression
66+
// predicates with virtual columns can't be pushed down to TiKV/TiFlash so they'll be put into a Projection
67+
// below the UnionScan, but the current UnionScan doesn't support placing Projection below it, see #53951.
68+
for _, expr := range predicates {
69+
if expression.ContainVirtualColumn([]expression.Expression{expr}) {
70+
predicatesWithVCol = append(predicatesWithVCol, expr)
71+
} else {
72+
predicatesWithoutVCol = append(predicatesWithoutVCol, expr)
73+
}
74+
}
75+
predicates = predicatesWithoutVCol
76+
retainedPredicates, _ := p.Children()[0].PredicatePushDown(predicates, opt)
77+
p.Conditions = make([]expression.Expression, 0, len(predicates))
78+
p.Conditions = append(p.Conditions, predicates...)
79+
// The conditions in UnionScan is only used for added rows, so parent Selection should not be removed.
80+
retainedPredicates = append(retainedPredicates, predicatesWithVCol...)
81+
return retainedPredicates, p
82+
}
83+
84+
// PruneColumns implements base.LogicalPlan.<2nd> interface.
85+
func (p *LogicalUnionScan) PruneColumns(parentUsedCols []*expression.Column, opt *optimizetrace.LogicalOptimizeOp) (base.LogicalPlan, error) {
86+
for i := 0; i < p.HandleCols.NumCols(); i++ {
87+
parentUsedCols = append(parentUsedCols, p.HandleCols.GetCol(i))
88+
}
89+
for _, col := range p.Schema().Columns {
90+
if col.ID == model.ExtraPhysTblID {
91+
parentUsedCols = append(parentUsedCols, col)
92+
}
93+
}
94+
condCols := expression.ExtractColumnsFromExpressions(nil, p.Conditions, nil)
95+
parentUsedCols = append(parentUsedCols, condCols...)
96+
var err error
97+
p.Children()[0], err = p.Children()[0].PruneColumns(parentUsedCols, opt)
98+
if err != nil {
99+
return nil, err
100+
}
101+
return p, nil
102+
}
103+
104+
// FindBestTask inherits BaseLogicalPlan.LogicalPlan.<3rd> implementation.
105+
106+
// BuildKeyInfo inherits BaseLogicalPlan.LogicalPlan.<4th> implementation.
107+
108+
// PushDownTopN inherits BaseLogicalPlan.LogicalPlan.<5th> implementation.
109+
110+
// DeriveTopN inherits BaseLogicalPlan.LogicalPlan.<6th> implementation.
111+
112+
// PredicateSimplification inherits BaseLogicalPlan.LogicalPlan.<7th> implementation.
113+
114+
// ConstantPropagation inherits BaseLogicalPlan.LogicalPlan.<8th> implementation.
115+
116+
// PullUpConstantPredicates inherits BaseLogicalPlan.LogicalPlan.<9th> implementation.
117+
118+
// RecursiveDeriveStats inherits BaseLogicalPlan.LogicalPlan.<10th> implementation.
119+
120+
// DeriveStats inherits BaseLogicalPlan.LogicalPlan.<11th> implementation.
121+
122+
// ExtractColGroups inherits BaseLogicalPlan.LogicalPlan.<12th> implementation.
123+
124+
// PreparePossibleProperties inherits BaseLogicalPlan.LogicalPlan.<13th> implementation.
125+
126+
// ExhaustPhysicalPlans implements base.LogicalPlan.<14th> interface.
127+
func (p *LogicalUnionScan) ExhaustPhysicalPlans(prop *property.PhysicalProperty) ([]base.PhysicalPlan, bool, error) {
128+
return exhaustPhysicalPlans4LogicalUnionScan(p, prop)
129+
}
130+
131+
// ExtractCorrelatedCols inherits BaseLogicalPlan.LogicalPlan.<15th> implementation.
132+
133+
// MaxOneRow inherits BaseLogicalPlan.LogicalPlan.<16th> implementation.
134+
135+
// Children inherits BaseLogicalPlan.LogicalPlan.<17th> implementation.
136+
137+
// SetChildren inherits BaseLogicalPlan.LogicalPlan.<18th> implementation.
138+
139+
// SetChild inherits BaseLogicalPlan.LogicalPlan.<19th> implementation.
140+
141+
// RollBackTaskMap inherits BaseLogicalPlan.LogicalPlan.<20th> implementation.
142+
143+
// CanPushToCop inherits BaseLogicalPlan.LogicalPlan.<21st> implementation.
144+
145+
// ExtractFD inherits BaseLogicalPlan.LogicalPlan.<22nd> implementation.
146+
147+
// GetBaseLogicalPlan inherits BaseLogicalPlan.LogicalPlan.<23rd> implementation.
148+
149+
// ConvertOuterToInnerJoin inherits BaseLogicalPlan.LogicalPlan.<24th> implementation.
150+
151+
// *************************** end implementation of logicalPlan interface ***************************

0 commit comments

Comments
 (0)