Skip to content

Commit f2abe99

Browse files
authored
planner: push necessary predicates without virtual column down through UnionScan (#54985)
close #54870
1 parent 7ffc7c9 commit f2abe99

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

pkg/planner/core/integration_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,20 @@ func TestIssue54213(t *testing.T) {
22372237
" └─IndexRangeScan_14 0.10 cop[tikv] table:tb, index:ab(a, b) range:[1 1,1 1], keep order:false, stats:pseudo"))
22382238
}
22392239

2240+
func TestIssue54870(t *testing.T) {
2241+
store := testkit.CreateMockStore(t)
2242+
tk := testkit.NewTestKit(t, store)
2243+
2244+
tk.MustExec("use test")
2245+
tk.MustExec(`create table t (id int,
2246+
deleted_at datetime(3) NOT NULL DEFAULT '1970-01-01 01:00:01.000',
2247+
is_deleted tinyint(1) GENERATED ALWAYS AS ((deleted_at > _utf8mb4'1970-01-01 01:00:01.000')) VIRTUAL NOT NULL,
2248+
key k(id, is_deleted))`)
2249+
tk.MustExec(`begin`)
2250+
tk.MustExec(`insert into t (id, deleted_at) values (1, now())`)
2251+
tk.MustHavePlan(`select 1 from t where id=1 and is_deleted=true`, "IndexRangeScan")
2252+
}
2253+
22402254
func TestIssue52472(t *testing.T) {
22412255
store := testkit.CreateMockStore(t)
22422256
tk := testkit.NewTestKit(t, store)

pkg/planner/core/logical_union_scan.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,22 @@ func (p *LogicalUnionScan) ExplainInfo() string {
6262

6363
// PredicatePushDown implements base.LogicalPlan.<1st> interface.
6464
func (p *LogicalUnionScan) PredicatePushDown(predicates []expression.Expression, opt *optimizetrace.LogicalOptimizeOp) ([]expression.Expression, base.LogicalPlan) {
65-
if expression.ContainVirtualColumn(predicates) {
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-
return predicates, p
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+
}
6974
}
75+
predicates = predicatesWithoutVCol
7076
retainedPredicates, _ := p.Children()[0].PredicatePushDown(predicates, opt)
7177
p.Conditions = make([]expression.Expression, 0, len(predicates))
7278
p.Conditions = append(p.Conditions, predicates...)
7379
// The conditions in UnionScan is only used for added rows, so parent Selection should not be removed.
80+
retainedPredicates = append(retainedPredicates, predicatesWithVCol...)
7481
return retainedPredicates, p
7582
}
7683

0 commit comments

Comments
 (0)