diff --git a/pkg/planner/core/logical_plans.go b/pkg/planner/core/logical_plans.go index deb0071455424..b10fdc3a11d5c 100644 --- a/pkg/planner/core/logical_plans.go +++ b/pkg/planner/core/logical_plans.go @@ -1418,9 +1418,13 @@ type LogicalMaxOneRow struct { } // LogicalTableDual represents a dual table plan. +// Note that sometimes we don't set schema for LogicalTableDual (most notably in buildTableDual()), which means +// outputting 0/1 row with zero column. This semantic may be different from your expectation sometimes but should not +// cause any actual problems now. type LogicalTableDual struct { logicalSchemaProducer + // RowCount could only be 0 or 1. RowCount int } diff --git a/pkg/planner/core/rule_predicate_push_down.go b/pkg/planner/core/rule_predicate_push_down.go index a960e5aa97490..468d166b17480 100644 --- a/pkg/planner/core/rule_predicate_push_down.go +++ b/pkg/planner/core/rule_predicate_push_down.go @@ -521,11 +521,6 @@ func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression return predicates, child } } - if len(p.children) == 1 { - if _, isDual := p.children[0].(*LogicalTableDual); isDual { - return predicates, p - } - } for _, cond := range predicates { substituted, hasFailed, newFilter := expression.ColumnSubstituteImpl(cond, p.Schema(), p.Exprs, true) if substituted && !hasFailed && !expression.HasGetSetVarFunc(newFilter) { diff --git a/tests/integrationtest/r/planner/core/casetest/integration.result b/tests/integrationtest/r/planner/core/casetest/integration.result index 1b2eefc689c9d..f27d6c26820a4 100644 --- a/tests/integrationtest/r/planner/core/casetest/integration.result +++ b/tests/integrationtest/r/planner/core/casetest/integration.result @@ -1558,3 +1558,25 @@ from (select 1 as c0) as subq_1; c1 NULL +use test; +drop table if exists tt; +create table tt(a bigint, b bigint, c bigint, d bigint, e bigint, primary key(c,d)); +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)); +id estRows task access object operator info +Update N/A root N/A +└─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 + └─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 + └─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)))) + ├─Union(Build) 0.00 root + │ ├─Projection 0.00 root Column#6->Column#18, Column#7->Column#19, Column#8->Column#20, Column#9->Column#21 + │ │ └─Projection 0.00 root 1->Column#6, 2->Column#7, 3->Column#8, 4->Column#9 + │ │ └─TableDual 0.00 root rows:0 + │ ├─Projection 0.00 root Column#10->Column#18, Column#11->Column#19, Column#12->Column#20, Column#13->Column#21 + │ │ └─Projection 0.00 root 2->Column#10, 3->Column#11, 4->Column#12, 5->Column#13 + │ │ └─TableDual 0.00 root rows:0 + │ └─Projection 0.00 root Column#14->Column#18, Column#15->Column#19, Column#16->Column#20, Column#17->Column#21 + │ └─Projection 0.00 root 3->Column#14, 4->Column#15, 5->Column#16, 6->Column#17 + │ └─TableDual 0.00 root rows:0 + └─TableReader(Probe) 0.00 root data:Selection + └─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))) + └─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 diff --git a/tests/integrationtest/t/planner/core/casetest/integration.test b/tests/integrationtest/t/planner/core/casetest/integration.test index c9c3a78fd7429..28f54fa8214b3 100644 --- a/tests/integrationtest/t/planner/core/casetest/integration.test +++ b/tests/integrationtest/t/planner/core/casetest/integration.test @@ -568,4 +568,10 @@ select ) order by c0 desc limit 1) as c1 from - (select 1 as c0) as subq_1; \ No newline at end of file + (select 1 as c0) as subq_1; + +# TestIssue50614 +use test; +drop table if exists tt; +create table tt(a bigint, b bigint, c bigint, d bigint, e bigint, primary key(c,d)); +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));