From 1c4c1c1fc4f469551b35417d7d1f0520fe2545dc Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 17:22:20 +0800 Subject: [PATCH 01/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- pkg/planner/core/issuetest/planner_issue_test.go | 9 +++++++++ pkg/planner/core/task_base.go | 1 + 2 files changed, 10 insertions(+) diff --git a/pkg/planner/core/issuetest/planner_issue_test.go b/pkg/planner/core/issuetest/planner_issue_test.go index cb072c14e1df0..3aa3e92bc0795 100644 --- a/pkg/planner/core/issuetest/planner_issue_test.go +++ b/pkg/planner/core/issuetest/planner_issue_test.go @@ -159,3 +159,12 @@ func TestIssues57583(t *testing.T) { " └─Selection_20 9990.00 cop[tikv] not(isnull(test.t1.v1))", " └─TableFullScan_19 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo")) } + +func TestIssue58476(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + tk.MustExec("CREATE TABLE t3 (id int PRIMARY KEY,c1 varchar(256),c2 varchar(256) GENERATED ALWAYS AS (concat(c1, c1)) VIRTUAL,KEY (id));") + tk.MustExec("insert into t3(id, c1) values (50, 'c');") + tk.MustQuery("SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;").Check(testkit.Rows()) +} diff --git a/pkg/planner/core/task_base.go b/pkg/planner/core/task_base.go index 27537d718c2cc..02b8b891cb82a 100644 --- a/pkg/planner/core/task_base.go +++ b/pkg/planner/core/task_base.go @@ -378,6 +378,7 @@ func (t *CopTask) convertToRootTaskImpl(ctx base.PlanContext) *RootTask { proj.SetChildren(p) newTask.SetPlan(proj) } + t.handleRootTaskConds(ctx, newTask) return newTask } if t.indexPlan != nil && t.tablePlan != nil { From 1b256fc2c1b41ed49a55a0cc789b9567add9af5c Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 17:28:10 +0800 Subject: [PATCH 02/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- pkg/planner/core/issuetest/BUILD.bazel | 2 +- pkg/planner/core/issuetest/planner_issue_test.go | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/planner/core/issuetest/BUILD.bazel b/pkg/planner/core/issuetest/BUILD.bazel index df6e246c0df8c..2a3b07f0c3748 100644 --- a/pkg/planner/core/issuetest/BUILD.bazel +++ b/pkg/planner/core/issuetest/BUILD.bazel @@ -10,7 +10,7 @@ go_test( data = glob(["testdata/**"]), flaky = True, race = "on", - shard_count = 5, + shard_count = 6, deps = [ "//pkg/parser", "//pkg/planner", diff --git a/pkg/planner/core/issuetest/planner_issue_test.go b/pkg/planner/core/issuetest/planner_issue_test.go index 3aa3e92bc0795..98c6d0bfd9104 100644 --- a/pkg/planner/core/issuetest/planner_issue_test.go +++ b/pkg/planner/core/issuetest/planner_issue_test.go @@ -167,4 +167,13 @@ func TestIssue58476(t *testing.T) { tk.MustExec("CREATE TABLE t3 (id int PRIMARY KEY,c1 varchar(256),c2 varchar(256) GENERATED ALWAYS AS (concat(c1, c1)) VIRTUAL,KEY (id));") tk.MustExec("insert into t3(id, c1) values (50, 'c');") tk.MustQuery("SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;").Check(testkit.Rows()) + tk.MustQuery("EXPLAIN SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;"). + Check(testkit.Rows( + `Projection_7 249.75 root test.t3.id`, + `└─Selection_15 249.75 root ge(test.t3.c2, "a"), le(test.t3.c2, "b")`, + ` └─Projection_14 9990.00 root test.t3.id, test.t3.c2`, + ` └─IndexMerge_12 9990.00 root type: union`, + ` ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t3, index:id(id) range:[-inf,100), keep order:false, stats:pseudo`, + ` ├─TableRangeScan_10(Build) 3333.33 cop[tikv] table:t3 range:(0,+inf], keep order:false, stats:pseudo`, + ` └─TableRowIDScan_11(Probe) 9990.00 cop[tikv] table:t3 keep order:false, stats:pseudo`)) } From 4c93a5bdfeac3d6258014a3cb5026930cfbba666 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 18:06:35 +0800 Subject: [PATCH 03/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- tests/integrationtest/r/index_merge.result | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integrationtest/r/index_merge.result b/tests/integrationtest/r/index_merge.result index 1a842a0ef04ff..712dee3589f63 100644 --- a/tests/integrationtest/r/index_merge.result +++ b/tests/integrationtest/r/index_merge.result @@ -238,7 +238,7 @@ insert into t1(c1, c2) values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_12 2250.55 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -253,7 +253,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_12 2825.66 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -268,7 +268,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_12 2825.66 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -283,7 +283,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1; id estRows task access object operator info Sort_5 4800.37 root index_merge.t1.c1 -└─Selection_12 2660.47 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) +└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -303,7 +303,7 @@ select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_12 2250.55 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -656,7 +656,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root index_merge.t1.c1 -└─Selection_12 4433.77 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) +└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1), eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo From aef2186fc16a465b2cbf5d79b8eabc3d9cf12fd2 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 18:06:43 +0800 Subject: [PATCH 04/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- pkg/planner/core/issuetest/planner_issue_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/planner/core/issuetest/planner_issue_test.go b/pkg/planner/core/issuetest/planner_issue_test.go index 98c6d0bfd9104..ca0b80fb7504f 100644 --- a/pkg/planner/core/issuetest/planner_issue_test.go +++ b/pkg/planner/core/issuetest/planner_issue_test.go @@ -167,13 +167,13 @@ func TestIssue58476(t *testing.T) { tk.MustExec("CREATE TABLE t3 (id int PRIMARY KEY,c1 varchar(256),c2 varchar(256) GENERATED ALWAYS AS (concat(c1, c1)) VIRTUAL,KEY (id));") tk.MustExec("insert into t3(id, c1) values (50, 'c');") tk.MustQuery("SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;").Check(testkit.Rows()) - tk.MustQuery("EXPLAIN SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;"). + tk.MustQuery("explain format='brief' SELECT /*+ USE_INDEX_MERGE(`t3`)*/ id FROM `t3` WHERE c2 BETWEEN 'a' AND 'b' GROUP BY id HAVING id < 100 or id > 0;"). Check(testkit.Rows( - `Projection_7 249.75 root test.t3.id`, - `└─Selection_15 249.75 root ge(test.t3.c2, "a"), le(test.t3.c2, "b")`, - ` └─Projection_14 9990.00 root test.t3.id, test.t3.c2`, - ` └─IndexMerge_12 9990.00 root type: union`, - ` ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t3, index:id(id) range:[-inf,100), keep order:false, stats:pseudo`, - ` ├─TableRangeScan_10(Build) 3333.33 cop[tikv] table:t3 range:(0,+inf], keep order:false, stats:pseudo`, - ` └─TableRowIDScan_11(Probe) 9990.00 cop[tikv] table:t3 keep order:false, stats:pseudo`)) + `Projection 249.75 root test.t3.id`, + `└─Selection 249.75 root ge(test.t3.c2, "a"), le(test.t3.c2, "b")`, + ` └─Projection 9990.00 root test.t3.id, test.t3.c2`, + ` └─IndexMerge 9990.00 root type: union`, + ` ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t3, index:id(id) range:[-inf,100), keep order:false, stats:pseudo`, + ` ├─TableRangeScan(Build) 3333.33 cop[tikv] table:t3 range:(0,+inf], keep order:false, stats:pseudo`, + ` └─TableRowIDScan(Probe) 9990.00 cop[tikv] table:t3 keep order:false, stats:pseudo`)) } From cf29bacbd17e7838426a3cd620bfedfc6ea2f4e1 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 18:08:12 +0800 Subject: [PATCH 05/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- .../r/planner/core/casetest/pushdown/push_down.result | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result index 75d49d4c5593f..8fb6a0364cd68 100644 --- a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result +++ b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result @@ -259,11 +259,11 @@ Projection_14 6.40 root 1->Column#10, Column#9 └─Projection_15 6.40 root format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)->Column#9 └─HashAgg_16 6.40 root group by:planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, funcs:firstrow(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74)->planner__core__casetest__pushdown__push_down.t4a8656d1.col_74 └─HashJoin_19 10.00 root inner join, equal:[eq(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, Column#13)] - ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) + ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) │ └─IndexMerge_27 10.00 root type: union │ ├─Selection_25(Build) 0.00 cop[tikv] │ │ └─IndexRangeScan_24 10.00 cop[tikv] table:t4a8656d1, index:idx_39(cast(`col_73` as double array), col_74) range:[0.035131302371695955,0.035131302371695955], keep order:false, stats:pseudo │ └─TableRowIDScan_26(Probe) 10.00 cop[tikv] table:t4a8656d1 keep order:false, stats:pseudo - └─Projection_34(Probe) 10000.00 root cast(planner__core__casetest__pushdown__push_down.tld47bc815.col_1, datetime(6) BINARY)->Column#13 - └─TableReader_36 10000.00 root data:TableFullScan_35 - └─TableFullScan_35 10000.00 cop[tikv] table:tld47bc815 keep order:false, stats:pseudo + └─Projection_36(Probe) 10000.00 root cast(planner__core__casetest__pushdown__push_down.tld47bc815.col_1, datetime(6) BINARY)->Column#13 + └─TableReader_38 10000.00 root data:TableFullScan_37 + └─TableFullScan_37 10000.00 cop[tikv] table:tld47bc815 keep order:false, stats:pseudo From 905b7f2e3d96cfda88f102f7cd1f6889c0f00c23 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 18:56:21 +0800 Subject: [PATCH 06/15] planner: fix idxMergePartPlans forget to deal with RootTaskConds Signed-off-by: Weizhen Wang --- pkg/planner/core/optimizer.go | 4 +++- tests/integrationtest/r/index_merge.result | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pkg/planner/core/optimizer.go b/pkg/planner/core/optimizer.go index ff914a94a6a3e..1aa511f8b8440 100644 --- a/pkg/planner/core/optimizer.go +++ b/pkg/planner/core/optimizer.go @@ -365,7 +365,9 @@ func mergeContinuousSelections(p base.PhysicalPlan) { if !ok { break } - sel.Conditions = append(sel.Conditions, tmp.Conditions...) + if !slices.Equal(sel.Conditions, tmp.Conditions) { + sel.Conditions = append(sel.Conditions, tmp.Conditions...) + } sel.SetChild(0, tmp.Children()[0]) } } diff --git a/tests/integrationtest/r/index_merge.result b/tests/integrationtest/r/index_merge.result index 712dee3589f63..dec912a11db9f 100644 --- a/tests/integrationtest/r/index_merge.result +++ b/tests/integrationtest/r/index_merge.result @@ -238,7 +238,7 @@ insert into t1(c1, c2) values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -253,7 +253,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -268,7 +268,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -283,7 +283,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1; id estRows task access object operator info Sort_5 4800.37 root index_merge.t1.c1 -└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) +└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -303,7 +303,7 @@ select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -656,7 +656,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root index_merge.t1.c1 -└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1), eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) +└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo From 3cf5296ad784fd73203c1b9481af55bbe0ea44bd Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 19:27:14 +0800 Subject: [PATCH 07/15] update Signed-off-by: Weizhen Wang --- .../r/planner/core/casetest/pushdown/push_down.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result index 8fb6a0364cd68..4adabaa7e2adf 100644 --- a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result +++ b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result @@ -259,7 +259,7 @@ Projection_14 6.40 root 1->Column#10, Column#9 └─Projection_15 6.40 root format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)->Column#9 └─HashAgg_16 6.40 root group by:planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, funcs:firstrow(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74)->planner__core__casetest__pushdown__push_down.t4a8656d1.col_74 └─HashJoin_19 10.00 root inner join, equal:[eq(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, Column#13)] - ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) + ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) │ └─IndexMerge_27 10.00 root type: union │ ├─Selection_25(Build) 0.00 cop[tikv] │ │ └─IndexRangeScan_24 10.00 cop[tikv] table:t4a8656d1, index:idx_39(cast(`col_73` as double array), col_74) range:[0.035131302371695955,0.035131302371695955], keep order:false, stats:pseudo From 28438ba19bfab7c3bd5d508ca8200eab33594804 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 19:27:23 +0800 Subject: [PATCH 08/15] update Signed-off-by: Weizhen Wang --- pkg/expression/explain.go | 3 +++ pkg/planner/core/optimizer.go | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/expression/explain.go b/pkg/expression/explain.go index 763a2b051259a..297192286485c 100644 --- a/pkg/expression/explain.go +++ b/pkg/expression/explain.go @@ -224,6 +224,9 @@ func sortedExplainExpressionList(ctx EvalContext, exprs []Expression, normalized buffer := bytes.NewBufferString("") exprInfos := make([]string, 0, len(exprs)) for _, expr := range exprs { + if expr == nil { + continue + } if ignoreInlist { exprInfos = append(exprInfos, expr.ExplainNormalizedInfo4InList()) } else if normalized { diff --git a/pkg/planner/core/optimizer.go b/pkg/planner/core/optimizer.go index 1aa511f8b8440..5e66e0295a9d3 100644 --- a/pkg/planner/core/optimizer.go +++ b/pkg/planner/core/optimizer.go @@ -365,9 +365,8 @@ func mergeContinuousSelections(p base.PhysicalPlan) { if !ok { break } - if !slices.Equal(sel.Conditions, tmp.Conditions) { - sel.Conditions = append(sel.Conditions, tmp.Conditions...) - } + sel.Conditions = append(sel.Conditions, tmp.Conditions...) + slices.Compact(sel.Conditions) sel.SetChild(0, tmp.Children()[0]) } } From ee51997d41a7dadea49c4f5e49edfaf50405ffc9 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 19:34:13 +0800 Subject: [PATCH 09/15] update Signed-off-by: Weizhen Wang --- pkg/expression/explain.go | 3 --- pkg/planner/core/optimizer.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/expression/explain.go b/pkg/expression/explain.go index 297192286485c..763a2b051259a 100644 --- a/pkg/expression/explain.go +++ b/pkg/expression/explain.go @@ -224,9 +224,6 @@ func sortedExplainExpressionList(ctx EvalContext, exprs []Expression, normalized buffer := bytes.NewBufferString("") exprInfos := make([]string, 0, len(exprs)) for _, expr := range exprs { - if expr == nil { - continue - } if ignoreInlist { exprInfos = append(exprInfos, expr.ExplainNormalizedInfo4InList()) } else if normalized { diff --git a/pkg/planner/core/optimizer.go b/pkg/planner/core/optimizer.go index 5e66e0295a9d3..9acede3f32688 100644 --- a/pkg/planner/core/optimizer.go +++ b/pkg/planner/core/optimizer.go @@ -366,7 +366,7 @@ func mergeContinuousSelections(p base.PhysicalPlan) { break } sel.Conditions = append(sel.Conditions, tmp.Conditions...) - slices.Compact(sel.Conditions) + sel.Conditions = slices.Compact(sel.Conditions) sel.SetChild(0, tmp.Children()[0]) } } From 0950a665b94e16dcb4e7778f907c8a99cdf19514 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 20:05:54 +0800 Subject: [PATCH 10/15] update Signed-off-by: Weizhen Wang --- pkg/planner/core/optimizer.go | 1 - tests/integrationtest/r/index_merge.result | 12 ++++++------ .../r/planner/core/casetest/integration.result | 4 ++-- .../planner/core/casetest/pushdown/push_down.result | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pkg/planner/core/optimizer.go b/pkg/planner/core/optimizer.go index 9acede3f32688..ff914a94a6a3e 100644 --- a/pkg/planner/core/optimizer.go +++ b/pkg/planner/core/optimizer.go @@ -366,7 +366,6 @@ func mergeContinuousSelections(p base.PhysicalPlan) { break } sel.Conditions = append(sel.Conditions, tmp.Conditions...) - sel.Conditions = slices.Compact(sel.Conditions) sel.SetChild(0, tmp.Children()[0]) } } diff --git a/tests/integrationtest/r/index_merge.result b/tests/integrationtest/r/index_merge.result index dec912a11db9f..712dee3589f63 100644 --- a/tests/integrationtest/r/index_merge.result +++ b/tests/integrationtest/r/index_merge.result @@ -238,7 +238,7 @@ insert into t1(c1, c2) values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -253,7 +253,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -268,7 +268,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) +└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -283,7 +283,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1; id estRows task access object operator info Sort_5 4800.37 root index_merge.t1.c1 -└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) +└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -303,7 +303,7 @@ select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -656,7 +656,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root index_merge.t1.c1 -└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) +└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1), eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo diff --git a/tests/integrationtest/r/planner/core/casetest/integration.result b/tests/integrationtest/r/planner/core/casetest/integration.result index 84f5a0b9efa1b..6a96bcd3ee54b 100644 --- a/tests/integrationtest/r/planner/core/casetest/integration.result +++ b/tests/integrationtest/r/planner/core/casetest/integration.result @@ -986,7 +986,7 @@ select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and fro explain format=brief select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'ab' or c2 = '10' and char_length(left(c1, 10)) = 10; id estRows task access object operator info Projection 17.99 root 1->Column#5 -└─Selection 0.04 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) +└─Selection 0.00 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) └─IndexMerge 19.99 root type: union ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:["ab","ab"], keep order:false, stats:pseudo ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:["10","10"], keep order:false, stats:pseudo @@ -1019,7 +1019,7 @@ select /*+ use_index_merge( tt2 ) */ 1 from tt2 where tt2.c1 in (-3896405) or tt explain format=brief select /*+ use_index_merge(tt3) */ 1 from tt3 where c1 < -10 or c2 < 10 and reverse(c3) = '2'; id estRows task access object operator info Projection 5098.44 root 1->Column#5 -└─Selection 2825.66 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) +└─Selection 1440.65 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) └─IndexMerge 5542.21 root type: union ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c1(c1) range:[-inf,-10), keep order:false, stats:pseudo ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo diff --git a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result index 4adabaa7e2adf..8fb6a0364cd68 100644 --- a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result +++ b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result @@ -259,7 +259,7 @@ Projection_14 6.40 root 1->Column#10, Column#9 └─Projection_15 6.40 root format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)->Column#9 └─HashAgg_16 6.40 root group by:planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, funcs:firstrow(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74)->planner__core__casetest__pushdown__push_down.t4a8656d1.col_74 └─HashJoin_19 10.00 root inner join, equal:[eq(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, Column#13)] - ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) + ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) │ └─IndexMerge_27 10.00 root type: union │ ├─Selection_25(Build) 0.00 cop[tikv] │ │ └─IndexRangeScan_24 10.00 cop[tikv] table:t4a8656d1, index:idx_39(cast(`col_73` as double array), col_74) range:[0.035131302371695955,0.035131302371695955], keep order:false, stats:pseudo From 57c6bdd638c7fdefc44e110f241257e8de950812 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Tue, 24 Dec 2024 21:06:22 +0800 Subject: [PATCH 11/15] update Signed-off-by: Weizhen Wang --- .../r/planner/core/casetest/integration.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integrationtest/r/planner/core/casetest/integration.result b/tests/integrationtest/r/planner/core/casetest/integration.result index 6a96bcd3ee54b..34d697f7d1268 100644 --- a/tests/integrationtest/r/planner/core/casetest/integration.result +++ b/tests/integrationtest/r/planner/core/casetest/integration.result @@ -986,7 +986,7 @@ select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and fro explain format=brief select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'ab' or c2 = '10' and char_length(left(c1, 10)) = 10; id estRows task access object operator info Projection 17.99 root 1->Column#5 -└─Selection 0.00 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) +└─Selection 0.00 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))), or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) └─IndexMerge 19.99 root type: union ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:["ab","ab"], keep order:false, stats:pseudo ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:["10","10"], keep order:false, stats:pseudo @@ -1019,7 +1019,7 @@ select /*+ use_index_merge( tt2 ) */ 1 from tt2 where tt2.c1 in (-3896405) or tt explain format=brief select /*+ use_index_merge(tt3) */ 1 from tt3 where c1 < -10 or c2 < 10 and reverse(c3) = '2'; id estRows task access object operator info Projection 5098.44 root 1->Column#5 -└─Selection 1440.65 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) +└─Selection 1440.65 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))), or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) └─IndexMerge 5542.21 root type: union ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c1(c1) range:[-inf,-10), keep order:false, stats:pseudo ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo From 17676bf80d4a7f5c64c92ab3520447c9245c9a7b Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Wed, 25 Dec 2024 00:15:57 +0800 Subject: [PATCH 12/15] update Signed-off-by: Weizhen Wang --- .../r/planner/core/casetest/integration.result | 4 ++-- .../r/planner/core/casetest/pushdown/push_down.result | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integrationtest/r/planner/core/casetest/integration.result b/tests/integrationtest/r/planner/core/casetest/integration.result index 34d697f7d1268..84f5a0b9efa1b 100644 --- a/tests/integrationtest/r/planner/core/casetest/integration.result +++ b/tests/integrationtest/r/planner/core/casetest/integration.result @@ -986,7 +986,7 @@ select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and fro explain format=brief select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'ab' or c2 = '10' and char_length(left(c1, 10)) = 10; id estRows task access object operator info Projection 17.99 root 1->Column#5 -└─Selection 0.00 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))), or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) +└─Selection 0.04 root or(eq(planner__core__casetest__integration.t1.c1, "ab"), and(eq(planner__core__casetest__integration.t1.c2, "10"), eq(char_length(left(planner__core__casetest__integration.t1.c1, 10)), 10))) └─IndexMerge 19.99 root type: union ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:["ab","ab"], keep order:false, stats:pseudo ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:["10","10"], keep order:false, stats:pseudo @@ -1019,7 +1019,7 @@ select /*+ use_index_merge( tt2 ) */ 1 from tt2 where tt2.c1 in (-3896405) or tt explain format=brief select /*+ use_index_merge(tt3) */ 1 from tt3 where c1 < -10 or c2 < 10 and reverse(c3) = '2'; id estRows task access object operator info Projection 5098.44 root 1->Column#5 -└─Selection 1440.65 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))), or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) +└─Selection 2825.66 root or(lt(planner__core__casetest__integration.tt3.c1, -10), and(lt(planner__core__casetest__integration.tt3.c2, 10), eq(reverse(cast(planner__core__casetest__integration.tt3.c3, var_string(20))), "2"))) └─IndexMerge 5542.21 root type: union ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c1(c1) range:[-inf,-10), keep order:false, stats:pseudo ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo diff --git a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result index 8fb6a0364cd68..75d49d4c5593f 100644 --- a/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result +++ b/tests/integrationtest/r/planner/core/casetest/pushdown/push_down.result @@ -259,11 +259,11 @@ Projection_14 6.40 root 1->Column#10, Column#9 └─Projection_15 6.40 root format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)->Column#9 └─HashAgg_16 6.40 root group by:planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, funcs:firstrow(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74)->planner__core__casetest__pushdown__push_down.t4a8656d1.col_74 └─HashJoin_19 10.00 root inner join, equal:[eq(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, Column#13)] - ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) + ├─Selection_20(Build) 8.00 root isnull(format(cast(planner__core__casetest__pushdown__push_down.t4a8656d1.col_74, double BINARY), 1)), json_overlaps(planner__core__casetest__pushdown__push_down.t4a8656d1.col_73, cast("[0.035131302371695955]", json BINARY)) │ └─IndexMerge_27 10.00 root type: union │ ├─Selection_25(Build) 0.00 cop[tikv] │ │ └─IndexRangeScan_24 10.00 cop[tikv] table:t4a8656d1, index:idx_39(cast(`col_73` as double array), col_74) range:[0.035131302371695955,0.035131302371695955], keep order:false, stats:pseudo │ └─TableRowIDScan_26(Probe) 10.00 cop[tikv] table:t4a8656d1 keep order:false, stats:pseudo - └─Projection_36(Probe) 10000.00 root cast(planner__core__casetest__pushdown__push_down.tld47bc815.col_1, datetime(6) BINARY)->Column#13 - └─TableReader_38 10000.00 root data:TableFullScan_37 - └─TableFullScan_37 10000.00 cop[tikv] table:tld47bc815 keep order:false, stats:pseudo + └─Projection_34(Probe) 10000.00 root cast(planner__core__casetest__pushdown__push_down.tld47bc815.col_1, datetime(6) BINARY)->Column#13 + └─TableReader_36 10000.00 root data:TableFullScan_35 + └─TableFullScan_35 10000.00 cop[tikv] table:tld47bc815 keep order:false, stats:pseudo From 7fb206f00fae428d81103d8a89a58b565cd53158 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Wed, 25 Dec 2024 00:18:04 +0800 Subject: [PATCH 13/15] update Signed-off-by: Weizhen Wang --- tests/integrationtest/r/index_merge.result | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integrationtest/r/index_merge.result b/tests/integrationtest/r/index_merge.result index 712dee3589f63..1a842a0ef04ff 100644 --- a/tests/integrationtest/r/index_merge.result +++ b/tests/integrationtest/r/index_merge.result @@ -238,7 +238,7 @@ insert into t1(c1, c2) values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_12 2250.55 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -253,7 +253,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) +└─Selection_12 2825.66 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -268,7 +268,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1; id estRows task access object operator info Sort_5 5098.44 root index_merge.t1.c1 -└─Selection_13 1440.65 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) +└─Selection_12 2825.66 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY)))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -283,7 +283,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1; id estRows task access object operator info Sort_5 4800.37 root index_merge.t1.c1 -└─Selection_13 1277.12 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) +└─Selection_12 2660.47 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3)) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -303,7 +303,7 @@ select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root index_merge.t1.c1 -└─Selection_13 913.89 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) +└─Selection_12 2250.55 root or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10))) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo @@ -656,7 +656,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root index_merge.t1.c1 -└─Selection_13 3547.02 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1), eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) +└─Selection_12 4433.77 root eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1) └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo From 284196a6b95e286d3ccdf86a70767ff43d4102cb Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Wed, 25 Dec 2024 00:18:21 +0800 Subject: [PATCH 14/15] update Signed-off-by: Weizhen Wang --- pkg/planner/core/task_base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/planner/core/task_base.go b/pkg/planner/core/task_base.go index 02b8b891cb82a..d6b2f2f854930 100644 --- a/pkg/planner/core/task_base.go +++ b/pkg/planner/core/task_base.go @@ -377,8 +377,8 @@ func (t *CopTask) convertToRootTaskImpl(ctx base.PlanContext) *RootTask { proj.SetSchema(schema) proj.SetChildren(p) newTask.SetPlan(proj) + t.handleRootTaskConds(ctx, newTask) } - t.handleRootTaskConds(ctx, newTask) return newTask } if t.indexPlan != nil && t.tablePlan != nil { From 162436012cf5a91030037c27303be101e6ca8b96 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Wed, 25 Dec 2024 00:31:19 +0800 Subject: [PATCH 15/15] update Signed-off-by: Weizhen Wang --- pkg/planner/core/task_base.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/planner/core/task_base.go b/pkg/planner/core/task_base.go index d6b2f2f854930..6b32b7b67a034 100644 --- a/pkg/planner/core/task_base.go +++ b/pkg/planner/core/task_base.go @@ -370,15 +370,14 @@ func (t *CopTask) convertToRootTaskImpl(ctx base.PlanContext) *RootTask { p.PlanPartInfo = t.physPlanPartInfo setTableScanToTableRowIDScan(p.tablePlan) newTask.SetPlan(p) - t.handleRootTaskConds(ctx, newTask) if t.needExtraProj { schema := t.originSchema proj := PhysicalProjection{Exprs: expression.Column2Exprs(schema.Columns)}.Init(ctx, p.StatsInfo(), t.idxMergePartPlans[0].QueryBlockOffset(), nil) proj.SetSchema(schema) proj.SetChildren(p) newTask.SetPlan(proj) - t.handleRootTaskConds(ctx, newTask) } + t.handleRootTaskConds(ctx, newTask) return newTask } if t.indexPlan != nil && t.tablePlan != nil {