From dc60fbe7ac3b582feefbffe5f3724ef5b44cf8fb Mon Sep 17 00:00:00 2001 From: Zhou Kunqin <25057648+time-and-fate@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:33:31 +0800 Subject: [PATCH 1/2] This is an automated cherry-pick of #51329 Signed-off-by: ti-chi-bot --- pkg/planner/core/logical_plans.go | 4 ++++ pkg/planner/core/rule_predicate_push_down.go | 4 ++++ .../planner/core/casetest/integration.result | 22 +++++++++++++++++++ .../t/planner/core/casetest/integration.test | 12 +++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) 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..203d341747205 100644 --- a/pkg/planner/core/rule_predicate_push_down.go +++ b/pkg/planner/core/rule_predicate_push_down.go @@ -521,11 +521,15 @@ func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression return predicates, child } } +<<<<<<< HEAD if len(p.children) == 1 { if _, isDual := p.children[0].(*LogicalTableDual); isDual { return predicates, p } } +======= + exprCtx := p.SCtx().GetExprCtx() +>>>>>>> 27ce02afd2e (planner: remove the limitation that predicates can't be pushed through `Projection` on `TableDual` (#51329)) 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..31a7a28f7189c 100644 --- a/tests/integrationtest/t/planner/core/casetest/integration.test +++ b/tests/integrationtest/t/planner/core/casetest/integration.test @@ -568,4 +568,14 @@ select ) order by c0 desc limit 1) as c1 from - (select 1 as c0) as subq_1; \ No newline at end of file +<<<<<<< HEAD + (select 1 as c0) as subq_1; +======= + (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)); +>>>>>>> 27ce02afd2e (planner: remove the limitation that predicates can't be pushed through `Projection` on `TableDual` (#51329)) From 8c89e94c75e6c1fd79aaedef2ab8b0c0150c37c3 Mon Sep 17 00:00:00 2001 From: time-and-fate <25057648+time-and-fate@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:29:31 +0800 Subject: [PATCH 2/2] resolve conflicts --- pkg/planner/core/rule_predicate_push_down.go | 9 --------- .../t/planner/core/casetest/integration.test | 4 ---- 2 files changed, 13 deletions(-) diff --git a/pkg/planner/core/rule_predicate_push_down.go b/pkg/planner/core/rule_predicate_push_down.go index 203d341747205..468d166b17480 100644 --- a/pkg/planner/core/rule_predicate_push_down.go +++ b/pkg/planner/core/rule_predicate_push_down.go @@ -521,15 +521,6 @@ func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression return predicates, child } } -<<<<<<< HEAD - if len(p.children) == 1 { - if _, isDual := p.children[0].(*LogicalTableDual); isDual { - return predicates, p - } - } -======= - exprCtx := p.SCtx().GetExprCtx() ->>>>>>> 27ce02afd2e (planner: remove the limitation that predicates can't be pushed through `Projection` on `TableDual` (#51329)) 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/t/planner/core/casetest/integration.test b/tests/integrationtest/t/planner/core/casetest/integration.test index 31a7a28f7189c..28f54fa8214b3 100644 --- a/tests/integrationtest/t/planner/core/casetest/integration.test +++ b/tests/integrationtest/t/planner/core/casetest/integration.test @@ -568,9 +568,6 @@ select ) order by c0 desc limit 1) as c1 from -<<<<<<< HEAD - (select 1 as c0) as subq_1; -======= (select 1 as c0) as subq_1; # TestIssue50614 @@ -578,4 +575,3 @@ 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)); ->>>>>>> 27ce02afd2e (planner: remove the limitation that predicates can't be pushed through `Projection` on `TableDual` (#51329))