Skip to content

Commit 27ce02a

Browse files
planner: remove the limitation that predicates can't be pushed through Projection on TableDual (#51329)
close #50614
1 parent f1410bf commit 27ce02a

File tree

4 files changed

+31
-6
lines changed

4 files changed

+31
-6
lines changed

pkg/planner/core/logical_plans.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,9 +1371,13 @@ type LogicalMaxOneRow struct {
13711371
}
13721372

13731373
// LogicalTableDual represents a dual table plan.
1374+
// Note that sometimes we don't set schema for LogicalTableDual (most notably in buildTableDual()), which means
1375+
// outputting 0/1 row with zero column. This semantic may be different from your expectation sometimes but should not
1376+
// cause any actual problems now.
13741377
type LogicalTableDual struct {
13751378
logicalSchemaProducer
13761379

1380+
// RowCount could only be 0 or 1.
13771381
RowCount int
13781382
}
13791383

pkg/planner/core/rule_predicate_push_down.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,6 @@ func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression
522522
return predicates, child
523523
}
524524
}
525-
if len(p.children) == 1 {
526-
if _, isDual := p.children[0].(*LogicalTableDual); isDual {
527-
return predicates, p
528-
}
529-
}
530525
exprCtx := p.SCtx().GetExprCtx()
531526
for _, cond := range predicates {
532527
substituted, hasFailed, newFilter := expression.ColumnSubstituteImpl(exprCtx, cond, p.Schema(), p.Exprs, true)

tests/integrationtest/r/planner/core/casetest/integration.result

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,3 +1781,25 @@ from
17811781
(select 1 as c0) as subq_1;
17821782
c1
17831783
NULL
1784+
use test;
1785+
drop table if exists tt;
1786+
create table tt(a bigint, b bigint, c bigint, d bigint, e bigint, primary key(c,d));
1787+
explain format = brief update tt, (select 1 as c1 ,2 as c2 ,3 as c3, 4 as c4 union all select 2,3,4,5 union all select 3,4,5,6) tmp set tt.a=tmp.c1, tt.b=tmp.c2 where tt.c=tmp.c3 and tt.d=tmp.c4 and (tt.c,tt.d) in ((11,111),(22,222),(33,333),(44,444));
1788+
id estRows task access object operator info
1789+
Update N/A root N/A
1790+
└─Projection 0.00 root test.tt.a, test.tt.b, test.tt.c, test.tt.d, test.tt.e, Column#18, Column#19, Column#20, Column#21
1791+
└─Projection 0.00 root test.tt.a, test.tt.b, test.tt.c, test.tt.d, test.tt.e, Column#18, Column#19, Column#20, Column#21
1792+
└─IndexJoin 0.00 root inner join, inner:TableReader, outer key:Column#20, Column#21, inner key:test.tt.c, test.tt.d, equal cond:eq(Column#20, test.tt.c), eq(Column#21, test.tt.d), other cond:or(or(and(eq(Column#20, 11), eq(test.tt.d, 111)), and(eq(Column#20, 22), eq(test.tt.d, 222))), or(and(eq(Column#20, 33), eq(test.tt.d, 333)), and(eq(Column#20, 44), eq(test.tt.d, 444)))), or(or(and(eq(test.tt.c, 11), eq(Column#21, 111)), and(eq(test.tt.c, 22), eq(Column#21, 222))), or(and(eq(test.tt.c, 33), eq(Column#21, 333)), and(eq(test.tt.c, 44), eq(Column#21, 444))))
1793+
├─Union(Build) 0.00 root
1794+
│ ├─Projection 0.00 root Column#6->Column#18, Column#7->Column#19, Column#8->Column#20, Column#9->Column#21
1795+
│ │ └─Projection 0.00 root 1->Column#6, 2->Column#7, 3->Column#8, 4->Column#9
1796+
│ │ └─TableDual 0.00 root rows:0
1797+
│ ├─Projection 0.00 root Column#10->Column#18, Column#11->Column#19, Column#12->Column#20, Column#13->Column#21
1798+
│ │ └─Projection 0.00 root 2->Column#10, 3->Column#11, 4->Column#12, 5->Column#13
1799+
│ │ └─TableDual 0.00 root rows:0
1800+
│ └─Projection 0.00 root Column#14->Column#18, Column#15->Column#19, Column#16->Column#20, Column#17->Column#21
1801+
│ └─Projection 0.00 root 3->Column#14, 4->Column#15, 5->Column#16, 6->Column#17
1802+
│ └─TableDual 0.00 root rows:0
1803+
└─TableReader(Probe) 0.00 root data:Selection
1804+
└─Selection 0.00 cop[tikv] or(or(and(eq(test.tt.c, 11), eq(test.tt.d, 111)), and(eq(test.tt.c, 22), eq(test.tt.d, 222))), or(and(eq(test.tt.c, 33), eq(test.tt.d, 333)), and(eq(test.tt.c, 44), eq(test.tt.d, 444)))), or(or(eq(test.tt.c, 11), eq(test.tt.c, 22)), or(eq(test.tt.c, 33), eq(test.tt.c, 44))), or(or(eq(test.tt.d, 111), eq(test.tt.d, 222)), or(eq(test.tt.d, 333), eq(test.tt.d, 444)))
1805+
└─TableRangeScan 0.00 cop[tikv] table:tt range: decided by [eq(test.tt.c, Column#20) eq(test.tt.d, Column#21)], keep order:false, stats:pseudo

tests/integrationtest/t/planner/core/casetest/integration.test

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,4 +716,8 @@ select
716716
from
717717
(select 1 as c0) as subq_1;
718718

719-
719+
# TestIssue50614
720+
use test;
721+
drop table if exists tt;
722+
create table tt(a bigint, b bigint, c bigint, d bigint, e bigint, primary key(c,d));
723+
explain format = brief update tt, (select 1 as c1 ,2 as c2 ,3 as c3, 4 as c4 union all select 2,3,4,5 union all select 3,4,5,6) tmp set tt.a=tmp.c1, tt.b=tmp.c2 where tt.c=tmp.c3 and tt.d=tmp.c4 and (tt.c,tt.d) in ((11,111),(22,222),(33,333),(44,444));

0 commit comments

Comments
 (0)