From 7e19095f49ff3134d18506af4c7729b090ef6d0f Mon Sep 17 00:00:00 2001 From: Elsa <111482174+elsa0520@users.noreply.github.com> Date: Fri, 24 May 2024 12:29:48 +0800 Subject: [PATCH] This is an automated cherry-pick of #53525 Signed-off-by: ti-chi-bot --- .../casetest/physicalplantest/BUILD.bazel | 36 + .../testdata/plan_suite_in.json | 623 +++ .../testdata/plan_suite_out.json | 3788 +++++++++++++++++ planner/core/casetest/physical_plan_test.go | 27 + planner/core/rule_build_key_info.go | 6 +- 5 files changed, 4479 insertions(+), 1 deletion(-) create mode 100644 pkg/planner/core/casetest/physicalplantest/BUILD.bazel create mode 100644 pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_in.json create mode 100644 pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json diff --git a/pkg/planner/core/casetest/physicalplantest/BUILD.bazel b/pkg/planner/core/casetest/physicalplantest/BUILD.bazel new file mode 100644 index 0000000000000..54f2d86948766 --- /dev/null +++ b/pkg/planner/core/casetest/physicalplantest/BUILD.bazel @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "physicalplantest_test", + timeout = "short", + srcs = [ + "main_test.go", + "physical_plan_test.go", + ], + data = glob(["testdata/**"]), + flaky = True, + race = "on", + shard_count = 33, + deps = [ + "//pkg/config", + "//pkg/domain", + "//pkg/executor", + "//pkg/infoschema", + "//pkg/parser", + "//pkg/parser/ast", + "//pkg/parser/model", + "//pkg/planner", + "//pkg/planner/core", + "//pkg/planner/util/coretestsdk", + "//pkg/testkit", + "//pkg/testkit/external", + "//pkg/testkit/testdata", + "//pkg/testkit/testmain", + "//pkg/testkit/testsetup", + "//pkg/util/context", + "//pkg/util/hint", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//require", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_in.json b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_in.json new file mode 100644 index 0000000000000..e036e59219ebb --- /dev/null +++ b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_in.json @@ -0,0 +1,623 @@ +[ + { + "name": "TestMPPHints", + "cases": [ + "select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // READ_FROM_STORAGE hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // Join hint + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // AGG hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), hash_agg() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), stream_agg() */ a, sum(b) from t group by a, c", + + // Index hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), use_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), ignore_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), force_index(t, idx_b) */ a, sum(b) from t where b < 2 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), index_merge(t, idx_b, idx_a) */ a, sum(b) from t where b < 2 or a > 2 group by a, c", + + // Join Order hint + "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), straight_join() */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), leading(t3, t1) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), straight_join() */ * from t t2, t t1, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), leading(t2, t3) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + + // View Hint + "select /*+ qb_name(qb, v), MPP_1PHASE_AGG(@qb) */ * from v", + "select /*+ qb_name(qb, v), MPP_2PHASE_AGG(@qb) */ * from v", + "select /*+ qb_name(qb, v1), shuffle_join(t1@qb, t2@qb) */ * from v1", + "select /*+ qb_name(qb, v1), broadcast_join(t1@qb, t2@qb) */ * from v1", + + // Subquery hint + "SELECT /*+ shuffle_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t t1 WHERE t1.b = t.b);", + "SELECT /*+ broadcast_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t t1 WHERE t1.b = t.b);", + "select * from t t1 where t1.a < (select /*+ MPP_1PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "select * from t t1 where t1.a < (select /*+ MPP_2PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + + // CTE + "WITH CTE AS (SELECT /*+ MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + + + // Test MPP Hints with hash_join_build and hash_join_probe hints + // TestMPPOuterJoinBuildSideForBroadcastJoin + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + + // TestMPPOuterJoinBuildSideForShuffleJoinWithFixedBuildSide + "set @@session.tidb_opt_mpp_outer_join_fixed_build_side = 1", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + + // TestMPPOuterJoinBuildSideForShuffleJoin + "set @@session.tidb_opt_mpp_outer_join_fixed_build_side = 0", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + + // Semi Join + "select /*+ shuffle_join(t1, t2@sel_2), hash_join_build(t2@sel_2) */ a from t t1 where t1.a>1 or t1.a in (select a from t t2);", + "select /*+ shuffle_join(t1, t2@sel_2), hash_join_build(t1) */ a from t t1 where t1.a>1 or t1.a not in (select a from t t2);", + "select /*+ shuffle_join(t1, t2@sel_2), hash_join_probe(t2@sel_2) */ a from t t1 where t1.a>1 or t1.a in (select a from t t2);", + "select /*+ shuffle_join(t1, t2@sel_2), hash_join_probe(t1) */ a from t t1 where t1.a>1 or t1.a not in (select a from t t2);" + ] + }, + { + "name": "TestMPPHintsScope", + "cases": [ + "set @@session.tidb_allow_mpp=true", + "explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "set @@session.tidb_enforce_mpp=true", + "explain select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "set @@session.tidb_enforce_mpp=false", + "explain select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ read_from_storage(tiflash[t1, t2]) hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ read_from_storage(tiflash[t1, t2]) merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "set @@session.tidb_allow_mpp=false", + "explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a" + ] + }, + { + "name": "TestMPPBCJModel", + "cases": [ + "set @@session.tidb_allow_mpp=true", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "explain select * from t t1, t t2 where t1.a=t2.a", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "explain select * from t t1, t t2 where t1.a=t2.a" + ] + }, + { + "name": "TestMPPPreferBCJ", + "cases": [ + "explain select * from t1, t2 where t1.a=t2.b", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "explain select * from t1, t2 where t1.a=t2.b", + "insert into t2 values (9); analyze table t2;", + "explain select * from t1, t2 where t1.a=t2.b" + ] + }, + { + "name": "TestMPPBCJModelOneTiFlash", + "cases": [ + "set @@session.tidb_allow_mpp=true", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "explain select * from t t1, t t2 where t1.a=t2.a", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "explain select * from t t1, t t2 where t1.a=t2.a" + ] + }, + { + "name": "TestMPPRightSemiJoin", + "cases": [ + "set @@session.tidb_allow_mpp=true", + "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "set @@session.tidb_broadcast_join_threshold_size=0", + "set @@session.tidb_broadcast_join_threshold_count=0", + "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)" + ] + }, + { + "name": "TestMPPRightOuterJoin", + "cases": [ + "set @@session.tidb_allow_mpp=true", + "explain select * from t1 right join t2 on t1.a=t2.b and t1.c < t2.d", + "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "set @@session.tidb_broadcast_join_threshold_size=0", + "set @@session.tidb_broadcast_join_threshold_count=0", + "explain select * from t1 right join t2 on t1.a=t2.b and t1.c < t2.d" + ] + }, + { + "name": "TestIssue37520", + "cases": [ + "select /*+ inl_join(t1@sel_2) */ a, (select b from t1 where t1.a = t2.b) from t2;", + "select /*+ inl_join(t2) */ a, (select b from t1 where t1.a = t2.b) from t2;", + "select /*+ inl_join(t2@sel_2) */ * from t1 where exists ( select /*+ semi_join_rewrite() */ * from t2 where t1.a = t2.a);", + "select /*+ inl_join(t1) */ * from t1 where exists ( select /*+ semi_join_rewrite() */ * from t2 where t1.a = t2.a);" + ] + }, + { + "name": "TestHintScope", + "cases": [ + // join hints + "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ MERGE_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(test.t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b", + // aggregation hints + "select /*+ STREAM_AGG() */ s, count(s) from (select /*+ HASH_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "select /*+ HASH_AGG() */ s, count(s) from (select /*+ STREAM_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "select /*+ HASH_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "select /*+ STREAM_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s" + ] + }, + { + "name": "TestIndexHint", + "cases": [ + // simple case + "select /*+ USE_INDEX(t, c_d_e) */ * from t", + "select /*+ USE_INDEX(test.t, c_d_e) */ * from t", + "select /*+ IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "select /*+ IGNORE_INDEX(test.t, c_d_e) */ c from t order by c", + "select /*+ FORCE_INDEX(t, c_d_e) */ * from t", + "select /*+ FORCE_INDEX(test.t, c_d_e) */ * from t", + "select /*+ USE_INDEX(t, c_d_e) */ * from t t1", + "select /*+ IGNORE_INDEX(t, c_d_e) */ t1.c from t t1 order by t1.c", + "select /*+ FORCE_INDEX(t, c_d_e) */ * from t t1", + "select /*+ USE_INDEX(t1, c_d_e) */ * from t t1", + "select /*+ IGNORE_INDEX(t1, c_d_e) */ t1.c from t t1 order by t1.c", + "select /*+ FORCE_INDEX(t1, c_d_e) */ * from t t1", + "select /*+ USE_INDEX(t1, c_d_e), USE_INDEX(t2, f) */ * from t t1, t t2 where t1.a = t2.b", + "select /*+ IGNORE_INDEX(t1, c_d_e), IGNORE_INDEX(t2, f), HASH_JOIN(t1) */ * from t t1, t t2 where t1.a = t2.b", + "select /*+ FORCE_INDEX(t1, c_d_e), FORCE_INDEX(t2, f) */ * from t t1, t t2 where t1.a = t2.b", + // test multiple indexes + "select /*+ USE_INDEX(t, c_d_e, f, g) */ * from t order by f", + "select /*+ FORCE_INDEX(t, c_d_e, f, g) */ * from t order by f", + // use TablePath when the hint only contains table. + "select /*+ USE_INDEX(t) */ f from t where f > 10", + "select /*+ FORCE_INDEX(t) */ f from t where f > 10", + // there will be a warning instead of error when index not exist + "select /*+ USE_INDEX(t, no_such_index) */ * from t", + "select /*+ IGNORE_INDEX(t, no_such_index) */ * from t", + "select /*+ FORCE_INDEX(t, no_such_index) */ * from t", + // use both use_index and ignore_index, same as index hints in sql. + "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, f) */ c from t order by c", + "select /*+ USE_INDEX(t, f), IGNORE_INDEX(t, f) */ c from t order by c", + "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "select /*+ USE_INDEX(t, c_d_e, f), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + // use both force_index and ignore_index, same as index hints in sql. + "select /*+ FORCE_INDEX(t, c_d_e), IGNORE_INDEX(t, f) */ c from t order by c", + "select /*+ FORCE_INDEX(t, f), IGNORE_INDEX(t, f) */ c from t order by c", + "select /*+ FORCE_INDEX(t, c_d_e), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "select /*+ FORCE_INDEX(t, c_d_e, f), IGNORE_INDEX(t, c_d_e) */ c from t order by c" + ] + }, + { + "name": "TestIndexMergeHint", + "cases": [ + "select /*+ USE_INDEX_MERGE(t, c_d_e, f_g) */ * from t where c < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(t, primary, f_g) */ * from t where a < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(t1, c_d_e, f_g) */ * from t where c < 1 or f > 2", + "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(t) USE_INDEX_MERGE(t) */ * from t where c < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(db2.t) */ * from t where c < 1 or f > 2", + "select /*+ USE_INDEX_MERGE(db2.t, c_d_e, f_g) */ * from t where c < 1 or f > 2" + ] + }, + { + "name": "TestRefine", + "cases": [ + "select a from t where c is not null", + "select a from t where c >= 4", + "select a from t where c <= 4", + "select a from t where c = 4 and d = 5 and e = 6", + "select a from t where d = 4 and c = 5", + "select a from t where c = 4 and e < 5", + "select a from t where c = 4 and d <= 5 and d > 3", + "select a from t where d <= 5 and d > 3", + "select a from t where c between 1 and 2", + "select a from t where c not between 1 and 2", + "select a from t where c <= 5 and c >= 3 and d = 1", + "select a from t where c = 1 or c = 2 or c = 3", + "select b from t where c = 1 or c = 2 or c = 3 or c = 4 or c = 5", + "select a from t where c = 5", + "select a from t where c = 5 and b = 1", + "select a from t where not a", + "select a from t where c in (1)", + "select a from t where c in ('1')", + "select a from t where c = 1.0", + "select a from t where c in (1) and d > 3", + "select a from t where c in (1, 2, 3) and (d > 3 and d < 4 or d > 5 and d < 6)", + "select a from t where c in (1, 2, 3) and (d > 2 and d < 4 or d > 5 and d < 7)", + "select a from t where c in (1, 2, 3)", + "select a from t where c in (1, 2, 3) and d in (1,2) and e = 1", + "select a from t where d in (1, 2, 3)", + "select a from t where c not in (1)", + "select a from t use index(c_d_e) where c != 1", + // test like + "select a from t where c_str like ''", + "select a from t where c_str like 'abc'", + "select a from t where c_str not like 'abc'", + "select a from t where not (c_str like 'abc' or c_str like 'abd')", + "select a from t where c_str like '_abc'", + "select a from t where c_str like 'abc%'", + "select a from t where c_str like 'abc_'", + "select a from t where c_str like 'abc%af'", + "select a from t where c_str like 'abc\\_' escape ''", + "select a from t where c_str like 'abc\\_'", + "select a from t where c_str like 'abc\\\\_'", + "select a from t where c_str like 'abc\\_%'", + "select a from t where c_str like 'abc=_%' escape '='", + "select a from t where c_str like 'abc\\__'", + // Check that 123 is converted to string '123'. index can be used. + "select a from t where c_str like 123", + "select a from t where c = 1.9 and d > 3", + "select a from t where c < 1.1", + "select a from t where c <= 1.9", + "select a from t where c >= 1.1", + "select a from t where c > 1.9", + "select a from t where c = 123456789098765432101234", + "select a from t where c = 'hanfei'" + ] + }, + { + "name": "TestAggEliminator", + "cases": [ + // Max to Limit + Sort-Desc. + "select max(a) from t;", + // Min to Limit + Sort. + "select min(a) from t;", + // Min to Limit + Sort, and isnull() should be added. + "select min(c_str) from t;", + // Do nothing to max + firstrow. + "select max(a), b from t;", + // If max/min contains scalar function, we can still do transformation. + "select max(a+1) from t;", + // Min + Max to Limit + Sort + Join. + "select max(a), min(a) from t;", + // Min + Max with range condition. + "select max(a), min(a) from t where a > 10", + // Min + Max with unified index range condition. + "select max(d), min(d) from t where c = 1 and d > 10", + // Min + Max with multiple columns + "select max(a), max(c), min(f) from t", + // Do nothing if any column has no index. + "select max(a), max(b) from t", + // Do nothing if any column has a non-range condition. + "select max(a), max(c) from t where c > 10", + // Do nothing if the condition cannot be pushed down to range. + "select max(a), min(a) from t where a * 3 + 10 < 100", + // Do nothing to max with groupby. + "select max(a) from t group by b;", + // If inner is not a data source, we can still do transformation. + "select max(a) from (select t1.a from t t1 join t t2 on t1.a=t2.a) t" + ] + }, + { + "name": "TestRuleColumnPruningLogicalApply", + "cases": [ + "SELECT COUNT(*) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "SELECT COUNT(a) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "SELECT COUNT(t) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "SELECT COUNT(a) FROM t t1 WHERE t1.a IN (SELECT t2.a FROM t t2, t t3 WHERE t2.b = t3.b)", + "SELECT a FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "SELECT a FROM t WHERE b IN (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a)", + "SELECT a FROM t WHERE EXISTS (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t2.b=t.b)", + "SELECT a FROM t WHERE NOT EXISTS (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t2.b=t.b)", + "SELECT a FROM t WHERE b IN (SELECT b FROM t WHERE b = 1 AND a IN (SELECT a FROM t WHERE a > 0))", + "SELECT a FROM t WHERE b IN (SELECT b FROM t WHERE b = 1 AND a IN (SELECT t2.a FROM (SELECT t1.a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t2))" + ] + }, + { + "name": "TestUnmatchedTableInHint", + "cases": [ + "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "SELECT /*+ TIDB_HJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "SELECT /*+ TIDB_INLJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "SELECT /*+ TIDB_SMJ(t1, t2) */ * from t t1, t t2 where t1.a = t2.a", + "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a" + ] + }, + { + "name": "TestJoinHints", + "cases": [ + "select /*+ TIDB_INLJ(t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", + "select /*+ TIDB_INLJ(test.t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", + "select /*+ TIDB_INLJ(t1) */ t1.b, t2.a from t t1, t t2 where t1.b = t2.a;", + "select /*+ TIDB_INLJ(t2) */ t1.b, t2.a from t2 t1, t2 t2 where t1.b=t2.b and t2.c=-1;" + ] + }, + { + "name": "TestAggregationHints", + "cases": [ + // without Aggregation hints + { + "SQL": "select count(*) from t t1, t t2 where t1.a = t2.b" + }, + { + "SQL": "select count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a" + }, + // with Aggregation hints + { + "SQL": "select /*+ HASH_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b" + }, + { + "SQL": "select /*+ STREAM_AGG() */ count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a" + }, + // test conflict warning + { + "SQL": "select /*+ HASH_AGG() STREAM_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b" + }, + { + "SQL": "select /*+ STREAM_AGG() */ distinct a from t" + }, + // additional test + { + "SQL": "select /*+ HASH_AGG() */ t1.a from t t1 where t1.a < any(select t2.b from t t2)" + }, + { + "SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a != any(select t2.b from t t2)" + }, + { + "SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a = all(select t2.b from t t2)" + }, + { + "SQL": "select /*+ STREAM_AGG() */ sum(t1.a) from t t1 join t t2 on t1.b = t2.b group by t1.b", + "AggPushDown": true + }, + { + "SQL": "select /*+ STREAM_AGG() */ e, sum(b) from t group by e" + } + ] + }, + { + "name": "TestQueryBlockHint", + "cases": [ + "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@sel_2 t3) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@qb t3) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "select /*+ HASH_AGG(@sel_1), STREAM_AGG(@sel_2) */ count(*) from t t1 where t1.a < (select count(*) from t t2 where t1.a > t2.a)", + "select /*+ STREAM_AGG(@sel_1), HASH_AGG(@qb) */ count(*) from t t1 where t1.a < (select /*+ QB_NAME(qb) */ count(*) from t t2 where t1.a > t2.a)", + "select /*+ HASH_AGG(@sel_2) */ a, (select count(*) from t t1 where t1.b > t.a) from t where b > (select b from t t2 where t2.b = t.a limit 1)", + "select /*+ HASH_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t1) */ t1.b, t2.a, t2.aa from t t1, (select t1.a as a, t2.a as aa from t t1, t t2) t2 where t1.a = t2.aa;", + "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b" + ] + }, + { + "name": "TestSemiJoinToInner", + "cases": [ + "select t1.a, (select count(t2.a) from t t2 where t2.g in (select t3.d from t t3 where t3.c = t1.a)) as agg_col from t t1;" + ] + }, + { + "name": "TestIndexJoinHint", + "cases": [ + "select /*+ INL_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "select /*+ INL_HASH_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "select /*+ INL_MERGE_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + // Issue 15484 + "select /*+ inl_merge_join(t2) */ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g", + "select /*+inl_merge_join(t2)*/ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g order by t1.a" + ] + }, + { + "name": "TestAggToCopHint", + "cases": [ + "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ sum(a) from ta group by a", + "select /*+ AGG_TO_COP(), USE_INDEX(t) */ sum(b) from ta group by b", + "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ distinct a from ta group by a", + "select /*+ AGG_TO_COP(), HASH_AGG(), HASH_JOIN(t1), USE_INDEX(t1), USE_INDEX(t2) */ sum(t1.a) from ta t1, ta t2 where t1.a = t2.b group by t1.a" + ] + }, + { + "name": "TestGroupConcatOrderby", + "cases": [ + "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from test;", + "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from ptest;", + "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from test;", + "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from ptest;" + ] + }, + { + "name": "TestInlineProjection", + "cases":[ + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1, t2 where t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 left outer join t2 on t1.a = t2.a;", + "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 right outer join t2 on t1.a = t2.a;", + "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a in (select t2.a from t2) from t1) x;", + "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a not in (select t2.a from t2) from t1) x;", + "select /*+ INL_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ INL_HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ INL_MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "select /*+ MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;" + ] + }, + { + "name": "TestHintFromDiffDatabase", + "cases": [ + "select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a" + ] + }, + { + "name": "TestMPPSinglePartitionType", + "cases": [ + "select * from employee where deptid>1", + "select deptid+5, empid*10 from employee where deptid>1", + // test normal aggregation, MPP2Phase. + "select count(*) from employee group by deptid+1", + // test normal aggregation, MPPScalar. + "select count(distinct deptid) a from employee", + // test normal join, Broadcast. + "select * from employee join employee e1 using(deptid)", + // test redundant collect exchange can be eliminated. + "select count(distinct a) from (select count(distinct deptid) a from employee) x", + // test mppScalar agg below mpp2Phase agg. + "select count(a) from (select count(distinct deptid) a, count(distinct empid) b from employee) x group by b+1", + // test mppScalar agg below mpp1Phase agg, TODO: add hint to enforce + // test mppScalar agg below mppTiDB agg, TODO: add hint to enforce + "select count(a) from (select count(distinct deptid) a, count(distinct empid) b from employee) x group by b", + // test mppScalar agg below join + "select * from employee join (select count(distinct deptid) a, count(distinct empid) b from employee) e1", + "select * from employee e1 join (select count(distinct deptid) a from employee) e2 on e1.deptid = e2.a", + "select * from (select count(distinct deptid) a from employee) e1 join employee e2 on e1.a = e2.deptid", + "select * from (select count(distinct deptid) a from employee) e1 join (select count(distinct deptid) b from employee) e2 on e1.a=e2.b", + // test mpp2Phase agg below join + "select * from employee e1 join employee e2 on e1.deptid = e2.deptid", + "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join employee e2 on e1.d = e2.deptid", + "select * from employee e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.deptid = e2.d", + "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.d = e2.d", + // non-broadcast join + "set tidb_broadcast_join_threshold_count=1", + "set tidb_broadcast_join_threshold_size=1", + "select * from (select count(distinct deptid) a from employee) e1 join employee e2 on e1.a = e2.deptid", + "select * from (select count(distinct deptid) a from employee) e1 join (select count(distinct deptid) b from employee) e2 on e1.a=e2.b", + "select * from employee e1 join employee e2 on e1.deptid = e2.deptid", + "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join employee e2 on e1.d = e2.deptid", + "select * from employee e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.deptid = e2.d", + "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.d = e2.d" + ] + }, + { + "name": "TestSemiJoinRewriteHints", + "cases": [ + "select /*+ SEMI_JOIN_REWRITE() */ * from t", + "select * from t where a > (select /*+ SEMI_JOIN_REWRITE() */ min(b) from t t1 where t1.c = t.c)", + "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 where t1.a=t.a)", + "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ t.b from t t1 where t1.a=t.a)", + "select exists(select /*+ SEMI_JOIN_REWRITE() */ * from t t1 where t1.a=t.a) from t", + "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 where t1.a > t.a)" + ] + }, + { + "name": "TestHJBuildAndProbeHint4DynamicPartitionTable", + "cases": [ + "select /*+ hash_join_build(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_probe(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_build(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_probe(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b" + ] + }, + { + "name": "TestHJBuildAndProbeHint4TiFlash", + "cases": [ + "select /*+ hash_join_build(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_probe(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_build(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "select /*+ hash_join_probe(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b" + ] + }, + { + "name": "TestCountStarForTiFlash", + "cases": [ + "select count(*) from t", + "select count(1), count(3.1415), count(0), count(null) from t -- every count but count(null) can be rewritten", + "select count(*) from t where a=1", + "select count(*) from t_pick_row_id", + "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- test recursive", + "select * from t outTable where outTable.a > (select count(*) from t inn where inn.a = outTable.b) -- shouldn't be rewritten for correlated sub query", + "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten when join under agg", + "select count(distinct 1) from t -- shouldn't be rewritten", + "select count(1), count(a), count(b) from t -- keep count(1)", + "select a, count(*) from t group by a -- shouldn't be rewritten", + "select sum(a) from t -- sum shouldn't be rewritten" + ] + }, + { + "name": "TestHashAggPushdownToTiFlashCompute", + "cases": [ + "select /*+ agg_to_cop() hash_agg() */ avg( distinct tbl_15.col_96 ) as r0 , min( tbl_15.col_92 ) as r1 , sum( distinct tbl_15.col_91 ) as r2 , max( tbl_15.col_92 ) as r3 from tbl_15 where tbl_15.col_94 != '2033-01-09' and tbl_15.col_93 > 7623.679908049186 order by r0,r1,r2,r3 limit 79 ;", + "select /*+ agg_to_cop() hash_agg() */ count(1) from tbl_15 ;", + "select /*+ agg_to_cop() stream_agg() */ avg( tbl_16.col_100 ) as r0 from tbl_16 where tbl_16.col_100 in ( 10672141 ) or tbl_16.col_104 in ( 'yfEG1t!*b' ,'C1*bqx_qyO' ,'vQ^yUpKHr&j#~' ) group by tbl_16.col_100 order by r0 limit 20 ;" + ] + }, + { + "name": "TestIssues49377Plan", + "cases": [ + "select 1,1,1 union all ((select * from employee where dept_id = 1) union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 );", + "select 1,1,1 union all ((select * from employee where dept_id = 1) union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 limit 1);", + "select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id) union all ( select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id ) limit 1);", + "select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id) union all ( select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 limit 1);" + ] + }, + { + "name": "TestPointgetIndexChoosen", + "cases": [ + "select * from t where b=1 and c='1';", + "select * from t where b=1 and c='1' and d='1';", + "select * from t where b in (1,2,3) and c in ('1');" + ] + }, + { + "name": "TestAlwaysTruePredicateWithSubquery", + "cases" : [ + "SHOW ERRORS WHERE TRUE = ALL ( SELECT TRUE GROUP BY 1 LIMIT 1 ) IS NULL IS NOT NULL;", + "explain select * from t WHERE TRUE = ALL ( SELECT TRUE GROUP BY 1 LIMIT 1 ) IS NULL IS NOT NULL;", + "explain select * from t WHERE TRUE = ALL ( SELECT TRUE from t GROUP BY 1 LIMIT 1 ) is null is not null;" + ] + } +] diff --git a/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json new file mode 100644 index 0000000000000..ed7a34e1757b6 --- /dev/null +++ b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json @@ -0,0 +1,3788 @@ +[ + { + "Name": "TestMPPHints", + "Cases": [ + { + "SQL": "select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a->Column#9, test.t.a->Column#10, test.t.c->Column#11", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a->Column#13, test.t.c->Column#14", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#8, Column#9, funcs:sum(Column#6)->Column#5, funcs:firstrow(Column#7)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#6, test.t.a->Column#7, test.t.a->Column#8, test.t.c->Column#9", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#8)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#11, Column#12, funcs:sum(Column#10)->Column#8", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#10, test.t.a->Column#11, test.t.c->Column#12", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The MPP join hints are in conflict, and you can only specify join method hints that are currently supported by MPP mode now" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The MPP join hints are in conflict, and you can only specify join method hints that are currently supported by MPP mode now" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The MPP join hints are in conflict, and you can only specify join method hints that are currently supported by MPP mode now" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The MPP join hints are in conflict, and you can only specify join method hints that are currently supported by MPP mode now" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), hash_agg() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#8, Column#9, funcs:sum(Column#6)->Column#5, funcs:firstrow(Column#7)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#6, test.t.a->Column#7, test.t.a->Column#8, test.t.c->Column#9", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), stream_agg() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#9, funcs:sum(Column#8)->Column#6", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a->Column#9, test.t.c->Column#10", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), use_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "Plan": [ + "Projection 2666.67 root test.t.a, Column#5", + "└─HashAgg 2666.67 root group by:test.t.a, test.t.c, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─IndexLookUp 2666.67 root ", + " ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + " └─HashAgg(Probe) 2666.67 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#7", + " └─TableRowIDScan 3333.33 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{} 1:{} 2:{}])", + "[planner:1815]The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), ignore_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "Plan": [ + "TableReader 2666.67 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 2666.67 mpp[tiflash] test.t.a, Column#5", + " └─Projection 2666.67 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 2666.67 mpp[tiflash] group by:Column#8, Column#9, funcs:sum(Column#6)->Column#5, funcs:firstrow(Column#7)->test.t.a", + " └─Projection 3333.33 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#6, test.t.a->Column#7, test.t.a->Column#8, test.t.c->Column#9", + " └─ExchangeReceiver 3333.33 mpp[tiflash] ", + " └─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─Selection 3333.33 mpp[tiflash] gt(test.t.a, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), force_index(t, idx_b) */ a, sum(b) from t where b < 2 group by a, c", + "Plan": [ + "Projection 2658.67 root test.t.a, Column#5", + "└─HashAgg 2658.67 root group by:test.t.a, test.t.c, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─IndexLookUp 2658.67 root ", + " ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + " └─HashAgg(Probe) 2658.67 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#7", + " └─TableRowIDScan 3323.33 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{} 1:{} 2:{}])", + "[planner:1815]The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), index_merge(t, idx_b, idx_a) */ a, sum(b) from t where b < 2 or a > 2 group by a, c", + "Plan": [ + "TableReader 4439.11 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 4439.11 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 4439.11 mpp[tiflash] test.t.a, Column#5", + " └─Projection 4439.11 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 4439.11 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#14)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 4439.11 mpp[tiflash] ", + " └─ExchangeSender 4439.11 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 4439.11 mpp[tiflash] group by:Column#17, Column#18, funcs:sum(Column#16)->Column#14", + " └─Projection 5548.89 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#16, test.t.a->Column#17, test.t.c->Column#18", + " └─Selection 5548.89 mpp[tiflash] or(lt(test.t.b, 2), gt(test.t.a, 2))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[parser:8061]Optimizer hint index_merge is not supported by TiDB and is ignored" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), straight_join() */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", + " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), leading(t3, t1) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 124625374.88 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 124625374.88 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 124625374.88 mpp[tiflash] test.t.a, test.t.b, test.t.c, test.t.a, test.t.b, test.t.c, test.t.a, test.t.b, test.t.c", + " └─HashJoin 124625374.88 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a) eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.b, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 99800100.00 mpp[tiflash] ", + " └─ExchangeSender 99800100.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.b, collate: binary]", + " └─HashJoin 99800100.00 mpp[tiflash] CARTESIAN inner join", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), straight_join() */ * from t t2, t t1, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 pushed down filter:empty, keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), leading(t2, t3) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 15593.77 mpp[tiflash] test.t.a, test.t.b, test.t.c, test.t.a, test.t.b, test.t.c, test.t.a, test.t.b, test.t.c", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t3 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v), MPP_1PHASE_AGG(@qb) */ * from v", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a->Column#9, test.t.a->Column#10, test.t.c->Column#11", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v), MPP_2PHASE_AGG(@qb) */ * from v", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a->Column#13, test.t.c->Column#14", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v1), shuffle_join(t1@qb, t2@qb) */ * from v1", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12487.50 mpp[tiflash] test.t.a", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v1), broadcast_join(t1@qb, t2@qb) */ * from v1", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12487.50 mpp[tiflash] test.t.a", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "SELECT /*+ shuffle_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t t1 WHERE t1.b = t.b);", + "Plan": [ + "TableReader 9990.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─Projection(Build) 7992.00 mpp[tiflash] test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "SELECT /*+ broadcast_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t t1 WHERE t1.b = t.b);", + "Plan": [ + "TableReader 9990.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 7992.00 mpp[tiflash] test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select * from t t1 where t1.a < (select /*+ MPP_1PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "Plan": [ + "TableReader 9990.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)], other cond:lt(cast(test.t.a, decimal(10,0) BINARY), Column#9)", + " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 7992.00 mpp[tiflash] Column#9, test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#26, funcs:sum(Column#24)->Column#9, funcs:firstrow(Column#25)->test.t.b", + " │ └─Projection 9990.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#24, test.t.b->Column#25, test.t.b->Column#26", + " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select * from t t1 where t1.a < (select /*+ MPP_2PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "Plan": [ + "TableReader 9990.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)], other cond:lt(cast(test.t.a, decimal(10,0) BINARY), Column#9)", + " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 7992.00 mpp[tiflash] Column#9, test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, funcs:sum(Column#13)->Column#9, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#29, funcs:sum(Column#28)->Column#13", + " │ └─Projection 9990.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#28, test.t.b->Column#29", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 3403.09 root group by:Column#10, Column#11, funcs:firstrow(Column#10)->Column#10, funcs:firstrow(Column#11)->Column#11", + "└─Union 3403.09 root ", + " ├─Selection 1701.55 root lt(Column#6, 18)", + " │ └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + " └─Selection 1701.55 root gt(test.t.b, 1)", + " └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + "CTE_0 2126.93 root Non-Recursive CTE", + "└─TableReader(Seed Part) 2126.93 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 2126.93 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 2126.93 mpp[tiflash] or(lt(Column#5, 18), gt(test.t.b, 1))", + " └─Projection 2658.67 mpp[tiflash] Column#5, test.t.b", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#5, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 3323.33 mpp[tiflash] ", + " └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 3403.09 root group by:Column#10, Column#11, funcs:firstrow(Column#10)->Column#10, funcs:firstrow(Column#11)->Column#11", + "└─Union 3403.09 root ", + " ├─Selection 1701.55 root lt(Column#6, 18)", + " │ └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + " └─Selection 1701.55 root gt(test.t.b, 1)", + " └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + "CTE_0 2126.93 root Non-Recursive CTE", + "└─TableReader(Seed Part) 2126.93 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 2126.93 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 2126.93 mpp[tiflash] or(lt(Column#5, 18), gt(test.t.b, 1))", + " └─Projection 2658.67 mpp[tiflash] Column#5, test.t.b", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:sum(Column#22)->Column#5, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 2658.67 mpp[tiflash] ", + " └─ExchangeSender 2658.67 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#22", + " └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 7095.48 root group by:Column#13, Column#14, funcs:firstrow(Column#13)->Column#13, funcs:firstrow(Column#14)->Column#14", + "└─Union 11086.68 root ", + " ├─Selection 5543.34 root lt(test.t.a, 18)", + " │ └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + " └─Selection 5543.34 root gt(test.t.b, 1)", + " └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + "CTE_0 6929.18 root Non-Recursive CTE", + "└─TableReader(Seed Part) 6929.18 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 6929.18 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 6929.18 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 6929.18 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)], other cond:or(lt(test.t.a, 18), gt(test.t.b, 1))", + " ├─ExchangeReceiver(Build) 5543.34 mpp[tiflash] ", + " │ └─ExchangeSender 5543.34 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 5543.34 mpp[tiflash] not(isnull(test.t.a)), or(lt(test.t.a, 18), gt(test.t.b, 1))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 7095.48 root group by:Column#13, Column#14, funcs:firstrow(Column#13)->Column#13, funcs:firstrow(Column#14)->Column#14", + "└─Union 11086.68 root ", + " ├─Selection 5543.34 root lt(test.t.a, 18)", + " │ └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + " └─Selection 5543.34 root gt(test.t.b, 1)", + " └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + "CTE_0 6929.18 root Non-Recursive CTE", + "└─TableReader(Seed Part) 6929.18 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 6929.18 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 6929.18 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 6929.18 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)], other cond:or(lt(test.t.a, 18), gt(test.t.b, 1))", + " ├─ExchangeReceiver(Build) 5543.34 mpp[tiflash] ", + " │ └─ExchangeSender 5543.34 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 5543.34 mpp[tiflash] not(isnull(test.t.a)), or(lt(test.t.a, 18), gt(test.t.b, 1))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 3013.16 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3013.16 mpp[tiflash] Column#20, Column#21", + " └─HashAgg 3013.16 mpp[tiflash] group by:Column#20, Column#21, funcs:firstrow(Column#20)->Column#20, funcs:firstrow(Column#21)->Column#21", + " └─ExchangeReceiver 3013.16 mpp[tiflash] ", + " └─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#20, collate: binary], [name: Column#21, collate: binary]", + " └─Union 3013.16 mpp[tiflash] ", + " ├─Selection 2126.93 mpp[tiflash] lt(Column#12, 18)", + " │ └─Projection 2658.67 mpp[tiflash] Column#12, test.t.b", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#12, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 3323.33 mpp[tiflash] ", + " │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─Projection 886.22 mpp[tiflash] Column#19->Column#20, test.t.b->Column#21", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#19, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 1107.78 mpp[tiflash] ", + " └─ExchangeSender 1107.78 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─Selection 1107.78 mpp[tiflash] gt(test.t.b, 1), lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 3013.16 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3013.16 mpp[tiflash] Column#20, Column#21", + " └─HashAgg 3013.16 mpp[tiflash] group by:Column#20, Column#21, funcs:firstrow(Column#20)->Column#20, funcs:firstrow(Column#21)->Column#21", + " └─ExchangeReceiver 3013.16 mpp[tiflash] ", + " └─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#20, collate: binary], [name: Column#21, collate: binary]", + " └─Union 3013.16 mpp[tiflash] ", + " ├─Selection 2126.93 mpp[tiflash] lt(Column#12, 18)", + " │ └─Projection 2658.67 mpp[tiflash] Column#12, test.t.b", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:sum(Column#32)->Column#12, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 2658.67 mpp[tiflash] ", + " │ └─ExchangeSender 2658.67 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#32", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─Projection 886.22 mpp[tiflash] Column#19->Column#20, test.t.b->Column#21", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:sum(Column#46)->Column#19, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 886.22 mpp[tiflash] ", + " └─ExchangeSender 886.22 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#46", + " └─Selection 1107.78 mpp[tiflash] gt(test.t.b, 1), lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 5322.67 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 5322.67 mpp[tiflash] Column#29, Column#30", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, funcs:firstrow(Column#29)->Column#29, funcs:firstrow(Column#30)->Column#30", + " └─ExchangeReceiver 5322.67 mpp[tiflash] ", + " └─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary], [name: Column#30, collate: binary]", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, ", + " └─Union 8316.67 mpp[tiflash] ", + " ├─Projection 4154.17 mpp[tiflash] test.t.a->Column#29, test.t.b->Column#30", + " │ └─HashJoin 4154.17 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " │ ├─ExchangeReceiver(Build) 3323.33 mpp[tiflash] ", + " │ │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " │ └─ExchangeReceiver(Probe) 3323.33 mpp[tiflash] ", + " │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Projection 4162.50 mpp[tiflash] test.t.a->Column#29, test.t.b->Column#30", + " └─HashJoin 4162.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 3330.00 mpp[tiflash] ", + " │ └─ExchangeSender 3330.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 3330.00 mpp[tiflash] gt(test.t.b, 1), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t1, t) in optimizer hint /*+ SHUFFLE_JOIN(t1, t, t1, t) */ or /*+ SHUFFLE_JOIN(t1, t, t1, t) */. Maybe you can use the table alias name", + "[planner:1815]There are no matching table names for (t1, t, t1, t) in optimizer hint /*+ SHUFFLE_JOIN(t1, t, t1, t, t1, t) */ or /*+ SHUFFLE_JOIN(t1, t, t1, t, t1, t) */. Maybe you can use the table alias name" + ] + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 5322.67 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 5322.67 mpp[tiflash] Column#29, Column#30", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, funcs:firstrow(Column#29)->Column#29, funcs:firstrow(Column#30)->Column#30", + " └─ExchangeReceiver 5322.67 mpp[tiflash] ", + " └─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary], [name: Column#30, collate: binary]", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, ", + " └─Union 8316.67 mpp[tiflash] ", + " ├─Projection 4154.17 mpp[tiflash] test.t.a->Column#29, test.t.b->Column#30", + " │ └─HashJoin 4154.17 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " │ ├─ExchangeReceiver(Build) 3323.33 mpp[tiflash] ", + " │ │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " │ └─Selection(Probe) 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Projection 4162.50 mpp[tiflash] test.t.a->Column#29, test.t.b->Column#30", + " └─HashJoin 4162.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 3330.00 mpp[tiflash] ", + " │ └─ExchangeSender 3330.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 3330.00 mpp[tiflash] gt(test.t.b, 1), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t1, t) in optimizer hint /*+ BROADCAST_JOIN(t1, t, t1, t) */ or /*+ TIDB_BCJ(t1, t, t1, t) */. Maybe you can use the table alias name", + "[planner:1815]There are no matching table names for (t1, t, t1, t) in optimizer hint /*+ BROADCAST_JOIN(t1, t, t1, t, t1, t) */ or /*+ TIDB_BCJ(t1, t, t1, t, t1, t) */. Maybe you can use the table alias name" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints", + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints", + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints" + ] + }, + { + "SQL": "set @@session.tidb_opt_mpp_outer_join_fixed_build_side = 1", + "Plan": null, + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_opt_mpp_outer_join_fixed_build_side = 0", + "Plan": null, + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t2) */ * from t t1 left join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] left outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1 right join t t2 on t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] right outer join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ shuffle_join(t1, t2@sel_2), hash_join_build(t2@sel_2) */ a from t t1 where t1.a>1 or t1.a in (select a from t t2);", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a", + " └─Selection 8000.00 mpp[tiflash] or(gt(test.t.a, 1), Column#9)", + " └─HashJoin 10000.00 mpp[tiflash] CARTESIAN left outer semi join, other cond:eq(test.t.a, test.t.a)", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]We can't use the HASH_JOIN_BUILD or HASH_JOIN_PROBE hint for left outer semi join, please check the hint" + ] + }, + { + "SQL": "select /*+ shuffle_join(t1, t2@sel_2), hash_join_build(t1) */ a from t t1 where t1.a>1 or t1.a not in (select a from t t2);", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a", + " └─Selection 8000.00 mpp[tiflash] or(gt(test.t.a, 1), Column#9)", + " └─HashJoin 10000.00 mpp[tiflash] Null-aware anti left outer semi join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints", + "[planner:1815]We can't use the HASH_JOIN_BUILD or HASH_JOIN_PROBE hint for anti left outer semi join, please check the hint", + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints" + ] + }, + { + "SQL": "select /*+ shuffle_join(t1, t2@sel_2), hash_join_probe(t2@sel_2) */ a from t t1 where t1.a>1 or t1.a in (select a from t t2);", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a", + " └─Selection 8000.00 mpp[tiflash] or(gt(test.t.a, 1), Column#9)", + " └─HashJoin 10000.00 mpp[tiflash] CARTESIAN left outer semi join, other cond:eq(test.t.a, test.t.a)", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints", + "[planner:1815]We can't use the HASH_JOIN_BUILD or HASH_JOIN_PROBE hint for left outer semi join, please check the hint", + "[planner:1815]Some HASH_JOIN_BUILD and HASH_JOIN_PROBE hints cannot be utilized for MPP joins, please check the hints" + ] + }, + { + "SQL": "select /*+ shuffle_join(t1, t2@sel_2), hash_join_probe(t1) */ a from t t1 where t1.a>1 or t1.a not in (select a from t t2);", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a", + " └─Selection 8000.00 mpp[tiflash] or(gt(test.t.a, 1), Column#9)", + " └─HashJoin 10000.00 mpp[tiflash] Null-aware anti left outer semi join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]We can't use the HASH_JOIN_BUILD or HASH_JOIN_PROBE hint for anti left outer semi join, please check the hint" + ] + } + ] + }, + { + "Name": "TestMPPHintsScope", + "Cases": [ + { + "SQL": "set @@session.tidb_allow_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader_31 8000.00 root MppVersion: 2, data:ExchangeSender_30", + "└─ExchangeSender_30 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection_5 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection_29 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg_27 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection_32 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a->Column#9, test.t.a->Column#10, test.t.c->Column#11", + " └─ExchangeReceiver_23 10000.00 mpp[tiflash] ", + " └─ExchangeSender_22 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan_21 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader_35 8000.00 root MppVersion: 2, data:ExchangeSender_34", + "└─ExchangeSender_34 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection_5 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection_30 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg_31 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver_33 8000.00 mpp[tiflash] ", + " └─ExchangeSender_32 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg_29 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection_36 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a->Column#13, test.t.c->Column#14", + " └─TableFullScan_21 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_22 12487.50 root MppVersion: 2, data:ExchangeSender_21", + "└─ExchangeSender_21 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_20 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_13(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_12 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection_11 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_10 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver_17(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender_16 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection_15 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_14 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_20 12487.50 root MppVersion: 2, data:ExchangeSender_19", + "└─ExchangeSender_19 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_18 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_13(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_12 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_11 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_10 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_15(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_14 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_enforce_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_69 12487.50 root MppVersion: 2, data:ExchangeSender_68", + "└─ExchangeSender_68 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_61 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_65(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_64 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_63 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_62 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_67(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_66 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "MergeJoin_10 12487.50 root inner join, left key:test.t.a, right key:test.t.a", + "├─Projection_19(Build) 9990.00 root test.t.a, test.t.b, test.t.c", + "│ └─IndexLookUp_18 9990.00 root ", + "│ ├─IndexFullScan_16(Build) 9990.00 cop[tikv] table:t2, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─TableRowIDScan_17(Probe) 9990.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─Projection_15(Probe) 9990.00 root test.t.a, test.t.b, test.t.c", + " └─IndexLookUp_14 9990.00 root ", + " ├─IndexFullScan_12(Build) 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + " └─TableRowIDScan_13(Probe) 9990.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "MPP mode may be blocked because you have used hint to specify a join algorithm which is not supported by mpp now.", + "MPP mode may be blocked because you have used hint to specify a join algorithm which is not supported by mpp now." + ] + }, + { + "SQL": "set @@session.tidb_enforce_mpp=false", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_69 12487.50 root MppVersion: 2, data:ExchangeSender_68", + "└─ExchangeSender_68 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_61 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_65(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_64 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_63 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_62 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_67(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_66 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "MergeJoin_10 12487.50 root inner join, left key:test.t.a, right key:test.t.a", + "├─Projection_19(Build) 9990.00 root test.t.a, test.t.b, test.t.c", + "│ └─IndexLookUp_18 9990.00 root ", + "│ ├─IndexFullScan_16(Build) 9990.00 cop[tikv] table:t2, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─TableRowIDScan_17(Probe) 9990.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─Projection_15(Probe) 9990.00 root test.t.a, test.t.b, test.t.c", + " └─IndexLookUp_14 9990.00 root ", + " ├─IndexFullScan_12(Build) 9990.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + " └─TableRowIDScan_13(Probe) 9990.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ read_from_storage(tiflash[t1, t2]) hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_29 12487.50 root MppVersion: 2, data:ExchangeSender_28", + "└─ExchangeSender_28 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_21 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_25(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_24 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_23 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_22 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_27(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_26 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ read_from_storage(tiflash[t1, t2]) merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "MergeJoin_11 12487.50 root inner join, left key:test.t.a, right key:test.t.a", + "├─Sort_21(Build) 9990.00 root test.t.a", + "│ └─TableReader_20 9990.00 root MppVersion: 2, data:ExchangeSender_19", + "│ └─ExchangeSender_19 9990.00 mpp[tiflash] ExchangeType: PassThrough", + "│ └─Selection_18 9990.00 mpp[tiflash] not(isnull(test.t.a))", + "│ └─TableFullScan_17 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo", + "└─Sort_16(Probe) 9990.00 root test.t.a", + " └─TableReader_15 9990.00 root MppVersion: 2, data:ExchangeSender_14", + " └─ExchangeSender_14 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection_13 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_12 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_allow_mpp=false", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "Projection_4 8000.00 root test.t.a, Column#5", + "└─HashAgg_10 8000.00 root group by:test.t.a, test.t.c, funcs:sum(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─TableReader_11 8000.00 root data:HashAgg_5", + " └─HashAgg_5 8000.00 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#6", + " └─TableFullScan_8 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "Projection_4 8000.00 root test.t.a, Column#5", + "└─HashAgg_10 8000.00 root group by:test.t.a, test.t.c, funcs:sum(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─TableReader_11 8000.00 root data:HashAgg_5", + " └─HashAgg_5 8000.00 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#6", + " └─TableFullScan_8 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "HashJoin_37 12487.50 root inner join, equal:[eq(test.t.a, test.t.a)]", + "├─TableReader_56(Build) 9990.00 root data:Selection_55", + "│ └─Selection_55 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan_54 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader_49(Probe) 9990.00 root data:Selection_48", + " └─Selection_48 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan_47 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The join can not push down to the MPP side, the shuffle_join() hint is invalid" + ] + }, + { + "SQL": "explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "HashJoin_37 12487.50 root inner join, equal:[eq(test.t.a, test.t.a)]", + "├─TableReader_56(Build) 9990.00 root data:Selection_55", + "│ └─Selection_55 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan_54 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader_49(Probe) 9990.00 root data:Selection_48", + " └─Selection_48 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan_47 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]The join can not push down to the MPP side, the broadcast_join() hint is invalid" + ] + } + ] + }, + { + "Name": "TestMPPBCJModel", + "Cases": [ + { + "SQL": "set @@session.tidb_allow_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_79 12487.50 root MppVersion: 2, data:ExchangeSender_78", + "└─ExchangeSender_78 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_77 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_44(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_43 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_42 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_41 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_46(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_45 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_81 12487.50 root MppVersion: 2, data:ExchangeSender_80", + "└─ExchangeSender_80 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_79 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_44(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_43 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection_42 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_41 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver_48(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender_47 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection_46 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_45 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestMPPPreferBCJ", + "Cases": [ + { + "SQL": "explain select * from t1, t2 where t1.a=t2.b", + "Plan": [ + "TableReader_36 1.00 root MppVersion: 2, data:ExchangeSender_35", + "└─ExchangeSender_35 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_34 1.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.b)]", + " ├─ExchangeReceiver_15(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender_14 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_13 1.00 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false", + " └─Selection_17(Probe) 8.00 mpp[tiflash] not(isnull(test.t2.b))", + " └─TableFullScan_16 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1, t2 where t1.a=t2.b", + "Plan": [ + "TableReader_38 1.00 root MppVersion: 2, data:ExchangeSender_37", + "└─ExchangeSender_37 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_36 1.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.b)]", + " ├─ExchangeReceiver_15(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender_14 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", + " │ └─Selection_13 1.00 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false", + " └─ExchangeReceiver_19(Probe) 8.00 mpp[tiflash] ", + " └─ExchangeSender_18 8.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " └─Selection_17 8.00 mpp[tiflash] not(isnull(test.t2.b))", + " └─TableFullScan_16 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false" + ], + "Warn": null + }, + { + "SQL": "insert into t2 values (9); analyze table t2;", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1, t2 where t1.a=t2.b", + "Plan": [ + "TableReader_36 1.00 root MppVersion: 2, data:ExchangeSender_35", + "└─ExchangeSender_35 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_34 1.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.b)]", + " ├─ExchangeReceiver_15(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender_14 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_13 1.00 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false", + " └─Selection_17(Probe) 9.00 mpp[tiflash] not(isnull(test.t2.b))", + " └─TableFullScan_16 9.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false" + ], + "Warn": null + } + ] + }, + { + "Name": "TestMPPBCJModelOneTiFlash", + "Cases": [ + { + "SQL": "set @@session.tidb_allow_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_81 12487.50 root MppVersion: 2, data:ExchangeSender_80", + "└─ExchangeSender_80 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_79 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_44(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_43 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection_42 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_41 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver_48(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender_47 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection_46 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_45 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=1", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader_79 12487.50 root MppVersion: 2, data:ExchangeSender_78", + "└─ExchangeSender_78 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_77 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver_44(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender_43 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_42 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan_41 10000.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection_46(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan_45 10000.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestMPPRightSemiJoin", + "Cases": [ + { + "SQL": "set @@session.tidb_allow_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)", + "Plan": [ + "TableReader_36 0.80 root MppVersion: 2, data:ExchangeSender_35", + "└─ExchangeSender_35 0.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_34 0.80 mpp[tiflash] semi join, equal:[eq(test.t1.a, test.t2.b)]", + " ├─ExchangeReceiver_17(Build) 8.00 mpp[tiflash] ", + " │ └─ExchangeSender_16 8.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_15 8.00 mpp[tiflash] not(isnull(test.t2.b))", + " │ └─TableFullScan_14 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false", + " └─Selection_13(Probe) 1.00 mpp[tiflash] not(isnull(test.t1.a))", + " └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_broadcast_join_threshold_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_broadcast_join_threshold_count=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)", + "Plan": [ + "TableReader_38 0.80 root MppVersion: 2, data:ExchangeSender_37", + "└─ExchangeSender_37 0.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_36 0.80 mpp[tiflash] semi join, equal:[eq(test.t1.a, test.t2.b)]", + " ├─ExchangeReceiver_15(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender_14 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", + " │ └─Selection_13 1.00 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false", + " └─ExchangeReceiver_19(Probe) 8.00 mpp[tiflash] ", + " └─ExchangeSender_18 8.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " └─Selection_17 8.00 mpp[tiflash] not(isnull(test.t2.b))", + " └─TableFullScan_16 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false" + ], + "Warn": null + } + ] + }, + { + "Name": "TestMPPRightOuterJoin", + "Cases": [ + { + "SQL": "set @@session.tidb_allow_mpp=true", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1 right join t2 on t1.a=t2.b and t1.c < t2.d", + "Plan": [ + "TableReader_32 3.00 root MppVersion: 2, data:ExchangeSender_31", + "└─ExchangeSender_31 3.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_30 3.00 mpp[tiflash] right outer join, equal:[eq(test.t1.a, test.t2.b)], other cond:lt(test.t1.c, test.t2.d)", + " ├─ExchangeReceiver_14(Build) 5.00 mpp[tiflash] ", + " │ └─ExchangeSender_13 5.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection_12 5.00 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.c))", + " │ └─TableFullScan_11 5.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false", + " └─TableFullScan_15(Probe) 3.00 mpp[tiflash] table:t2 keep order:false" + ], + "Warn": null + }, + { + "SQL": "set @@session.tidb_prefer_broadcast_join_by_exchange_data_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_broadcast_join_threshold_size=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "set @@session.tidb_broadcast_join_threshold_count=0", + "Plan": null, + "Warn": null + }, + { + "SQL": "explain select * from t1 right join t2 on t1.a=t2.b and t1.c < t2.d", + "Plan": [ + "TableReader_34 3.00 root MppVersion: 2, data:ExchangeSender_33", + "└─ExchangeSender_33 3.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_32 3.00 mpp[tiflash] right outer join, equal:[eq(test.t1.a, test.t2.b)], other cond:lt(test.t1.c, test.t2.d)", + " ├─ExchangeReceiver_17(Build) 3.00 mpp[tiflash] ", + " │ └─ExchangeSender_16 3.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─TableFullScan_15 3.00 mpp[tiflash] table:t2 keep order:false", + " └─ExchangeReceiver_14(Probe) 5.00 mpp[tiflash] ", + " └─ExchangeSender_13 5.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", + " └─Selection_12 5.00 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.c))", + " └─TableFullScan_11 5.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false" + ], + "Warn": null + } + ] + }, + { + "Name": "TestIssue37520", + "Cases": [ + { + "SQL": "select /*+ inl_join(t1@sel_2) */ a, (select b from t1 where t1.a = t2.b) from t2;", + "Plan": [ + "IndexJoin 12500.00 root left outer join, inner:TableReader, outer key:test.t2.b, inner key:test.t1.a, equal cond:eq(test.t2.b, test.t1.a)", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t1 range: decided by [test.t2.b], keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ inl_join(t2) */ a, (select b from t1 where t1.a = t2.b) from t2;", + "Plan": [ + "HashJoin 12500.00 root left outer join, equal:[eq(test.t2.b, test.t1.a)]", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable" + ] + }, + { + "SQL": "select /*+ inl_join(t2@sel_2) */ * from t1 where exists ( select /*+ semi_join_rewrite() */ * from t2 where t1.a = t2.a);", + "Plan": [ + "MergeJoin 9990.00 root inner join, left key:test.t1.a, right key:test.t2.a", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:ia(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:true, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable" + ] + }, + { + "SQL": "select /*+ inl_join(t1) */ * from t1 where exists ( select /*+ semi_join_rewrite() */ * from t2 where t1.a = t2.a);", + "Plan": [ + "IndexJoin 9990.00 root inner join, inner:TableReader, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:ia(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 7992.00 root data:TableRangeScan", + " └─TableRangeScan 7992.00 cop[tikv] table:t1 range: decided by [test.t2.a], keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestHintScope", + "Cases": [ + { + "SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,NULL]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ MERGE_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(test.t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,NULL]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "MergeInnerJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)->Sort}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ INL_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "IndexJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ HASH_JOIN(test.t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(test.t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "RightHashJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.c,test.t.a)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "MergeInnerJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "IndexJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + }, + { + "SQL": "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b", + "Best": "MergeInnerJoin{LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort->TableReader(Table(t))->Sort}(test.t.b,test.t.b)" + }, + { + "SQL": "select /*+ STREAM_AGG() */ s, count(s) from (select /*+ HASH_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->Sort->StreamAgg->Projection" + }, + { + "SQL": "select /*+ HASH_AGG() */ s, count(s) from (select /*+ STREAM_AGG() */ sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Sort->Projection->StreamAgg->HashAgg->Projection" + }, + { + "SQL": "select /*+ HASH_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->HashAgg->Projection" + }, + { + "SQL": "select /*+ STREAM_AGG() */ s, count(s) from (select sum(t1.a) as s from t t1, t t2 where t1.a = t2.b group by t1.a) p group by s", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->Projection->HashAgg->Sort->StreamAgg->Projection" + } + ] + }, + { + "Name": "TestIndexHint", + "Cases": [ + { + "SQL": "select /*+ USE_INDEX(t, c_d_e) */ * from t", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), no_order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ USE_INDEX(test.t, c_d_e) */ * from t", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), no_order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(test.t, c_d_e) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e) */ * from t", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), no_order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(test.t, c_d_e) */ * from t", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), no_order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, c_d_e) */ * from t t1", + "Best": "TableReader(Table(t))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(t, c_d_e) */ t1.c from t t1 order by t1.c", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`), order_index(@`sel_1` `test`.`t1` `c_d_e`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e) */ * from t t1", + "Best": "TableReader(Table(t))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX(t1, c_d_e) */ * from t t1", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`), no_order_index(@`sel_1` `test`.`t1` `c_d_e`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(t1, c_d_e) */ t1.c from t t1 order by t1.c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t1, c_d_e) */ * from t t1", + "Best": "IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t1` `c_d_e`), no_order_index(@`sel_1` `test`.`t1` `c_d_e`)" + }, + { + "SQL": "select /*+ USE_INDEX(t1, c_d_e), USE_INDEX(t2, f) */ * from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))}(test.t.a,test.t.b)", + "HasWarn": false, + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `c_d_e`), no_order_index(@`sel_1` `test`.`t1` `c_d_e`), use_index(@`sel_1` `test`.`t2` `f`), no_order_index(@`sel_1` `test`.`t2` `f`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(t1, c_d_e), IGNORE_INDEX(t2, f), HASH_JOIN(t1) */ * from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.b)", + "HasWarn": false, + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_1` `test`.`t2` ), no_order_index(@`sel_1` `test`.`t2` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t1, c_d_e), FORCE_INDEX(t2, f) */ * from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{IndexLookUp(Index(t.c_d_e)[[NULL,+inf]], Table(t))->IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))}(test.t.a,test.t.b)", + "HasWarn": false, + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `c_d_e`), no_order_index(@`sel_1` `test`.`t1` `c_d_e`), use_index(@`sel_1` `test`.`t2` `f`), no_order_index(@`sel_1` `test`.`t2` `f`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, c_d_e, f, g) */ * from t order by f", + "Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `f`), order_index(@`sel_1` `test`.`t` `f`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e, f, g) */ * from t order by f", + "Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `f`), order_index(@`sel_1` `test`.`t` `f`)" + }, + { + "SQL": "select /*+ USE_INDEX(t) */ f from t where f > 10", + "Best": "TableReader(Table(t)->Sel([gt(test.t.f, 10)]))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t) */ f from t where f > 10", + "Best": "TableReader(Table(t)->Sel([gt(test.t.f, 10)]))", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, no_such_index) */ * from t", + "Best": "TableReader(Table(t))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ IGNORE_INDEX(t, no_such_index) */ * from t", + "Best": "TableReader(Table(t))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, no_such_index) */ * from t", + "Best": "TableReader(Table(t))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, f) */ c from t order by c", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, f), IGNORE_INDEX(t, f) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, c_d_e), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX(t, c_d_e, f), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `f`), no_order_index(@`sel_1` `test`.`t` `f`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e), IGNORE_INDEX(t, f) */ c from t order by c", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]])", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `c_d_e`), order_index(@`sel_1` `test`.`t` `c_d_e`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, f), IGNORE_INDEX(t, f) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "Best": "TableReader(Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ FORCE_INDEX(t, c_d_e, f), IGNORE_INDEX(t, c_d_e) */ c from t order by c", + "Best": "IndexLookUp(Index(t.f)[[NULL,+inf]], Table(t))->Sort", + "HasWarn": false, + "Hints": "use_index(@`sel_1` `test`.`t` `f`), no_order_index(@`sel_1` `test`.`t` `f`)" + } + ] + }, + { + "Name": "TestIndexMergeHint", + "Cases": [ + { + "SQL": "select /*+ USE_INDEX_MERGE(t, c_d_e, f_g) */ * from t where c < 1 or f > 2", + "Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))", + "HasWarn": false, + "Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f_g`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t, primary, f_g) */ * from t where a < 1 or f > 2", + "Best": "IndexMergeReader(PartialPlans->[Table(t), Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))", + "HasWarn": false, + "Hints": "use_index_merge(@`sel_1` `t` `primary`, `f_g`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "Best": "IndexMergeReader(PartialPlans->[Table(t), Index(t.f_g)[(2,+inf]]], TablePlan->Table(t))", + "HasWarn": false, + "Hints": "use_index_merge(@`sel_1` `t` `primary`, `f_g`)" + }, + { + "SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.a, 1), gt(test.t.f, 2))]))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t1, c_d_e, f_g) */ * from t where c < 1 or f > 2", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.a, 1), gt(test.t.f, 2))]))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(t) USE_INDEX_MERGE(t) */ * from t where c < 1 or f > 2", + "Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))", + "HasWarn": false, + "Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(db2.t) */ * from t where c < 1 or f > 2", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + }, + { + "SQL": "select /*+ USE_INDEX_MERGE(db2.t, c_d_e, f_g) */ * from t where c < 1 or f > 2", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", + "HasWarn": true, + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`)" + } + ] + }, + { + "Name": "TestRefine", + "Cases": [ + { + "SQL": "select a from t where c is not null", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]])" + }, + { + "SQL": "select a from t where c >= 4", + "Best": "IndexReader(Index(t.c_d_e)[[4,+inf]])->Projection" + }, + { + "SQL": "select a from t where c <= 4", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,4]])->Projection" + }, + { + "SQL": "select a from t where c = 4 and d = 5 and e = 6", + "Best": "PointGet(Index(t.c_d_e)[KindInt64 4 KindInt64 5 KindInt64 6])->Projection" + }, + { + "SQL": "select a from t where d = 4 and c = 5", + "Best": "IndexReader(Index(t.c_d_e)[[5 4,5 4]])->Projection" + }, + { + "SQL": "select a from t where c = 4 and e < 5", + "Best": "IndexReader(Index(t.c_d_e)[[4,4]]->Sel([lt(test.t.e, 5)]))->Projection" + }, + { + "SQL": "select a from t where c = 4 and d <= 5 and d > 3", + "Best": "IndexReader(Index(t.c_d_e)[(4 3,4 5]])->Projection" + }, + { + "SQL": "select a from t where d <= 5 and d > 3", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([le(test.t.d, 5) gt(test.t.d, 3)]))->Projection" + }, + { + "SQL": "select a from t where c between 1 and 2", + "Best": "IndexReader(Index(t.c_d_e)[[1,2]])->Projection" + }, + { + "SQL": "select a from t where c not between 1 and 2", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (2,+inf]])->Projection" + }, + { + "SQL": "select a from t where c <= 5 and c >= 3 and d = 1", + "Best": "IndexReader(Index(t.c_d_e)[[3,5]]->Sel([eq(test.t.d, 1)]))->Projection" + }, + { + "SQL": "select a from t where c = 1 or c = 2 or c = 3", + "Best": "IndexReader(Index(t.c_d_e)[[1,3]])->Projection" + }, + { + "SQL": "select b from t where c = 1 or c = 2 or c = 3 or c = 4 or c = 5", + "Best": "TableReader(Table(t)->Sel([or(or(eq(test.t.c, 1), eq(test.t.c, 2)), or(eq(test.t.c, 3), or(eq(test.t.c, 4), eq(test.t.c, 5))))]))->Projection" + }, + { + "SQL": "select a from t where c = 5", + "Best": "IndexReader(Index(t.c_d_e)[[5,5]])->Projection" + }, + { + "SQL": "select a from t where c = 5 and b = 1", + "Best": "IndexLookUp(Index(t.c_d_e)[[5,5]], Table(t)->Sel([eq(test.t.b, 1)]))->Projection" + }, + { + "SQL": "select a from t where not a", + "Best": "PointGet(Handle(t.a)0)" + }, + { + "SQL": "select a from t where c in (1)", + "Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection" + }, + { + "SQL": "select a from t where c in ('1')", + "Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection" + }, + { + "SQL": "select a from t where c = 1.0", + "Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection" + }, + { + "SQL": "select a from t where c in (1) and d > 3", + "Best": "IndexReader(Index(t.c_d_e)[(1 3,1 +inf]])->Projection" + }, + { + "SQL": "select a from t where c in (1, 2, 3) and (d > 3 and d < 4 or d > 5 and d < 6)", + "Best": "Dual->Projection" + }, + { + "SQL": "select a from t where c in (1, 2, 3) and (d > 2 and d < 4 or d > 5 and d < 7)", + "Best": "IndexReader(Index(t.c_d_e)[[1 3,1 3] [1 6,1 6] [2 3,2 3] [2 6,2 6] [3 3,3 3] [3 6,3 6]])->Projection" + }, + { + "SQL": "select a from t where c in (1, 2, 3)", + "Best": "IndexReader(Index(t.c_d_e)[[1,1] [2,2] [3,3]])->Projection" + }, + { + "SQL": "select a from t where c in (1, 2, 3) and d in (1,2) and e = 1", + "Best": "BatchPointGet(Index(t.c_d_e)[[KindInt64 1 KindInt64 1 KindInt64 1] [KindInt64 1 KindInt64 2 KindInt64 1] [KindInt64 2 KindInt64 1 KindInt64 1] [KindInt64 2 KindInt64 2 KindInt64 1] [KindInt64 3 KindInt64 1 KindInt64 1] [KindInt64 3 KindInt64 2 KindInt64 1]])->Projection" + }, + { + "SQL": "select a from t where d in (1, 2, 3)", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([in(test.t.d, 1, 2, 3)]))->Projection" + }, + { + "SQL": "select a from t where c not in (1)", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (1,+inf]])->Projection" + }, + { + "SQL": "select a from t use index(c_d_e) where c != 1", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,1) (1,+inf]])->Projection" + }, + { + "SQL": "select a from t where c_str like ''", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"\",\"\"]]->Sel([like(test.t.c_str, , 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abc\"]]->Sel([like(test.t.c_str, abc, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str not like 'abc'", + "Best": "IndexReader(Index(t.c_d_e_str)[[NULL,+inf]]->Sel([not(like(test.t.c_str, abc, 92))]))->Projection" + }, + { + "SQL": "select a from t where not (c_str like 'abc' or c_str like 'abd')", + "Best": "IndexReader(Index(t.c_d_e_str)[[NULL,+inf]]->Sel([and(not(like(test.t.c_str, abc, 92)), not(like(test.t.c_str, abd, 92)))]))->Projection" + }, + { + "SQL": "select a from t where c_str like '_abc'", + "Best": "IndexReader(Index(t.c_d_e_str)[[NULL,+inf]]->Sel([like(test.t.c_str, _abc, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc%'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abd\")]->Sel([like(test.t.c_str, abc%, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc_'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abd\")]->Sel([like(test.t.c_str, abc_, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc%af'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc\",\"abd\")]->Sel([like(test.t.c_str, abc%af, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc\\_' escape ''", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]]->Sel([like(test.t.c_str, abc\\_, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc\\_'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]]->Sel([like(test.t.c_str, abc\\_, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc\\\\_'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc_\"]]->Sel([like(test.t.c_str, abc\\_, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc\\_%'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc`\")]->Sel([like(test.t.c_str, abc\\_%, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc=_%' escape '='", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc`\")]->Sel([like(test.t.c_str, abc=_%, 61)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 'abc\\__'", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"abc_\",\"abc`\")]->Sel([like(test.t.c_str, abc\\__, 92)]))->Projection" + }, + { + "SQL": "select a from t where c_str like 123", + "Best": "IndexReader(Index(t.c_d_e_str)[[\"123\",\"123\"]]->Sel([like(test.t.c_str, 123, 92)]))->Projection" + }, + { + "SQL": "select a from t where c = 1.9 and d > 3", + "Best": "Dual" + }, + { + "SQL": "select a from t where c < 1.1", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,2)])->Projection" + }, + { + "SQL": "select a from t where c <= 1.9", + "Best": "IndexReader(Index(t.c_d_e)[[-inf,1]])->Projection" + }, + { + "SQL": "select a from t where c >= 1.1", + "Best": "IndexReader(Index(t.c_d_e)[[2,+inf]])->Projection" + }, + { + "SQL": "select a from t where c > 1.9", + "Best": "IndexReader(Index(t.c_d_e)[(1,+inf]])->Projection" + }, + { + "SQL": "select a from t where c = 123456789098765432101234", + "Best": "Dual" + }, + { + "SQL": "select a from t where c = 'hanfei'", + "Best": "IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Sel([eq(cast(test.t.c, double BINARY), cast(hanfei, double BINARY))]))->Projection" + } + ] + }, + { + "Name": "TestAggEliminator", + "Cases": [ + { + "SQL": "select max(a) from t;", + "Best": "TableReader(Table(t)->Limit)->Limit->StreamAgg" + }, + { + "SQL": "select min(a) from t;", + "Best": "TableReader(Table(t)->Limit)->Limit->StreamAgg" + }, + { + "SQL": "select min(c_str) from t;", + "Best": "IndexReader(Index(t.c_d_e_str)[[-inf,+inf]]->Limit)->Limit->StreamAgg" + }, + { + "SQL": "select max(a), b from t;", + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" + }, + { + "SQL": "select max(a+1) from t;", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->TopN([plus(test.t.a, 1) true],0,1))->Projection->TopN([Column#40 true],0,1)->Projection->Projection->StreamAgg" + }, + { + "SQL": "select max(a), min(a) from t;", + "Best": "RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" + }, + { + "SQL": "select max(a), min(a) from t where a > 10", + "Best": "RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" + }, + { + "SQL": "select max(d), min(d) from t where c = 1 and d > 10", + "Best": "LeftHashJoin{IndexReader(Index(t.c_d_e)[(1 10,1 +inf]]->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[(1 10,1 +inf]]->Limit)->Limit->StreamAgg}" + }, + { + "SQL": "select max(a), max(c), min(f) from t", + "Best": "LeftHashJoin{RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit->StreamAgg}->IndexReader(Index(t.f)[[NULL,+inf]]->Limit)->Limit->StreamAgg}" + }, + { + "SQL": "select max(a), max(b) from t", + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" + }, + { + "SQL": "select max(a), max(c) from t where c > 10", + "Best": "IndexReader(Index(t.c_d_e)[(10,+inf]]->HashAgg)->HashAgg" + }, + { + "SQL": "select max(a), min(a) from t where a * 3 + 10 < 100", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->Sel([lt(plus(mul(test.t.a, 3), 10), 100)])->HashAgg)->HashAgg" + }, + { + "SQL": "select max(a) from t group by b;", + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" + }, + { + "SQL": "select max(a) from (select t1.a from t t1 join t t2 on t1.a=t2.a) t", + "Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Limit->StreamAgg" + } + ] + }, + { + "Name": "TestRuleColumnPruningLogicalApply", + "Cases": [ + { + "SQL": "SELECT COUNT(*) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->HashAgg)->HashAgg" + }, + { + "SQL": "SELECT COUNT(a) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->HashAgg)->HashAgg" + }, + { + "SQL": "SELECT COUNT(t) FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "Best": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Limit}->HashAgg" + }, + { + "SQL": "SELECT COUNT(a) FROM t t1 WHERE t1.a IN (SELECT t2.a FROM t t2, t t3 WHERE t2.b = t3.b)", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.b,test.t.b)->HashAgg}(test.t.a,test.t.a)->HashAgg" + }, + { + "SQL": "SELECT a FROM (SELECT a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]])" + }, + { + "SQL": "SELECT a FROM t WHERE b IN (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a)", + "Best": "LeftHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->HashAgg}(test.t.b,test.t.b)" + }, + { + "SQL": "SELECT a FROM t WHERE EXISTS (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t2.b=t.b)", + "Best": "LeftHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)}(test.t.b,test.t.b)" + }, + { + "SQL": "SELECT a FROM t WHERE NOT EXISTS (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t2.b=t.b)", + "Best": "LeftHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)}(test.t.b,test.t.b)" + }, + { + "SQL": "SELECT a FROM t WHERE b IN (SELECT b FROM t WHERE b = 1 AND a IN (SELECT a FROM t WHERE a > 0))", + "Best": "RightHashJoin{IndexJoin{TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->TableReader(Table(t)->Sel([gt(test.t.a, 0)]))}(test.t.a,test.t.a)->HashAgg->TableReader(Table(t))}(test.t.b,test.t.b)" + }, + { + "SQL": "SELECT a FROM t WHERE b IN (SELECT b FROM t WHERE b = 1 AND a IN (SELECT t2.a FROM (SELECT t1.a, (SELECT t2.b FROM t t2, t t3 WHERE t2.a = t3.a AND t1.a = t2.a LIMIT 1) t FROM t t1) t2))", + "Best": "LeftHashJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->TableReader(Table(t))}(test.t.a,test.t.a)->HashAgg}(test.t.b,test.t.b)" + } + ] + }, + { + "Name": "TestUnmatchedTableInHint", + "Cases": [ + { + "SQL": "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ MERGE_JOIN(t3, t4) */ or /*+ TIDB_SMJ(t3, t4) */. Maybe you can use the table alias name" + }, + { + "SQL": "SELECT /*+ TIDB_HJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ HASH_JOIN(t3, t4) */ or /*+ TIDB_HJ(t3, t4) */. Maybe you can use the table alias name" + }, + { + "SQL": "SELECT /*+ TIDB_INLJ(t3, t4) */ * from t t1, t t2 where t1.a = t2.a", + "Warning": "[planner:1815]There are no matching table names for (t3, t4) in optimizer hint /*+ INL_JOIN(t3, t4) */ or /*+ TIDB_INLJ(t3, t4) */. Maybe you can use the table alias name" + }, + { + "SQL": "SELECT /*+ TIDB_SMJ(t1, t2) */ * from t t1, t t2 where t1.a = t2.a", + "Warning": "" + }, + { + "SQL": "SELECT /*+ TIDB_SMJ(t3, t4) */ * from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a", + "Warning": "[planner:1815]There are no matching table names for (t4) in optimizer hint /*+ MERGE_JOIN(t3, t4) */ or /*+ TIDB_SMJ(t3, t4) */. Maybe you can use the table alias name" + } + ] + }, + { + "Name": "TestJoinHints", + "Cases": [ + { + "SQL": "select /*+ TIDB_INLJ(t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", + "Best": "MergeInnerJoin{IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)", + "Warning": "", + "Hints": "merge_join(@`sel_1` `test`.`t3`), inl_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_1` `test`.`t2` ), order_index(@`sel_1` `test`.`t2` `primary`), use_index(@`sel_1` `test`.`t3` ), order_index(@`sel_1` `test`.`t3` `primary`)" + }, + { + "SQL": "select /*+ TIDB_INLJ(test.t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", + "Best": "MergeInnerJoin{IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)", + "Warning": "", + "Hints": "merge_join(@`sel_1` `test`.`t3`), inl_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_1` `test`.`t2` ), order_index(@`sel_1` `test`.`t2` `primary`), use_index(@`sel_1` `test`.`t3` ), order_index(@`sel_1` `test`.`t3` `primary`)" + }, + { + "SQL": "select /*+ TIDB_INLJ(t1) */ t1.b, t2.a from t t1, t t2 where t1.b = t2.a;", + "Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.b,test.t.a)", + "Warning": "[planner:1815]Optimizer Hint /*+ INL_JOIN(t1) */ or /*+ TIDB_INLJ(t1) */ is inapplicable", + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_1` `test`.`t2` `f`), no_order_index(@`sel_1` `test`.`t2` `f`)" + }, + { + "SQL": "select /*+ TIDB_INLJ(t2) */ t1.b, t2.a from t2 t1, t2 t2 where t1.b=t2.b and t2.c=-1;", + "Best": "IndexJoin{TableReader(Table(t2)->Sel([eq(test.t2.c, -1)]))->IndexReader(Index(t2.b)[[NULL,NULL]])}(test.t2.b,test.t2.b)->Projection", + "Warning": "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable", + "Hints": "inl_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t2` ), no_order_index(@`sel_1` `test`.`t2` `primary`), use_index(@`sel_1` `test`.`t1` `b`), no_order_index(@`sel_1` `test`.`t1` `b`)" + } + ] + }, + { + "Name": "TestAggregationHints", + "Cases": [ + { + "SQL": "select count(*) from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->StreamAgg", + "Warning": "" + }, + { + "SQL": "select count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])->Projection}(test.t.a,Column#26)->HashAgg", + "Warning": "" + }, + { + "SQL": "select /*+ HASH_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->HashAgg", + "Warning": "" + }, + { + "SQL": "select /*+ STREAM_AGG() */ count(t1.a) from t t1, t t2 where t1.a = t2.a*2 group by t1.a", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])->Projection}(test.t.a,Column#26)->Sort->StreamAgg", + "Warning": "" + }, + { + "SQL": "select /*+ HASH_AGG() STREAM_AGG() */ count(*) from t t1, t t2 where t1.a = t2.b", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))}(test.t.a,test.t.b)->StreamAgg", + "Warning": "[planner:1815]Optimizer aggregation hints are conflicted" + }, + { + "SQL": "select /*+ STREAM_AGG() */ distinct a from t", + "Best": "IndexReader(Index(t.f)[[NULL,+inf]])", + "Warning": "" + }, + { + "SQL": "select /*+ HASH_AGG() */ t1.a from t t1 where t1.a < any(select t2.b from t t2)", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t)->HashAgg)->HashAgg->Sel([ne(Column#27, 0)])}", + "Warning": "" + }, + { + "SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a != any(select t2.b from t t2)", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))->HashAgg->Sel([ne(Column#28, 0)])}", + "Warning": "" + }, + { + "SQL": "select /*+ hash_agg() */ t1.a from t t1 where t1.a = all(select t2.b from t t2)", + "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->TableReader(Table(t))->HashAgg->Sel([or(and(le(Column#26, 1), if(ne(Column#27, 0), , 1)), or(eq(Column#28, 0), 0))])}", + "Warning": "" + }, + { + "SQL": "select /*+ STREAM_AGG() */ sum(t1.a) from t t1 join t t2 on t1.b = t2.b group by t1.b", + "Best": "LeftHashJoin{TableReader(Table(t))->TableReader(Table(t))->Sort->Projection->StreamAgg}(test.t.b,test.t.b)->HashAgg", + "Warning": "" + }, + { + "SQL": "select /*+ STREAM_AGG() */ e, sum(b) from t group by e", + "Best": "TableReader(Table(t))->Sort->Projection->StreamAgg->Projection", + "Warning": "" + } + ] + }, + { + "Name": "TestQueryBlockHint", + "Cases": [ + { + "SQL": "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@sel_2 t3) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "IndexJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,NULL]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), no_order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ MERGE_JOIN(@sel_1 t1), INL_JOIN(@qb t3) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "IndexJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,NULL]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), no_order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ HASH_JOIN(@sel_1 t1), MERGE_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t2) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ INL_JOIN(@sel_1 t1), HASH_JOIN(@qb t2) */ t1.a, t1.b from t t1, (select /*+ QB_NAME(qb) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", + "Plan": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)", + "Hints": "use_index(@`sel_1` `test`.`t1` ), order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` ), order_index(@`sel_2` `test`.`t2` `primary`), use_index(@`sel_2` `test`.`t3` `c_d_e`), order_index(@`sel_2` `test`.`t3` `c_d_e`)" + }, + { + "SQL": "select /*+ HASH_AGG(@sel_1), STREAM_AGG(@sel_2) */ count(*) from t t1 where t1.a < (select count(*) from t t2 where t1.a > t2.a)", + "Plan": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]]->Sel([gt(test.t.a, test.t.a)])->StreamAgg)->StreamAgg}->HashAgg", + "Hints": "hash_agg(@`sel_1`), use_index(@`sel_1` `test`.`t1` `f`), no_order_index(@`sel_1` `test`.`t1` `f`), stream_agg(@`sel_2`), use_index(@`sel_2` `test`.`t2` `f`), no_order_index(@`sel_2` `test`.`t2` `f`), agg_to_cop(@`sel_2`)" + }, + { + "SQL": "select /*+ STREAM_AGG(@sel_1), HASH_AGG(@qb) */ count(*) from t t1 where t1.a < (select /*+ QB_NAME(qb) */ count(*) from t t2 where t1.a > t2.a)", + "Plan": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]]->Sel([gt(test.t.a, test.t.a)])->HashAgg)->HashAgg}->StreamAgg", + "Hints": "stream_agg(@`sel_1`), use_index(@`sel_1` `test`.`t1` `f`), no_order_index(@`sel_1` `test`.`t1` `f`), hash_agg(@`sel_2`), use_index(@`sel_2` `test`.`t2` `f`), no_order_index(@`sel_2` `test`.`t2` `f`), agg_to_cop(@`sel_2`)" + }, + { + "SQL": "select /*+ HASH_AGG(@sel_2) */ a, (select count(*) from t t1 where t1.b > t.a) from t where b > (select b from t t2 where t2.b = t.a limit 1)", + "Plan": "Apply{Apply{TableReader(Table(t))->TableReader(Table(t)->Sel([eq(test.t.b, test.t.a)])->Limit)->Limit}->TableReader(Table(t)->Sel([gt(test.t.b, test.t.a)])->HashAgg)->HashAgg}->Projection", + "Hints": "use_index(@`sel_1` `test`.`t` ), no_order_index(@`sel_1` `test`.`t` `primary`), use_index(@`sel_3` `test`.`t2` ), no_order_index(@`sel_3` `test`.`t2` `primary`), limit_to_cop(@`sel_3`), hash_agg(@`sel_2`), use_index(@`sel_2` `test`.`t1` ), no_order_index(@`sel_2` `test`.`t1` `primary`), agg_to_cop(@`sel_2`)" + }, + { + "SQL": "select /*+ HASH_JOIN(@sel_1 t1), HASH_JOIN(@sel_2 t1) */ t1.b, t2.a, t2.aa from t t1, (select t1.a as a, t2.a as aa from t t1, t t2) t2 where t1.a = t2.aa;", + "Plan": "LeftHashJoin{LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->IndexReader(Index(t.f)[[NULL,+inf]])}->Projection", + "Hints": "use_index(@`sel_1` `test`.`t1` ), no_order_index(@`sel_1` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` `f`), no_order_index(@`sel_2` `test`.`t2` `f`), use_index(@`sel_2` `test`.`t1` `f`), no_order_index(@`sel_2` `test`.`t1` `f`)" + }, + { + "SQL": "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b", + "Plan": "MergeInnerJoin{TableReader(Table(t))->Sort->LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort}(test.t.b,test.t.b)->Projection", + "Hints": "use_index(@`sel_1` `test`.`t2` ), no_order_index(@`sel_1` `test`.`t2` `primary`), hash_join(@`sel_2` `test`.`t1`), use_index(@`sel_2` `test`.`t1` ), no_order_index(@`sel_2` `test`.`t1` `primary`), use_index(@`sel_2` `test`.`t2` `f`), no_order_index(@`sel_2` `test`.`t2` `f`)" + } + ] + }, + { + "Name": "TestSemiJoinToInner", + "Cases": [ + { + "SQL": "select t1.a, (select count(t2.a) from t t2 where t2.g in (select t3.d from t t3 where t3.c = t1.a)) as agg_col from t t1;", + "Best": "Apply{IndexReader(Index(t.f)[[NULL,+inf]])->IndexHashJoin{IndexReader(Index(t.c_d_e)[[NULL,+inf]]->HashAgg)->HashAgg->IndexReader(Index(t.g)[[NULL,NULL]])}(test.t.d,test.t.g)}->HashAgg" + } + ] + }, + { + "Name": "TestIndexJoinHint", + "Cases": [ + { + "SQL": "select /*+ INL_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)" + }, + { + "SQL": "select /*+ INL_HASH_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "Plan": "IndexHashJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)" + }, + { + "SQL": "select /*+ INL_MERGE_JOIN(t1) */ * from t1 join t2 on t1.a = t2.a;", + "Plan": "IndexMergeJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->Projection->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)" + }, + { + "SQL": "select /*+ inl_merge_join(t2) */ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g", + "Plan": "IndexMergeJoin{IndexReader(Index(t.g_2)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)" + }, + { + "SQL": "select /*+inl_merge_join(t2)*/ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g order by t1.a", + "Plan": "IndexMergeJoin{IndexReader(Index(t.g_2)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)->Sort" + } + ] + }, + { + "Name": "TestAggToCopHint", + "Cases": [ + { + "SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ sum(a) from ta group by a", + "Best": "IndexReader(Index(ta.a)[[NULL,+inf]]->HashAgg)->HashAgg", + "Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists" + }, + { + "SQL": "select /*+ AGG_TO_COP(), USE_INDEX(t) */ sum(b) from ta group by b", + "Best": "TableReader(Table(ta)->HashAgg)->HashAgg", + "Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists" + }, + { + "SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), USE_INDEX(t) */ distinct a from ta group by a", + "Best": "IndexReader(Index(ta.a)[[NULL,+inf]]->HashAgg)->HashAgg", + "Warning": "[planner:1815]use_index(test.t) is inapplicable, check whether the table(test.t) exists" + }, + { + "SQL": "select /*+ AGG_TO_COP(), HASH_AGG(), HASH_JOIN(t1), USE_INDEX(t1), USE_INDEX(t2) */ sum(t1.a) from ta t1, ta t2 where t1.a = t2.b group by t1.a", + "Best": "LeftHashJoin{TableReader(Table(ta)->Sel([not(isnull(test.ta.a))]))->TableReader(Table(ta)->Sel([not(isnull(test.ta.b))]))}(test.ta.a,test.ta.b)->Projection->HashAgg", + "Warning": "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable" + } + ] + }, + { + "Name": "TestGroupConcatOrderby", + "Cases": [ + { + "SQL": "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from test;", + "Plan": [ + "HashAgg 1.00 root funcs:group_concat(Column#6 order by Column#7 desc separator \"++\")->Column#4, funcs:group_concat(Column#8 order by Column#9 desc, Column#10 separator \"--\")->Column#5", + "└─Projection 10000.00 root cast(test.test.name, var_string(20))->Column#6, test.test.name->Column#7, cast(test.test.id, var_string(20))->Column#8, test.test.name->Column#9, test.test.id->Column#10", + " └─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo" + ], + "Result": [ + "500++200++30++20++20++10 3--3--1--1--2--1" + ] + }, + { + "SQL": "select /*+ agg_to_cop */ group_concat(name ORDER BY name desc SEPARATOR '++'), group_concat(id ORDER BY name desc, id asc SEPARATOR '--') from ptest;", + "Plan": [ + "HashAgg 1.00 root funcs:group_concat(Column#6 order by Column#7 desc separator \"++\")->Column#4, funcs:group_concat(Column#8 order by Column#9 desc, Column#10 separator \"--\")->Column#5", + "└─Projection 10000.00 root cast(test.ptest.name, var_string(20))->Column#6, test.ptest.name->Column#7, cast(test.ptest.id, var_string(20))->Column#8, test.ptest.name->Column#9, test.ptest.id->Column#10", + " └─TableReader 10000.00 root partition:all data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:ptest keep order:false, stats:pseudo" + ], + "Result": [ + "500++200++30++20++20++10 3--3--1--1--2--1" + ] + }, + { + "SQL": "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from test;", + "Plan": [ + "HashAgg 1.00 root funcs:group_concat(distinct Column#5 order by Column#6 desc separator \",\")->Column#4", + "└─Projection 10000.00 root cast(test.test.name, var_string(20))->Column#5, test.test.name->Column#6", + " └─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo" + ], + "Result": [ + "500,200,30,20,10" + ] + }, + { + "SQL": "select /*+ agg_to_cop */ group_concat(distinct name order by name desc) from ptest;", + "Plan": [ + "HashAgg 1.00 root funcs:group_concat(distinct Column#5 order by Column#6 desc separator \",\")->Column#4", + "└─Projection 10000.00 root cast(test.ptest.name, var_string(20))->Column#5, test.ptest.name->Column#6", + " └─TableReader 10000.00 root partition:all data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:ptest keep order:false, stats:pseudo" + ], + "Result": [ + "500,200,30,20,10" + ] + } + ] + }, + { + "Name": "TestInlineProjection", + "Cases": [ + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1, t2 where t1.a = t2.a;", + "Plan": "LeftHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)", + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "Plan": "LeftHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)", + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 left outer join t2 on t1.a = t2.a;", + "Plan": "LeftHashJoin{TableReader(Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t1.a,test.t2.a)", + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ HASH_JOIN(t1) */ t1.b, t2.b from t1 right outer join t2 on t1.a = t2.a;", + "Plan": "RightHashJoin{TableReader(Table(t1)->Sel([not(isnull(test.t1.a))]))->TableReader(Table(t2))}(test.t1.a,test.t2.a)", + "Hints": "hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a in (select t2.a from t2) from t1) x;", + "Plan": "LeftHashJoin{IndexReader(Index(t1.idx_a)[[NULL,+inf]])->IndexReader(Index(t2.idx_a)[[NULL,+inf]])}->Projection", + "Hints": "hash_join(@`sel_2` `test`.`t1`), use_index(@`sel_2` `test`.`t1` `idx_a`), no_order_index(@`sel_2` `test`.`t1` `idx_a`), use_index(@`sel_3` `test`.`t2` `idx_a`), no_order_index(@`sel_3` `test`.`t2` `idx_a`)" + }, + { + "SQL": "select 1 from (select /*+ HASH_JOIN(t1) */ t1.a not in (select t2.a from t2) from t1) x;", + "Plan": "LeftHashJoin{IndexReader(Index(t1.idx_a)[[NULL,+inf]])->IndexReader(Index(t2.idx_a)[[NULL,+inf]])}->Projection", + "Hints": "hash_join(@`sel_2` `test`.`t1`), use_index(@`sel_2` `test`.`t1` `idx_a`), no_order_index(@`sel_2` `test`.`t1` `idx_a`), use_index(@`sel_3` `test`.`t2` `idx_a`), no_order_index(@`sel_3` `test`.`t2` `idx_a`)" + }, + { + "SQL": "select /*+ INL_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "Plan": "IndexJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)", + "Hints": "inl_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `idx_a`), no_order_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ INL_HASH_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "Plan": "IndexHashJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)", + "Hints": "inl_hash_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `idx_a`), no_order_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ INL_MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "Plan": "IndexMergeJoin{IndexLookUp(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]), Table(t1))->Projection->TableReader(Table(t2)->Sel([not(isnull(test.t2.a))]))}(test.t2.a,test.t1.a)", + "Hints": "inl_merge_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `idx_a`), order_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` )" + }, + { + "SQL": "select /*+ MERGE_JOIN(t1) */ t1.b, t2.b from t1 inner join t2 on t1.a = t2.a;", + "Plan": "MergeInnerJoin{IndexLookUp(Index(t1.idx_a)[[-inf,+inf]], Table(t1))->Projection->IndexLookUp(Index(t2.idx_a)[[-inf,+inf]], Table(t2))->Projection}(test.t1.a,test.t2.a)", + "Hints": "merge_join(@`sel_1` `test`.`t1`), use_index(@`sel_1` `test`.`t1` `idx_a`), order_index(@`sel_1` `test`.`t1` `idx_a`), use_index(@`sel_1` `test`.`t2` `idx_a`), order_index(@`sel_1` `test`.`t2` `idx_a`)" + } + ] + }, + { + "Name": "TestHintFromDiffDatabase", + "Cases": [ + { + "SQL": "select /*+ inl_hash_join(test.t1) */ * from test.t2 join test.t1 on test.t2.a = test.t1.a", + "Plan": "IndexHashJoin{IndexReader(Index(t2.idx_a)[[-inf,+inf]])->IndexReader(Index(t1.idx_a)[[NULL,NULL]]->Sel([not(isnull(test.t1.a))]))}(test.t2.a,test.t1.a)" + } + ] + }, + { + "Name": "TestMPPSinglePartitionType", + "Cases": [ + { + "SQL": "select * from employee where deptid>1", + "Plan": [ + "TableReader 3333.33 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 3333.33 mpp[tiflash] gt(test.employee.deptid, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select deptid+5, empid*10 from employee where deptid>1", + "Plan": [ + "TableReader 3333.33 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3333.33 mpp[tiflash] plus(test.employee.deptid, 5)->Column#5, mul(test.employee.empid, 10)->Column#6", + " └─Selection 3333.33 mpp[tiflash] gt(test.employee.deptid, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select count(*) from employee group by deptid+1", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] Column#5", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#12, funcs:sum(Column#13)->Column#5", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#12, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#14, funcs:count(1)->Column#13", + " └─Projection 10000.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#14", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select count(distinct deptid) a from employee", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#5", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#7)->Column#5", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#7", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee join employee e1 using(deptid)", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12487.50 mpp[tiflash] test.employee.deptid, test.employee.empid, test.employee.salary, test.employee.empid, test.employee.salary", + " └─Projection 12487.50 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, test.employee.empid, test.employee.salary", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, test.employee.deptid)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select count(distinct a) from (select count(distinct deptid) a from employee) x", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#6", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct Column#5)->Column#6", + " └─Projection 1.00 mpp[tiflash] Column#5", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#8)->Column#5", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#8", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select count(a) from (select count(distinct deptid) a, count(distinct empid) b from employee) x group by b+1", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#7", + " └─HashAgg 1.00 mpp[tiflash] group by:Column#12, funcs:sum(Column#13)->Column#7", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#12, collate: binary]", + " └─HashAgg 1.00 mpp[tiflash] group by:Column#15, funcs:count(Column#14)->Column#13", + " └─Projection 1.00 mpp[tiflash] Column#5->Column#14, plus(Column#6, 1)->Column#15", + " └─Projection 1.00 mpp[tiflash] Column#5, Column#6", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#5, funcs:count(distinct test.employee.empid)->Column#6", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, test.employee.empid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select count(a) from (select count(distinct deptid) a, count(distinct empid) b from employee) x group by b", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#7", + " └─HashAgg 1.00 mpp[tiflash] group by:Column#6, funcs:count(Column#5)->Column#7", + " └─Projection 1.00 mpp[tiflash] Column#5, Column#6", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#5, funcs:count(distinct test.employee.empid)->Column#6", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, test.employee.empid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee join (select count(distinct deptid) a, count(distinct empid) b from employee) e1", + "Plan": [ + "TableReader 10000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 10000.00 mpp[tiflash] CARTESIAN inner join", + " ├─ExchangeReceiver(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 1.00 mpp[tiflash] Column#9, Column#10", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#9, funcs:count(distinct test.employee.empid)->Column#10", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " │ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, test.employee.empid, ", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee e1 join (select count(distinct deptid) a from employee) e2 on e1.deptid = e2.a", + "Plan": [ + "TableReader 1.25 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.25 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 1.25 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#9)]", + " ├─ExchangeReceiver(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 1.00 mpp[tiflash] Column#9", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#10)->Column#9", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#10", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " │ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select count(distinct deptid) a from employee) e1 join employee e2 on e1.a = e2.deptid", + "Plan": [ + "TableReader 1.25 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.25 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.25 mpp[tiflash] Column#5, test.employee.empid, test.employee.deptid, test.employee.salary", + " └─HashJoin 1.25 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#5)]", + " ├─ExchangeReceiver(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 1.00 mpp[tiflash] Column#5", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#10)->Column#5", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#10", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " │ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select count(distinct deptid) a from employee) e1 join (select count(distinct deptid) b from employee) e2 on e1.a=e2.b", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 1.00 mpp[tiflash] inner join, equal:[eq(Column#5, Column#10)]", + " ├─ExchangeReceiver(Build) 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 1.00 mpp[tiflash] Column#5", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#11)->Column#5", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#11", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " │ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Projection(Probe) 1.00 mpp[tiflash] Column#10", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#12)->Column#10", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#12", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee e1 join employee e2 on e1.deptid = e2.deptid", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, test.employee.deptid)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join employee e2 on e1.d = e2.deptid", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] Column#6, Column#5, test.employee.empid, test.employee.deptid, test.employee.salary", + " └─HashJoin 8000.00 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#6)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#6, Column#5", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#5, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, funcs:sum(Column#14)->Column#5, funcs:firstrow(Column#15)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#13, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#27, funcs:count(Column#25)->Column#14, funcs:firstrow(Column#26)->Column#15", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#25, test.employee.deptid->Column#26, plus(test.employee.deptid, 1)->Column#27", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.deptid = e2.d", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 8000.00 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#10)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#10, Column#9", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#9, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, funcs:sum(Column#14)->Column#9, funcs:firstrow(Column#15)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#13, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#27, funcs:count(Column#25)->Column#14, funcs:firstrow(Column#26)->Column#15", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#25, test.employee.deptid->Column#26, plus(test.employee.deptid, 1)->Column#27", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.d = e2.d", + "Plan": [ + "TableReader 6400.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 6400.00 mpp[tiflash] inner join, equal:[eq(Column#6, Column#12)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#6, Column#5", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#5, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#17, funcs:sum(Column#18)->Column#5, funcs:firstrow(Column#19)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#17, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#43, funcs:count(Column#41)->Column#18, funcs:firstrow(Column#42)->Column#19", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#41, test.employee.deptid->Column#42, plus(test.employee.deptid, 1)->Column#43", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─Projection(Probe) 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#12, Column#11", + " └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " └─Projection 8000.00 mpp[tiflash] Column#11, test.employee.deptid", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#20, funcs:sum(Column#21)->Column#11, funcs:firstrow(Column#22)->test.employee.deptid", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#20, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#46, funcs:count(Column#44)->Column#21, funcs:firstrow(Column#45)->Column#22", + " └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#44, test.employee.deptid->Column#45, plus(test.employee.deptid, 1)->Column#46", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "set tidb_broadcast_join_threshold_count=1", + "Plan": null + }, + { + "SQL": "set tidb_broadcast_join_threshold_size=1", + "Plan": null + }, + { + "SQL": "select * from (select count(distinct deptid) a from employee) e1 join employee e2 on e1.a = e2.deptid", + "Plan": [ + "Projection 1.25 root Column#5, test.employee.empid, test.employee.deptid, test.employee.salary", + "└─HashJoin 1.25 root inner join, equal:[eq(test.employee.deptid, Column#5)]", + " ├─TableReader(Build) 1.00 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " │ └─Projection 1.00 mpp[tiflash] Column#5", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#12)->Column#5", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#12", + " │ └─ExchangeReceiver 1.00 mpp[tiflash] ", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " │ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select count(distinct deptid) a from employee) e1 join (select count(distinct deptid) b from employee) e2 on e1.a=e2.b", + "Plan": [ + "HashJoin 1.00 root inner join, equal:[eq(Column#5, Column#10)]", + "├─TableReader(Build) 1.00 root MppVersion: 2, data:ExchangeSender", + "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + "│ └─Projection 1.00 mpp[tiflash] Column#10", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#16)->Column#10", + "│ └─ExchangeReceiver 1.00 mpp[tiflash] ", + "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#16", + "│ └─ExchangeReceiver 1.00 mpp[tiflash] ", + "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + "│ └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + "│ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + "└─TableReader(Probe) 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#5", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#15)->Column#5", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct test.employee.deptid)->Column#15", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg 1.00 mpp[tiflash] group by:test.employee.deptid, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee e1 join employee e2 on e1.deptid = e2.deptid", + "Plan": [ + "TableReader 12487.50 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, test.employee.deptid)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join employee e2 on e1.d = e2.deptid", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] Column#6, Column#5, test.employee.empid, test.employee.deptid, test.employee.salary", + " └─Projection 8000.00 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, Column#6, Column#5, Column#26", + " └─HashJoin 8000.00 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#6)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#6, collate: binary]", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#6, Column#5", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#5, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, funcs:sum(Column#14)->Column#5, funcs:firstrow(Column#15)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#13, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#29, funcs:count(Column#27)->Column#14, funcs:firstrow(Column#28)->Column#15", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#27, test.employee.deptid->Column#28, plus(test.employee.deptid, 1)->Column#29", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#26, collate: binary]", + " └─Projection 9990.00 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, cast(test.employee.deptid, bigint(20))->Column#26", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e2 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from employee e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.deptid = e2.d", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, Column#10, Column#9", + " └─Projection 8000.00 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, Column#10, Column#9, Column#26", + " └─HashJoin 8000.00 mpp[tiflash] inner join, equal:[eq(test.employee.deptid, Column#10)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#10, collate: binary]", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#10, Column#9", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#9, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, funcs:sum(Column#14)->Column#9, funcs:firstrow(Column#15)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#13, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#29, funcs:count(Column#27)->Column#14, funcs:firstrow(Column#28)->Column#15", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#27, test.employee.deptid->Column#28, plus(test.employee.deptid, 1)->Column#29", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#26, collate: binary]", + " └─Projection 9990.00 mpp[tiflash] test.employee.empid, test.employee.deptid, test.employee.salary, cast(test.employee.deptid, bigint(20))->Column#26", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.employee.deptid))", + " └─TableFullScan 10000.00 mpp[tiflash] table:e1 pushed down filter:empty, keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from (select deptid+1 d, count(empid) a from employee group by d) e1 join (select deptid+1 d, count(empid) a from employee group by d) e2 on e1.d = e2.d", + "Plan": [ + "TableReader 6400.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 6400.00 mpp[tiflash] inner join, equal:[eq(Column#6, Column#12)]", + " ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash] ", + " │ └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#6, collate: binary]", + " │ └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#6, Column#5", + " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " │ └─Projection 8000.00 mpp[tiflash] Column#5, test.employee.deptid", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#17, funcs:sum(Column#18)->Column#5, funcs:firstrow(Column#19)->test.employee.deptid", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#17, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:Column#43, funcs:count(Column#41)->Column#18, funcs:firstrow(Column#42)->Column#19", + " │ └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#41, test.employee.deptid->Column#42, plus(test.employee.deptid, 1)->Column#43", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 6400.00 mpp[tiflash] ", + " └─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#12, collate: binary]", + " └─Projection 6400.00 mpp[tiflash] plus(test.employee.deptid, 1)->Column#12, Column#11", + " └─Selection 6400.00 mpp[tiflash] not(isnull(plus(test.employee.deptid, 1)))", + " └─Projection 8000.00 mpp[tiflash] Column#11, test.employee.deptid", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#20, funcs:sum(Column#21)->Column#11, funcs:firstrow(Column#22)->test.employee.deptid", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#20, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#46, funcs:count(Column#44)->Column#21, funcs:firstrow(Column#45)->Column#22", + " └─Projection 10000.00 mpp[tiflash] test.employee.empid->Column#44, test.employee.deptid->Column#45, plus(test.employee.deptid, 1)->Column#46", + " └─TableFullScan 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestSemiJoinRewriteHints", + "Cases": [ + { + "SQL": "select /*+ SEMI_JOIN_REWRITE() */ * from t", + "Plan": [ + "TableReader 10000.00 root data:TableFullScan", + "└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "[planner:1815]The SEMI_JOIN_REWRITE hint is not used correctly, maybe it's not in a subquery or the subquery is not EXISTS clause." + }, + { + "SQL": "select * from t where a > (select /*+ SEMI_JOIN_REWRITE() */ min(b) from t t1 where t1.c = t.c)", + "Plan": [ + "HashJoin 7992.00 root inner join, equal:[eq(test.t.c, test.t.c)], other cond:gt(test.t.a, Column#9)", + "├─Selection(Build) 6393.60 root not(isnull(Column#9))", + "│ └─HashAgg 7992.00 root group by:test.t.c, funcs:min(Column#10)->Column#9, funcs:firstrow(test.t.c)->test.t.c", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t.c, funcs:min(test.t.b)->Column#10", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.c))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.c))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "[planner:1815]The SEMI_JOIN_REWRITE hint is not used correctly, maybe it's not in a subquery or the subquery is not EXISTS clause." + }, + { + "SQL": "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 where t1.a=t.a)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, test.t.a)]", + "├─HashAgg(Build) 7992.00 root group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t.a, ", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "" + }, + { + "SQL": "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ t.b from t t1 where t1.a=t.a)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, test.t.a)]", + "├─HashAgg(Build) 7992.00 root group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t.a, ", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "" + }, + { + "SQL": "select exists(select /*+ SEMI_JOIN_REWRITE() */ * from t t1 where t1.a=t.a) from t", + "Plan": [ + "HashJoin 10000.00 root left outer semi join, equal:[eq(test.t.a, test.t.a)]", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "[planner:1815]SEMI_JOIN_REWRITE() is inapplicable for LeftOuterSemiJoin." + }, + { + "SQL": "select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 where t1.a > t.a)", + "Plan": [ + "HashJoin 7992.00 root CARTESIAN semi join, other cond:gt(test.t.a, test.t.a)", + "├─TableReader(Build) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": "[planner:1815]SEMI_JOIN_REWRITE() is inapplicable for SemiJoin with left conditions or other conditions." + } + ] + }, + { + "Name": "TestHJBuildAndProbeHint4DynamicPartitionTable", + "Cases": [ + { + "SQL": "select /*+ hash_join_build(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "HashJoin 12475.01 root inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + "├─TableReader(Build) 9980.01 root partition:all data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_probe(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "HashJoin 12475.01 root inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + "├─TableReader(Build) 9980.01 root partition:all data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_build(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "HashJoin 12475.01 root inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + "├─TableReader(Build) 9980.01 root partition:all data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_probe(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "HashJoin 12475.01 root inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + "├─TableReader(Build) 9980.01 root partition:all data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ], + "Warning": null + } + ] + }, + { + "Name": "TestHJBuildAndProbeHint4TiFlash", + "Cases": [ + { + "SQL": "select /*+ hash_join_build(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "TableReader 12500.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t1.a, test.t2.a", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_probe(t2) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "TableReader 12500.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t1.a, test.t2.a", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_build(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "TableReader 12500.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t1.a, test.t2.a", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ hash_join_probe(t1) */ t1.a, t2.a from t1 join t2 on t1.a=t2.a and t1.b=t2.b", + "Plan": [ + "TableReader 12500.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t1.a, test.t2.a", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + }, + { + "Name": "TestCountStarForTiFlash", + "Cases": [ + { + "SQL": "select count(*) from t", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#12)->Column#10", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#12", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(3.1415), count(0), count(null) from t -- every count but count(null) can be rewritten", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#18)->Column#10, funcs:count(Column#19)->Column#11, funcs:count(Column#20)->Column#12, funcs:count(Column#21)->Column#13", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#18, funcs:count(test.t.d)->Column#19, funcs:count(test.t.d)->Column#20, funcs:count(NULL)->Column#21", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t where a=1", + "Plan": [ + "StreamAgg 1.00 root funcs:count(1)->Column#10", + "└─TableReader 10.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 10.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 10.00 mpp[tiflash] eq(test.t.a, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t_pick_row_id", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#5)->Column#3", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t_pick_row_id._tidb_rowid)->Column#5", + " └─TableFullScan 10000.00 mpp[tiflash] table:t_pick_row_id keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- test recursive", + "Plan": [ + "HashJoin 1.25 root inner join, equal:[eq(test.t.a, Column#10)]", + "├─HashAgg(Build) 1.00 root funcs:count(Column#22)->Column#10", + "│ └─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#22", + "│ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from t outTable where outTable.a > (select count(*) from t inn where inn.a = outTable.b) -- shouldn't be rewritten for correlated sub query", + "Plan": [ + "Projection 10000.00 root test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.f, test.t.g, test.t.h", + "└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(test.t.a, Column#19)", + " ├─TableReader(Build) 10000.00 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:outTable keep order:false, stats:pseudo", + " └─HashAgg(Probe) 10000.00 root funcs:count(Column#21)->Column#19", + " └─TableReader 10000.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 10000.00 mpp[tiflash] funcs:count(1)->Column#21", + " └─Selection 80000000.00 mpp[tiflash] eq(cast(test.t.a, double BINARY), cast(test.t.b, double BINARY))", + " └─TableFullScan 100000000.00 mpp[tiflash] table:inn pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten when join under agg", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#22)->Column#19", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#22", + " └─Projection 12500.00 mpp[tiflash] 1->Column#21", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.e)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(distinct 1) from t -- shouldn't be rewritten", + "Plan": [ + "TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#10", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct Column#12)->Column#10", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough, Compression: FAST", + " └─HashAgg 1.00 mpp[tiflash] group by:1, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(a), count(b) from t -- keep count(1)", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#16)->Column#10, funcs:count(Column#17)->Column#11, funcs:count(Column#18)->Column#12", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#16, funcs:count(test.t.a)->Column#17, funcs:count(test.t.b)->Column#18", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select a, count(*) from t group by a -- shouldn't be rewritten", + "Plan": [ + "TableReader 8000.00 root MppVersion: 2, data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#10", + " └─Projection 8000.00 mpp[tiflash] Column#10, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, funcs:count(1)->Column#10, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select sum(a) from t -- sum shouldn't be rewritten", + "Plan": [ + "HashAgg 1.00 root funcs:sum(Column#12)->Column#10", + "└─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#15)->Column#12", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#15", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + }, + { + "Name": "TestHashAggPushdownToTiFlashCompute", + "Cases": [ + { + "SQL": "select /*+ agg_to_cop() hash_agg() */ avg( distinct tbl_15.col_96 ) as r0 , min( tbl_15.col_92 ) as r1 , sum( distinct tbl_15.col_91 ) as r2 , max( tbl_15.col_92 ) as r3 from tbl_15 where tbl_15.col_94 != '2033-01-09' and tbl_15.col_93 > 7623.679908049186 order by r0,r1,r2,r3 limit 79 ;", + "Plan": [ + "Limit 1.00 root offset:0, count:79", + "└─Sort 1.00 root Column#11, Column#12, Column#13, Column#14", + " └─HashAgg 1.00 root funcs:avg(distinct Column#89)->Column#11, funcs:min(Column#90)->Column#12, funcs:sum(distinct Column#91)->Column#13, funcs:max(Column#92)->Column#14", + " └─Projection 7100.44 root cast(test.tbl_15.col_96, decimal(10,0) UNSIGNED BINARY)->Column#89, Column#15->Column#90, cast(test.tbl_15.col_91, decimal(3,0) UNSIGNED BINARY)->Column#91, Column#16->Column#92", + " └─PartitionUnion 7100.44 root ", + " ├─TableReader 1775.11 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:min(Column#18)->Column#15, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91, funcs:max(Column#20)->Column#16, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91", + " │ └─ExchangeReceiver 1775.11 mpp[tiflash] ", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.tbl_15.col_96, collate: binary], [name: test.tbl_15.col_91, collate: binary]", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:min(test.tbl_15.col_92)->Column#18, funcs:max(test.tbl_15.col_92)->Column#20", + " │ └─Selection 2218.89 mpp[tiflash] gt(test.tbl_15.col_93, 7623.679908049186), ne(test.tbl_15.col_94, 2033-01-09 00:00:00.000000)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p0 pushed down filter:empty, keep order:false, stats:pseudo", + " ├─TableReader 1775.11 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:min(Column#30)->Column#15, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91, funcs:max(Column#32)->Column#16, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91", + " │ └─ExchangeReceiver 1775.11 mpp[tiflash] ", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.tbl_15.col_96, collate: binary], [name: test.tbl_15.col_91, collate: binary]", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:min(test.tbl_15.col_92)->Column#30, funcs:max(test.tbl_15.col_92)->Column#32", + " │ └─Selection 2218.89 mpp[tiflash] gt(test.tbl_15.col_93, 7623.679908049186), ne(test.tbl_15.col_94, 2033-01-09 00:00:00.000000)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p1 pushed down filter:empty, keep order:false, stats:pseudo", + " ├─TableReader 1775.11 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:min(Column#42)->Column#15, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91, funcs:max(Column#44)->Column#16, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91", + " │ └─ExchangeReceiver 1775.11 mpp[tiflash] ", + " │ └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.tbl_15.col_96, collate: binary], [name: test.tbl_15.col_91, collate: binary]", + " │ └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:min(test.tbl_15.col_92)->Column#42, funcs:max(test.tbl_15.col_92)->Column#44", + " │ └─Selection 2218.89 mpp[tiflash] gt(test.tbl_15.col_93, 7623.679908049186), ne(test.tbl_15.col_94, 2033-01-09 00:00:00.000000)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p2 pushed down filter:empty, keep order:false, stats:pseudo", + " └─TableReader 1775.11 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:min(Column#54)->Column#15, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91, funcs:max(Column#56)->Column#16, funcs:firstrow(test.tbl_15.col_96)->test.tbl_15.col_96, funcs:firstrow(test.tbl_15.col_91)->test.tbl_15.col_91", + " └─ExchangeReceiver 1775.11 mpp[tiflash] ", + " └─ExchangeSender 1775.11 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.tbl_15.col_96, collate: binary], [name: test.tbl_15.col_91, collate: binary]", + " └─HashAgg 1775.11 mpp[tiflash] group by:test.tbl_15.col_91, test.tbl_15.col_96, funcs:min(test.tbl_15.col_92)->Column#54, funcs:max(test.tbl_15.col_92)->Column#56", + " └─Selection 2218.89 mpp[tiflash] gt(test.tbl_15.col_93, 7623.679908049186), ne(test.tbl_15.col_94, 2033-01-09 00:00:00.000000)", + " └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p3 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ agg_to_cop() hash_agg() */ count(1) from tbl_15 ;", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#12)->Column#11", + "└─PartitionUnion 4.00 root ", + " ├─HashAgg 1.00 root funcs:count(Column#13)->Column#12", + " │ └─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.tbl_15.col_91)->Column#13", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p0 keep order:false, stats:pseudo", + " ├─HashAgg 1.00 root funcs:count(Column#14)->Column#12", + " │ └─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.tbl_15.col_91)->Column#14", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p1 keep order:false, stats:pseudo", + " ├─HashAgg 1.00 root funcs:count(Column#15)->Column#12", + " │ └─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " │ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.tbl_15.col_91)->Column#15", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p2 keep order:false, stats:pseudo", + " └─HashAgg 1.00 root funcs:count(Column#16)->Column#12", + " └─TableReader 1.00 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.tbl_15.col_91)->Column#16", + " └─TableFullScan 10000.00 mpp[tiflash] table:tbl_15, partition:p3 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select /*+ agg_to_cop() stream_agg() */ avg( tbl_16.col_100 ) as r0 from tbl_16 where tbl_16.col_100 in ( 10672141 ) or tbl_16.col_104 in ( 'yfEG1t!*b' ,'C1*bqx_qyO' ,'vQ^yUpKHr&j#~' ) group by tbl_16.col_100 order by r0 limit 20 ;", + "Plan": [ + "TopN 20.00 root Column#10, offset:0, count:20", + "└─HashAgg 63.95 root group by:test.tbl_16.col_100, funcs:avg(Column#11, Column#12)->Column#10", + " └─PartitionUnion 63.95 root ", + " ├─StreamAgg 31.98 root group by:Column#22, funcs:count(Column#19)->Column#11, funcs:sum(Column#20)->Column#12, funcs:firstrow(Column#21)->test.tbl_16.col_100", + " │ └─Projection 39.97 root test.tbl_16.col_100->Column#19, cast(test.tbl_16.col_100, decimal(8,0) UNSIGNED BINARY)->Column#20, test.tbl_16.col_100->Column#21, test.tbl_16.col_100->Column#22", + " │ └─Sort 39.97 root test.tbl_16.col_100", + " │ └─TableReader 39.97 root MppVersion: 2, data:ExchangeSender", + " │ └─ExchangeSender 39.97 mpp[tiflash] ExchangeType: PassThrough", + " │ └─Selection 39.97 mpp[tiflash] or(eq(test.tbl_16.col_100, 10672141), in(test.tbl_16.col_104, \"yfEG1t!*b\", \"C1*bqx_qyO\", \"vQ^yUpKHr&j#~\"))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:tbl_16, partition:p0 pushed down filter:empty, keep order:false, stats:pseudo", + " └─StreamAgg 31.98 root group by:Column#26, funcs:count(Column#23)->Column#11, funcs:sum(Column#24)->Column#12, funcs:firstrow(Column#25)->test.tbl_16.col_100", + " └─Projection 39.97 root test.tbl_16.col_100->Column#23, cast(test.tbl_16.col_100, decimal(8,0) UNSIGNED BINARY)->Column#24, test.tbl_16.col_100->Column#25, test.tbl_16.col_100->Column#26", + " └─Sort 39.97 root test.tbl_16.col_100", + " └─TableReader 39.97 root MppVersion: 2, data:ExchangeSender", + " └─ExchangeSender 39.97 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 39.97 mpp[tiflash] or(eq(test.tbl_16.col_100, 10672141), in(test.tbl_16.col_104, \"yfEG1t!*b\", \"C1*bqx_qyO\", \"vQ^yUpKHr&j#~\"))", + " └─TableFullScan 10000.00 mpp[tiflash] table:tbl_16, partition:p1 pushed down filter:empty, keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + }, + { + "Name": "TestIssues49377Plan", + "Cases": [ + { + "SQL": "select 1,1,1 union all ((select * from employee where dept_id = 1) union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 );", + "Plan": [ + "Union 21.00 root ", + "├─Projection 1.00 root 1->Column#15, 1->Column#16, 1->Column#17", + "│ └─TableDual 1.00 root rows:1", + "└─Projection 20.00 root cast(Column#12, bigint(11) BINARY)->Column#15, Column#13->Column#16, cast(Column#14, bigint(11) BINARY)->Column#17", + " └─Sort 20.00 root Column#12", + " └─Union 20.00 root ", + " ├─TableReader 10.00 root data:Selection", + " │ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " │ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + " └─Sort 10.00 root test.employee.employee_id", + " └─TableReader 10.00 root data:Selection", + " └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select 1,1,1 union all ((select * from employee where dept_id = 1) union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 limit 1);", + "Plan": [ + "Union 2.00 root ", + "├─Projection 1.00 root 1->Column#15, 1->Column#16, 1->Column#17", + "│ └─TableDual 1.00 root rows:1", + "└─Projection 1.00 root cast(Column#12, bigint(11) BINARY)->Column#15, Column#13->Column#16, cast(Column#14, bigint(11) BINARY)->Column#17", + " └─TopN 1.00 root Column#12, offset:0, count:1", + " └─Union 2.00 root ", + " ├─TopN 1.00 root test.employee.employee_id, offset:0, count:1", + " │ └─TableReader 1.00 root data:TopN", + " │ └─TopN 1.00 cop[tikv] test.employee.employee_id, offset:0, count:1", + " │ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " │ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + " └─TopN 1.00 root test.employee.employee_id, offset:0, count:1", + " └─TableReader 1.00 root data:TopN", + " └─TopN 1.00 cop[tikv] test.employee.employee_id, offset:0, count:1", + " └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id) union all ( select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id ) limit 1);", + "Plan": [ + "Union 21.00 root ", + "├─TableReader 10.00 root data:Selection", + "│ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + "│ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + "├─Sort 10.00 root test.employee.employee_id", + "│ └─TableReader 10.00 root data:Selection", + "│ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + "│ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + "└─Limit 1.00 root offset:0, count:1", + " └─Union 1.00 root ", + " ├─Limit 1.00 root offset:0, count:1", + " │ └─TableReader 1.00 root data:Limit", + " │ └─Limit 1.00 cop[tikv] offset:0, count:1", + " │ └─Selection 1.00 cop[tikv] eq(test.employee.dept_id, 1)", + " │ └─TableFullScan 1000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + " └─TopN 1.00 root test.employee.employee_id, offset:0, count:1", + " └─TableReader 1.00 root data:TopN", + " └─TopN 1.00 cop[tikv] test.employee.employee_id, offset:0, count:1", + " └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id) union all ( select * from employee where dept_id = 1 union all ( select * from employee where dept_id = 1 order by employee_id ) order by 1 limit 1);", + "Plan": [ + "Union 21.00 root ", + "├─TableReader 10.00 root data:Selection", + "│ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + "│ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + "├─Sort 10.00 root test.employee.employee_id", + "│ └─TableReader 10.00 root data:Selection", + "│ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + "│ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + "└─TopN 1.00 root Column#17, offset:0, count:1", + " └─Union 2.00 root ", + " ├─TopN 1.00 root test.employee.employee_id, offset:0, count:1", + " │ └─TableReader 1.00 root data:TopN", + " │ └─TopN 1.00 cop[tikv] test.employee.employee_id, offset:0, count:1", + " │ └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " │ └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo", + " └─TopN 1.00 root test.employee.employee_id, offset:0, count:1", + " └─TableReader 1.00 root data:TopN", + " └─TopN 1.00 cop[tikv] test.employee.employee_id, offset:0, count:1", + " └─Selection 10.00 cop[tikv] eq(test.employee.dept_id, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:employee keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + }, + { + "Name": "TestPointgetIndexChoosen", + "Cases": [ + { + "SQL": "select * from t where b=1 and c='1';", + "Plan": [ + "Point_Get 1.00 root table:t, index:ubc(b, c) " + ], + "Warning": null + }, + { + "SQL": "select * from t where b=1 and c='1' and d='1';", + "Plan": [ + "Selection 0.00 root eq(test.t.d, \"1\")", + "└─Point_Get 1.00 root table:t, index:ubc(b, c) " + ], + "Warning": null + }, + { + "SQL": "select * from t where b in (1,2,3) and c in ('1');", + "Plan": [ + "Batch_Point_Get 3.00 root table:t, index:ubc(b, c) keep order:false, desc:false" + ], + "Warning": null + } + ] + }, + { + "Name": "TestAlwaysTruePredicateWithSubquery", + "Cases": [ + { + "SQL": "SHOW ERRORS WHERE TRUE = ALL ( SELECT TRUE GROUP BY 1 LIMIT 1 ) IS NULL IS NOT NULL;", + "Plan": null, + "Warning": null + }, + { + "SQL": "explain select * from t WHERE TRUE = ALL ( SELECT TRUE GROUP BY 1 LIMIT 1 ) IS NULL IS NOT NULL;", + "Plan": [ + "HashJoin_14 10000.00 root CARTESIAN inner join", + "├─StreamAgg_19(Build) 1.00 root funcs:count(1)->Column#13", + "│ └─Limit_22 1.00 root offset:0, count:1", + "│ └─HashAgg_23 1.00 root group by:1, ", + "│ └─TableDual_24 1.00 root rows:1", + "└─TableReader_17(Probe) 10000.00 root data:TableFullScan_16", + " └─TableFullScan_16 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "explain select * from t WHERE TRUE = ALL ( SELECT TRUE from t GROUP BY 1 LIMIT 1 ) is null is not null;", + "Plan": [ + "HashJoin_14 10000.00 root CARTESIAN inner join", + "├─StreamAgg_19(Build) 1.00 root funcs:count(1)->Column#16", + "│ └─Limit_22 1.00 root offset:0, count:1", + "│ └─HashAgg_27 1.00 root group by:Column#17, funcs:firstrow(Column#18)->test.t.a, funcs:firstrow(Column#19)->test.t.b, funcs:firstrow(Column#20)->test.t._tidb_rowid", + "│ └─TableReader_28 1.00 root data:HashAgg_23", + "│ └─HashAgg_23 1.00 cop[tikv] group by:1, funcs:firstrow(test.t.a)->Column#18, funcs:firstrow(test.t.b)->Column#19, funcs:firstrow(test.t._tidb_rowid)->Column#20", + "│ └─TableFullScan_26 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader_17(Probe) 10000.00 root data:TableFullScan_16", + " └─TableFullScan_16 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + } +] diff --git a/planner/core/casetest/physical_plan_test.go b/planner/core/casetest/physical_plan_test.go index a2687afb4cb75..7186ded568f67 100644 --- a/planner/core/casetest/physical_plan_test.go +++ b/planner/core/casetest/physical_plan_test.go @@ -2570,10 +2570,12 @@ func TestConstantPropagateWithCollation(t *testing.T) { Plan []string Warning []string } + planSuiteData := GetPlanSuiteData() planSuiteData.LoadTestCases(t, &input, &output) store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + // create table tk.MustExec("use test") tk.MustExec("create table t (id int primary key, name varchar(20));") @@ -2593,3 +2595,28 @@ func TestConstantPropagateWithCollation(t *testing.T) { tk.MustQuery("show warnings").Check(testkit.Rows(output[i].Warning...)) } } + +// Test issue #46962 plan +func TestAlwaysTruePredicateWithSubquery(t *testing.T) { + var ( + input []string + output []struct { + SQL string + Plan []string + Warning []string + } + ) + planSuiteData := GetPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`CREATE TABLE t ( a int NOT NULL , b int NOT NULL ) `) + for i, ts := range input { + testdata.OnRecord(func() { + output[i].SQL = ts + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(ts).Rows()) + }) + tk.MustQuery(ts).Check(testkit.Rows(output[i].Plan...)) + } +} diff --git a/planner/core/rule_build_key_info.go b/planner/core/rule_build_key_info.go index 5b2f5c4ad4580..abfeb7935d05b 100644 --- a/planner/core/rule_build_key_info.go +++ b/planner/core/rule_build_key_info.go @@ -44,7 +44,11 @@ func buildKeyInfo(lp LogicalPlan) { // BuildKeyInfo implements LogicalPlan BuildKeyInfo interface. func (la *LogicalAggregation) BuildKeyInfo(selfSchema *expression.Schema, childSchema []*expression.Schema) { - if la.IsPartialModeAgg() { + // According to the issue#46962, we can ignore the judgment of partial agg + // Sometimes, the agg inside of subquery and there is a true condition in where clause, the agg function is empty. + // For example, ``` select xxxx from xxx WHERE TRUE = ALL ( SELECT TRUE GROUP BY 1 LIMIT 1 ) IS NULL IS NOT NULL; + // In this case, the agg is complete mode and we can ignore this check. + if len(la.AggFuncs) != 0 && la.IsPartialModeAgg() { return } la.logicalSchemaProducer.BuildKeyInfo(selfSchema, childSchema)