Skip to content

Commit c90dcf8

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 42b624c commit c90dcf8

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed

pkg/planner/core/integration_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,6 +2288,43 @@ func TestIssue48257(t *testing.T) {
22882288
))
22892289
}
22902290

2291+
<<<<<<< HEAD
2292+
=======
2293+
func TestIssue54213(t *testing.T) {
2294+
store := testkit.CreateMockStore(t)
2295+
tk := testkit.NewTestKit(t, store)
2296+
2297+
tk.MustExec(`use test`)
2298+
tk.MustExec(`CREATE TABLE tb (
2299+
object_id bigint(20),
2300+
a bigint(20) ,
2301+
b bigint(20) ,
2302+
c bigint(20) ,
2303+
PRIMARY KEY (object_id),
2304+
KEY ab (a,b))`)
2305+
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(
2306+
testkit.Rows("StreamAgg_11 1.00 root funcs:count(1)->Column#6",
2307+
"└─Limit_12 0.10 root offset:0, count:100",
2308+
" └─IndexReader_16 0.10 root index:Limit_15",
2309+
" └─Limit_15 0.10 cop[tikv] offset:0, count:100",
2310+
" └─IndexRangeScan_14 0.10 cop[tikv] table:tb, index:ab(a, b) range:[1 1,1 1], keep order:false, stats:pseudo"))
2311+
}
2312+
2313+
func TestIssue54870(t *testing.T) {
2314+
store := testkit.CreateMockStore(t)
2315+
tk := testkit.NewTestKit(t, store)
2316+
2317+
tk.MustExec("use test")
2318+
tk.MustExec(`create table t (id int,
2319+
deleted_at datetime(3) NOT NULL DEFAULT '1970-01-01 01:00:01.000',
2320+
is_deleted tinyint(1) GENERATED ALWAYS AS ((deleted_at > _utf8mb4'1970-01-01 01:00:01.000')) VIRTUAL NOT NULL,
2321+
key k(id, is_deleted))`)
2322+
tk.MustExec(`begin`)
2323+
tk.MustExec(`insert into t (id, deleted_at) values (1, now())`)
2324+
tk.MustHavePlan(`select 1 from t where id=1 and is_deleted=true`, "IndexRangeScan")
2325+
}
2326+
2327+
>>>>>>> f2abe99f30c (planner: push necessary predicates without virtual column down through UnionScan (#54985))
22912328
func TestIssue52472(t *testing.T) {
22922329
store := testkit.CreateMockStore(t)
22932330
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)