[
  {
    "Name": "TestPushLimitDownIndexLookUpReader",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 limit 2,1",
        "Plan": [
          "IndexLookUp 1.00 root  limit embedded(offset:2, count:1)",
          "├─Limit(Build) 3.00 cop[tikv]  offset:0, count:3",
          "│ └─IndexRangeScan 3.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:false",
          "└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 order by b desc limit 2,1",
        "Plan": [
          "Limit 1.00 root  offset:2, count:1",
          "└─Projection 3.00 root  test.tbl.a, test.tbl.b, test.tbl.c",
          "  └─IndexLookUp 3.00 root  ",
          "    ├─Limit(Build) 3.00 cop[tikv]  offset:0, count:3",
          "    │ └─IndexRangeScan 3.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:true, desc",
          "    └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tbl keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 and c > 1 limit 2,1",
        "Plan": [
          "IndexLookUp 1.00 root  limit embedded(offset:2, count:1)",
          "├─Limit(Build) 3.00 cop[tikv]  offset:0, count:3",
          "│ └─Selection 3.00 cop[tikv]  gt(test.tbl.c, 1)",
          "│   └─IndexRangeScan 3.75 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:false",
          "└─TableRowIDScan(Probe) 1.00 cop[tikv] table:tbl keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 and a > 1 limit 2,1",
        "Plan": [
          "Limit 1.00 root  offset:2, count:1",
          "└─IndexLookUp 3.00 root  ",
          "  ├─IndexRangeScan(Build) 3.75 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:false",
          "  └─Limit(Probe) 3.00 cop[tikv]  offset:0, count:3",
          "    └─Selection 3.00 cop[tikv]  gt(test.tbl.a, 1)",
          "      └─TableRowIDScan 3.75 cop[tikv] table:tbl keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestIsFromUnixtimeNullRejective",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t t1 left join t t2 on t1.a=t2.a where from_unixtime(t2.b);",
        "Plan": [
          "Projection 9990.00 root  test.t.a, test.t.b, test.t.a, test.t.b",
          "└─HashJoin 9990.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "  ├─Selection(Build) 7992.00 root  from_unixtime(cast(test.t.b, decimal(20,0) BINARY))",
          "  │ └─TableReader 9990.00 root  data:Selection",
          "  │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t.a))",
          "  │     └─TableFullScan 10000.00 cop[tikv] table:t2 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:t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestAggColumnPrune",
    "Cases": [
      {
        "SQL": "select count(1) from t join (select count(1) from t where false) as tmp",
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select count(1) from t join (select max(a) from t where false) as tmp",
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select count(1) from t join (select min(a) from t where false) as tmp",
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select count(1) from t join (select sum(a) from t where false) as tmp",
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select count(1) from t join (select avg(a) from t where false) as tmp",
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select count(1) from t join (select count(1) from t where false group by a) as tmp",
        "Res": [
          "0"
        ]
      },
      {
        "SQL": "select count(1) from t join (select max(a) from t where false group by a) as tmp",
        "Res": [
          "0"
        ]
      },
      {
        "SQL": "select count(1) from t join (select min(a) from t where false group by a) as tmp",
        "Res": [
          "0"
        ]
      },
      {
        "SQL": "select count(1) from t join (select sum(a) from t where false group by a) as tmp",
        "Res": [
          "0"
        ]
      },
      {
        "SQL": "select count(1) from t join (select avg(a) from t where false group by a) as tmp",
        "Res": [
          "0"
        ]
      },
      {
        "SQL": "SELECT avg(2) FROM(SELECT min(c) FROM t JOIN(SELECT 1 c) d ORDER BY a) e",
        "Res": [
          "2.0000"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexJoinInnerIndexNDV",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ inl_join(t2) */ * from t1, t2 where t1.a = t2.a and t1.b = t2.b and t1.c = t2.c",
        "Plan": [
          "IndexJoin 3.00 root  inner join, inner:IndexLookUp, outer key:test.t1.c, inner key:test.t2.c, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b), eq(test.t1.c, test.t2.c)",
          "├─TableReader(Build) 3.00 root  data:TableFullScan",
          "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─IndexLookUp(Probe) 3.00 root  ",
          "  ├─IndexRangeScan(Build) 3.00 cop[tikv] table:t2, index:idx2(c) range: decided by [eq(test.t2.c, test.t1.c)], keep order:false",
          "  └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestSimplifyOuterJoinWithCast",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t t1 left join t t2 on t1.a = t2.a where cast(t1.b as date) >= '2019-01-01'",
        "Plan": [
          "HashJoin 10000.00 root  left outer join, equal:[eq(test.t.a, test.t.a)]",
          "├─TableReader(Build) 8000.00 root  data:Selection",
          "│ └─Selection 8000.00 cop[tikv]  ge(cast(test.t.b, date BINARY), 2019-01-01 00:00:00.000000)",
          "│   └─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"
        ]
      }
    ]
  },
  {
    "Name": "TestMaxMinEliminate",
    "Cases": [
      {
        "SQL": "explain format = 'brief' (select max(a) from t) union (select min(a) from t)",
        "Plan": [
          "HashAgg 2.00 root  group by:Column#5, funcs:firstrow(Column#5)->Column#5",
          "└─Union 2.00 root  ",
          "  ├─StreamAgg 1.00 root  funcs:max(test.t.a)->Column#2",
          "  │ └─Limit 1.00 root  offset:0, count:1",
          "  │   └─TableReader 1.00 root  data:Limit",
          "  │     └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "  │       └─TableFullScan 1.00 cop[tikv] table:t keep order:true, desc, stats:pseudo",
          "  └─StreamAgg 1.00 root  funcs:min(test.t.a)->Column#4",
          "    └─Limit 1.00 root  offset:0, count:1",
          "      └─TableReader 1.00 root  data:Limit",
          "        └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "          └─TableFullScan 1.00 cop[tikv] table:t keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(a), max(a) from cluster_index_t",
        "Plan": [
          "HashJoin 1.00 root  CARTESIAN inner join",
          "├─StreamAgg(Build) 1.00 root  funcs:max(test.cluster_index_t.a)->Column#5",
          "│ └─Limit 1.00 root  offset:0, count:1",
          "│   └─TableReader 1.00 root  data:Limit",
          "│     └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "│       └─TableFullScan 1.00 cop[tikv] table:cluster_index_t keep order:true, desc, stats:pseudo",
          "└─StreamAgg(Probe) 1.00 root  funcs:min(test.cluster_index_t.a)->Column#4",
          "  └─Limit 1.00 root  offset:0, count:1",
          "    └─TableReader 1.00 root  data:Limit",
          "      └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "        └─TableFullScan 1.00 cop[tikv] table:cluster_index_t keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(b), max(b) from cluster_index_t where a = 1",
        "Plan": [
          "HashJoin 1.00 root  CARTESIAN inner join",
          "├─StreamAgg(Build) 1.00 root  funcs:max(test.cluster_index_t.b)->Column#5",
          "│ └─Limit 1.00 root  offset:0, count:1",
          "│   └─TableReader 1.00 root  data:Limit",
          "│     └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "│       └─TableRangeScan 1.00 cop[tikv] table:cluster_index_t range:[1,1], keep order:true, desc, stats:pseudo",
          "└─StreamAgg(Probe) 1.00 root  funcs:min(test.cluster_index_t.b)->Column#4",
          "  └─Limit 1.00 root  offset:0, count:1",
          "    └─TableReader 1.00 root  data:Limit",
          "      └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "        └─TableRangeScan 1.00 cop[tikv] table:cluster_index_t range:[1,1], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(a), max(a) from cluster_index_t where b = 1",
        "Plan": [
          "StreamAgg 1.00 root  funcs:min(Column#8)->Column#4, funcs:max(Column#9)->Column#5",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:min(test.cluster_index_t.a)->Column#8, funcs:max(test.cluster_index_t.a)->Column#9",
          "    └─Selection 10.00 cop[tikv]  eq(test.cluster_index_t.b, 1)",
          "      └─TableFullScan 10000.00 cop[tikv] table:cluster_index_t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(b), max(b) from cluster_index_t where b = 1",
        "Plan": [
          "StreamAgg 1.00 root  funcs:min(Column#8)->Column#4, funcs:max(Column#9)->Column#5",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:min(test.cluster_index_t.b)->Column#8, funcs:max(test.cluster_index_t.b)->Column#9",
          "    └─Selection 10.00 cop[tikv]  eq(test.cluster_index_t.b, 1)",
          "      └─TableFullScan 10000.00 cop[tikv] table:cluster_index_t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexJoinUniqueCompositeIndex",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a = t2.a and t1.c = t2.c",
        "Plan": [
          "IndexJoin 2.00 root  inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.c, test.t2.c)",
          "├─TableReader(Build) 1.00 root  data:TableFullScan",
          "│ └─TableFullScan 1.00 cop[tikv] table:t1 keep order:false",
          "└─IndexLookUp(Probe) 2.00 root  ",
          "  ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false",
          "  └─TableRowIDScan(Probe) 2.00 cop[tikv] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a = t2.a and t1.c <= t2.b",
        "Plan": [
          "IndexJoin 2.00 root  inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), other cond:le(test.t1.c, test.t2.b)",
          "├─TableReader(Build) 1.00 root  data:TableFullScan",
          "│ └─TableFullScan 1.00 cop[tikv] table:t1 keep order:false",
          "└─IndexLookUp(Probe) 2.00 root  ",
          "  ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a) le(test.t1.c, test.t2.b)], keep order:false",
          "  └─TableRowIDScan(Probe) 2.00 cop[tikv] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ TIDB_INLJ(t2) */ * from t1 join t2 on t1.a = t2.a and t2.b = 1",
        "Plan": [
          "IndexJoin 1.00 root  inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)",
          "├─TableReader(Build) 1.00 root  data:TableFullScan",
          "│ └─TableFullScan 1.00 cop[tikv] table:t1 keep order:false",
          "└─IndexLookUp(Probe) 1.00 root  ",
          "  ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a) eq(test.t2.b, 1)], keep order:false",
          "  └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestPartitionTableStats",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t order by a",
        "Result": [
          "Sort 10005.00 root  test.t.a",
          "└─PartitionUnion 10005.00 root  ",
          "  ├─TableReader 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "  ├─TableReader 1.00 root  data:TableFullScan",
          "  │ └─TableFullScan 1.00 cop[tikv] table:t, partition:p1 keep order:false",
          "  └─TableReader 4.00 root  data:TableFullScan",
          "    └─TableFullScan 4.00 cop[tikv] table:t, partition:p2 keep order:false"
        ]
      },
      {
        "SQL": "select * from t order by a",
        "Result": [
          "15 5",
          "21 1",
          "22 2",
          "23 3",
          "24 4"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t order by a limit 3",
        "Result": [
          "TopN 3.00 root  test.t.a, offset:0, count:3",
          "└─PartitionUnion 7.00 root  ",
          "  ├─TopN 3.00 root  test.t.a, offset:0, count:3",
          "  │ └─TableReader 3.00 root  data:TopN",
          "  │   └─TopN 3.00 cop[tikv]  test.t.a, offset:0, count:3",
          "  │     └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "  ├─TopN 1.00 root  test.t.a, offset:0, count:3",
          "  │ └─TableReader 1.00 root  data:TableFullScan",
          "  │   └─TableFullScan 1.00 cop[tikv] table:t, partition:p1 keep order:false",
          "  └─TopN 3.00 root  test.t.a, offset:0, count:3",
          "    └─TableReader 3.00 root  data:TopN",
          "      └─TopN 3.00 cop[tikv]  test.t.a, offset:0, count:3",
          "        └─TableFullScan 4.00 cop[tikv] table:t, partition:p2 keep order:false"
        ]
      },
      {
        "SQL": "select * from t order by a limit 3",
        "Result": [
          "15 5",
          "21 1",
          "22 2"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexMerge",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, b) */ * from t where a = 1 or b = 2",
        "Plan": [
          "IndexMerge 2.00 root  type: union",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[2,2], keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, A, B) */ * from t where a = 1 or b = 2",
        "Plan": [
          "IndexMerge 2.00 root  type: union",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[2,2], keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, primary) */ * from t where 1 or t.c",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, b, c) */ * from t where 1 or t.a = 1 or t.b = 2",
        "Plan": [
          "TableReader 10000.00 root  data:Selection",
          "└─Selection 10000.00 cop[tikv]  or(1, or(eq(test.t.a, 1), eq(test.t.b, 2)))",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexMergeHint4CNF",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t where b = 1 and (a = 1 or c = 1)",
        "Plan": [
          "IndexLookUp 0.02 root  ",
          "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false, stats:pseudo",
          "└─Selection(Probe) 0.02 cop[tikv]  or(eq(test.t.a, 1), eq(test.t.c, 1))",
          "  └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, c) */ * from t where b = 1 and (a = 1 or c = 1)",
        "Plan": [
          "IndexMerge 0.02 root  type: union",
          "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo",
          "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:c(c) range:[1,1], keep order:false, stats:pseudo",
          "└─Selection(Probe) 0.02 cop[tikv]  eq(test.t.b, 1)",
          "  └─TableRowIDScan 19.99 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestSubqueryWithTopN",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select t1.b from t t1 where t1.b in (select t2.a from t t2 order by t1.a+t2.a limit 1)",
        "Plan": [
          "Projection 9990.00 root  test.t.b",
          "└─Apply 9990.00 root  semi join, equal:[eq(test.t.b, test.t.a)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t.b))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─Selection(Probe) 7992.00 root  not(isnull(test.t.a))",
          "    └─Projection 9990.00 root  test.t.a",
          "      └─TopN 9990.00 root  Column#7, offset:0, count:1",
          "        └─Projection 9990.00 root  test.t.a, plus(test.t.a, test.t.a)->Column#7",
          "          └─TableReader 9990.00 root  data:TopN",
          "            └─TopN 9990.00 cop[tikv]  plus(test.t.a, test.t.a), offset:0, count:1",
          "              └─TableFullScan 99900000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select t1.a from t t1 order by (t1.b = 1 and exists (select 1 from t t2 where t1.b = t2.b)) limit 1",
        "Plan": [
          "Projection 1.00 root  test.t.a",
          "└─Projection 1.00 root  test.t.a, test.t.b, Column#11",
          "  └─TopN 1.00 root  Column#13, offset:0, count:1",
          "    └─Projection 10000.00 root  test.t.a, test.t.b, Column#11, and(eq(test.t.b, 1), Column#11)->Column#13",
          "      └─HashJoin 10000.00 root  left outer semi join, equal:[eq(test.t.b, test.t.b)]",
          "        ├─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:TableFullScan",
          "          └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select b+b as x from t) t1, t t2 where t1.x=t2.b order by t1.x limit 1",
        "Plan": [
          "TopN 1.00 root  Column#4, offset:0, count:1",
          "└─Projection 10000.00 root  Column#4, test.t.a, test.t.b",
          "  └─HashJoin 10000.00 root  inner join, equal:[eq(test.t.b, Column#4)]",
          "    ├─Projection(Build) 8000.00 root  plus(test.t.b, test.t.b)->Column#4",
          "    │ └─TableReader 8000.00 root  data:Selection",
          "    │   └─Selection 8000.00 cop[tikv]  not(isnull(plus(test.t.b, test.t.b)))",
          "    │     └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexJoinTableRange",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ TIDB_INLJ(t2)*/ * from t1, t2 where t1.a = t2.a and t1.b = t2.b",
        "Plan": [
          "IndexJoin 12487.50 root  inner join, inner:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)",
          "├─IndexReader(Build) 9990.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9980.01 root  data:Selection",
          "  └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.b))",
          "    └─TableRangeScan 9990.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ TIDB_INLJ(t2)*/ * from t1, t2 where t1.a = t2.a and t1.b = t2.a and t1.b = t2.b",
        "Plan": [
          "IndexJoin 12487.50 root  inner join, inner:TableReader, outer key:test.t1.a, test.t1.b, inner key:test.t2.a, test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.a), eq(test.t1.b, test.t2.b)",
          "├─IndexReader(Build) 9990.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9980.01 root  data:Selection",
          "  └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.b))",
          "    └─TableRangeScan 9990.00 cop[tikv] table:t2 range: decided by [test.t1.a test.t1.b], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_JOIN(t4) */ * from t3 join t4 on t3.a = t4.a where t4.b = 1",
        "Plan": [
          "IndexJoin 12.50 root  inner join, inner:TableReader, outer key:test.t3.a, inner key:test.t4.a, equal cond:eq(test.t3.a, test.t4.a)",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9.99 root  data:Selection",
          "  └─Selection 9.99 cop[tikv]  eq(test.t4.b, 1)",
          "    └─TableRangeScan 9990.00 cop[tikv] table:t4 range: decided by [eq(test.t4.a, test.t3.a) eq(test.t4.b, 1)], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_JOIN(t4) */ * from t3 join t4 on t3.b = t4.b where t4.a = 1",
        "Plan": [
          "IndexJoin 12.50 root  inner join, inner:TableReader, outer key:test.t3.b, inner key:test.t4.b, equal cond:eq(test.t3.b, test.t4.b)",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.b))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9.99 root  data:Selection",
          "  └─Selection 9.99 cop[tikv]  eq(test.t4.a, 1)",
          "    └─TableRangeScan 9990.00 cop[tikv] table:t4 range: decided by [eq(test.t4.b, test.t3.b) eq(test.t4.a, 1)], keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestHintWithRequiredProperty",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ INL_JOIN(t2) */ * from t t1, t t2 where t1.a = t2.b order by t2.a",
        "Plan": [
          "Sort 12487.50 root  test.t.a",
          "└─IndexJoin 12487.50 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.t.b, equal cond:eq(test.t.a, test.t.b)",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─IndexLookUp(Probe) 12487.50 root  ",
          "    ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.t.b))",
          "    │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warnings": []
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_HASH_JOIN(t2) */ * from t t1, t t2 where t1.a = t2.b order by t2.a",
        "Plan": [
          "Sort 12487.50 root  test.t.a",
          "└─IndexHashJoin 12487.50 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.t.b, equal cond:eq(test.t.a, test.t.b)",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─IndexLookUp(Probe) 12487.50 root  ",
          "    ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.t.b))",
          "    │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warnings": []
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_MERGE_JOIN(t2)*/ t1.a, t2.a from t t1, t t2 ,t t3 where t1.a = t2.a and t3.a=t2.a",
        "Plan": [
          "HashJoin 15625.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t3, index:b(b) keep order:false, stats:pseudo",
          "└─IndexMergeJoin(Probe) 12500.00 root  inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a",
          "  ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "  │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:b(b) keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 10000.00 root  data:TableRangeScan",
          "    └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:true, stats:pseudo"
        ],
        "Warnings": []
      },
      {
        "SQL": "desc format = 'brief' select * from t t1, (select /*+ HASH_AGG() */ b, max(a) from t t2 group by b) t2 where t1.b = t2.b order by t1.b",
        "Plan": [
          "Sort 9990.00 root  test.t.b",
          "└─Projection 9990.00 root  test.t.a, test.t.b, test.t.c, test.t.b, Column#7",
          "  └─HashJoin 9990.00 root  inner join, equal:[eq(test.t.b, test.t.b)]",
          "    ├─HashAgg(Build) 7992.00 root  group by:test.t.b, funcs:max(Column#10)->Column#7, funcs:firstrow(test.t.b)->test.t.b",
          "    │ └─IndexReader 7992.00 root  index:HashAgg",
          "    │   └─HashAgg 7992.00 cop[tikv]  group by:test.t.b, funcs:max(test.t.a)->Column#10",
          "    │     └─IndexFullScan 9990.00 cop[tikv] table:t2, index:b(b) keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warnings": []
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_HASH_JOIN(t2) */ distinct t2.a from t t1 join t t2 on t1.a = t2.a",
        "Plan": [
          "IndexHashJoin 12500.00 root  inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:b(b) keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableRangeScan",
          "  └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo"
        ],
        "Warnings": []
      },
      {
        "SQL": "desc format = 'brief' select /*+ INL_JOIN(t2) */ * from t t1, t t2 where t1.a = t2.c order by t1.a",
        "Plan": [
          "Sort 12487.50 root  test.t.a",
          "└─HashJoin 12487.50 root  inner join, equal:[eq(test.t.a, test.t.c)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t.c))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable",
          "[planner:1815]Optimizer Hint /*+ INL_JOIN(t2) */ or /*+ TIDB_INLJ(t2) */ is inapplicable"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexHintWarning",
    "Cases": [
      {
        "SQL": "select /*+ USE_INDEX(t1, j) */ * from t1",
        "Warnings": [
          "[planner:1176]Key 'j' doesn't exist in table 't1'"
        ]
      },
      {
        "SQL": "select /*+ IGNORE_INDEX(t1, j) */ * from t1",
        "Warnings": [
          "[planner:1176]Key 'j' doesn't exist in table 't1'"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX(t2, a, b, c) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index(test.t2, a, b, c) is inapplicable, check whether the table(test.t2) exists"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX(t2) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index(test.t2) is inapplicable, check whether the table(test.t2) exists"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX(t1, a), USE_INDEX(t2, a), USE_INDEX(t3, a) */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]use_index(test.t3, a) is inapplicable, check whether the table(test.t3) exists"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX(t3, a), USE_INDEX(t4, b), IGNORE_INDEX(t3, a) */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]use_index(test.t3, a) is inapplicable, check whether the table(test.t3) exists",
          "[planner:1815]use_index(test.t4, b) is inapplicable, check whether the table(test.t4) exists",
          "[planner:1815]ignore_index(test.t3, a) is inapplicable, check whether the table(test.t3) exists"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE(t3, a, b, d) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index_merge(test.t3, a, b, d) is inapplicable, check whether the table(test.t3) exists"
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b, c, d) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index_merge(test.t1, a, b, c, d) is inapplicable, check whether the indexes (c, d) exist, or the indexes are conflicted with use_index/ignore_index/force_index hints."
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b), USE_INDEX(t1, a) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index_merge(test.t1, a, b) is inapplicable, check whether the indexes (b) exist, or the indexes are conflicted with use_index/ignore_index/force_index hints."
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE(t1, a, b), IGNORE_INDEX(t1, a) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index_merge(test.t1, a, b) is inapplicable, check whether the indexes (a) exist, or the indexes are conflicted with use_index/ignore_index/force_index hints."
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE(t1, primary, a, b, c) */ * from t1",
        "Warnings": [
          "[planner:1815]use_index_merge(test.t1, primary, a, b, c) is inapplicable, check whether the indexes (c) exist, or the indexes are conflicted with use_index/ignore_index/force_index hints."
        ]
      }
    ]
  },
  {
    "Name": "TestHintWithoutTableWarning",
    "Cases": [
      {
        "SQL": "select /*+ TIDB_SMJ() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint TIDB_SMJ() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ MERGE_JOIN() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint MERGE_JOIN() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ INL_JOIN() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint INL_JOIN() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ TIDB_INLJ() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint TIDB_INLJ() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ INL_HASH_JOIN() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint INL_HASH_JOIN() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ INL_MERGE_JOIN() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint INL_MERGE_JOIN() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ HASH_JOIN() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[planner:1815]Hint HASH_JOIN() is inapplicable. Please specify the table names in the arguments."
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[parser:1064]Optimizer hint syntax error at line 1 column 22 near \") */\" "
        ]
      },
      {
        "SQL": "select /*+ IGNORE_INDEX() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[parser:1064]Optimizer hint syntax error at line 1 column 25 near \") */\" "
        ]
      },
      {
        "SQL": "select /*+ USE_INDEX_MERGE() */ * from t1, t2 where t1.a=t2.a",
        "Warnings": [
          "[parser:1064]Optimizer hint syntax error at line 1 column 28 near \") */\" "
        ]
      }
    ]
  },
  {
    "Name": "TestPartitionPruningForInExpr",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t where a in (1, 2,'11')",
        "Plan": [
          "TableReader 30.00 root partition:p0,p2 data:Selection",
          "└─Selection 30.00 cop[tikv]  in(test.t.a, 1, 2, 11)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where a in (17, null)",
        "Plan": [
          "TableReader 10.00 root partition:p0,p2 data:Selection",
          "└─Selection 10.00 cop[tikv]  in(test.t.a, 17, NULL)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where a in (16, 'abc')",
        "Plan": [
          "TableReader 20.00 root partition:p0,p2 data:Selection",
          "└─Selection 20.00 cop[tikv]  in(test.t.a, 16, 0)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where a in (15, 0.12, 3.47)",
        "Plan": [
          "TableReader 10.00 root partition:p2 data:Selection",
          "└─Selection 10.00 cop[tikv]  or(eq(test.t.a, 15), 0)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where a in (0.12, 3.47)",
        "Plan": [
          "TableDual 0.00 root  rows:0"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where a in (14, floor(3.47))",
        "Plan": [
          "TableReader 20.00 root partition:p0,p2 data:Selection",
          "└─Selection 20.00 cop[tikv]  in(test.t.a, 14, 3)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where b in (3, 4)",
        "Plan": [
          "TableReader 20.00 root partition:all data:Selection",
          "└─Selection 20.00 cop[tikv]  in(test.t.b, 3, 4)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestStreamAggProp",
    "Cases": [
      {
        "SQL": "select /*+ stream_agg() */ count(*) c from t group by a order by c limit 1",
        "Plan": [
          "TopN 1.00 root  Column#3, offset:0, count:1",
          "└─StreamAgg 8000.00 root  group by:test.t.a, funcs:count(1)->Column#3",
          "  └─Sort 10000.00 root  test.t.a",
          "    └─TableReader 10000.00 root  data:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select /*+ stream_agg() */ count(*) c from t group by a order by c",
        "Plan": [
          "Sort 8000.00 root  Column#3",
          "└─StreamAgg 8000.00 root  group by:test.t.a, funcs:count(1)->Column#3",
          "  └─Sort 10000.00 root  test.t.a",
          "    └─TableReader 10000.00 root  data:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "1",
          "2"
        ]
      },
      {
        "SQL": "select /*+ stream_agg() */ count(*) c from t group by a order by a limit 1",
        "Plan": [
          "Projection 1.00 root  Column#3",
          "└─Limit 1.00 root  offset:0, count:1",
          "  └─StreamAgg 1.00 root  group by:test.t.a, funcs:count(1)->Column#3, funcs:firstrow(test.t.a)->test.t.a",
          "    └─Sort 1.25 root  test.t.a",
          "      └─TableReader 1.25 root  data:TableFullScan",
          "        └─TableFullScan 1.25 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "2"
        ]
      },
      {
        "SQL": "select /*+ stream_agg() */ count(*) c from t group by a order by a",
        "Plan": [
          "Projection 8000.00 root  Column#3",
          "└─StreamAgg 8000.00 root  group by:test.t.a, funcs:count(1)->Column#3, funcs:firstrow(test.t.a)->test.t.a",
          "  └─Sort 10000.00 root  test.t.a",
          "    └─TableReader 10000.00 root  data:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "2",
          "1"
        ]
      }
    ]
  },
  {
    "Name": "TestOptimizeHintOnPartitionTable",
    "Cases": [
      {
        "SQL": "select /*+ use_index(t) */ * from t",
        "Plan": [
          "PartitionUnion 30000.00 root  ",
          "├─TableReader 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "├─TableReader 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "select /*+ use_index(t partition(p0, p1) b, c) */ * from t partition(p1,p2)",
        "Plan": [
          "PartitionUnion 20000.00 root  ",
          "├─IndexLookUp 10000.00 root  ",
          "│ ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t, partition:p1, index:b(b) keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Warning 1105 unknown partitions (p0) in optimizer hint /*+ USE_INDEX(t PARTITION(p0, p1) b, c) */"
        ]
      },
      {
        "SQL": "select /*+ use_index(t partition(p_non_exist)) */ * from t partition(p1,p2)",
        "Plan": [
          "PartitionUnion 20000.00 root  ",
          "├─TableReader 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Warning 1105 unknown partitions (p_non_exist) in optimizer hint /*+ USE_INDEX(t PARTITION(p_non_exist)) */"
        ]
      },
      {
        "SQL": "select /*+ use_index(t partition(p0, p1) b, c) */ * from t",
        "Plan": [
          "PartitionUnion 30000.00 root  ",
          "├─IndexLookUp 10000.00 root  ",
          "│ ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t, partition:p0, index:b(b) keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "├─IndexLookUp 10000.00 root  ",
          "│ ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t, partition:p1, index:b(b) keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "select /*+ ignore_index(t partition(p0, p1) b, c) */ * from t",
        "Plan": [
          "PartitionUnion 30000.00 root  ",
          "├─TableReader 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p0 keep order:false, stats:pseudo",
          "├─TableReader 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "select /*+ hash_join(t1, t2 partition(p0)) */ * from t t1 join t t2 on t1.a = t2.a",
        "Plan": [
          "HashJoin 37500.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─PartitionUnion(Build) 30000.00 root  ",
          "│ ├─TableReader 10000.00 root  data:TableFullScan",
          "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t2, partition:p0 keep order:false, stats:pseudo",
          "│ ├─TableReader 10000.00 root  data:TableFullScan",
          "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t2, partition:p1 keep order:false, stats:pseudo",
          "│ └─TableReader 10000.00 root  data:TableFullScan",
          "│   └─TableFullScan 10000.00 cop[tiflash] table:t2, partition:p2 keep order:false, stats:pseudo",
          "└─PartitionUnion(Probe) 30000.00 root  ",
          "  ├─TableReader 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t1, partition:p0 keep order:false, stats:pseudo",
          "  ├─TableReader 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t1, partition:p1 keep order:false, stats:pseudo",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t1, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Warning 1105 Optimizer Hint /*+ HASH_JOIN(t1, t2 PARTITION(p0)) */ is inapplicable on specified partitions"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(t partition(p0)) */ * from t where t.b = 1 or t.c = \"8\"",
        "Plan": [
          "PartitionUnion 59.97 root  ",
          "├─IndexMerge 19.99 root  type: union",
          "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:b(b) range:[1,1], keep order:false, stats:pseudo",
          "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:c(c) range:[\"8\",\"8\"], keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "├─TableReader 19.99 root  data:Selection",
          "│ └─Selection 19.99 cop[tiflash]  or(eq(test.t.b, 1), eq(test.t.c, \"8\"))",
          "│   └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 19.99 root  data:Selection",
          "  └─Selection 19.99 cop[tiflash]  or(eq(test.t.b, 1), eq(test.t.c, \"8\"))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "select /*+ use_index_merge(t partition(p0, p1) primary, b) */ * from t where t.a = 1 or t.b = 2",
        "Plan": [
          "PartitionUnion 33.00 root  ",
          "├─IndexMerge 11.00 root  type: union",
          "│ ├─TableRangeScan(Build) 1.00 cop[tikv] table:t, partition:p0 range:[1,1], keep order:false, stats:pseudo",
          "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:b(b) range:[2,2], keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 11.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "├─IndexMerge 11.00 root  type: union",
          "│ ├─TableRangeScan(Build) 1.00 cop[tikv] table:t, partition:p1 range:[1,1], keep order:false, stats:pseudo",
          "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p1, index:b(b) range:[2,2], keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 11.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo",
          "└─TableReader 11.00 root  data:Selection",
          "  └─Selection 11.00 cop[tiflash]  or(eq(test.t.a, 1), eq(test.t.b, 2))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "select /*+ use_index(t partition(p0) b) */ * from t partition(p0, p1)",
        "Plan": [
          "PartitionUnion 20000.00 root  ",
          "├─IndexLookUp 10000.00 root  ",
          "│ ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t, partition:p0, index:b(b) keep order:false, stats:pseudo",
          "│ └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t, partition:p1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      }
    ]
  },
  {
    "Name": "TestAccessPathOnClusterIndex",
    "Cases": [
      {
        "SQL": "select * from t1",
        "Plan": [
          "TableReader 3.00 root  data:TableFullScan",
          "└─TableFullScan 3.00 cop[tikv] table:t1 keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11",
          "2 222 2.2000000000 12",
          "3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select * from t1 where t1.a >= 1 and t1.a < 4",
        "Plan": [
          "TableReader 3.00 root  data:TableRangeScan",
          "└─TableRangeScan 3.00 cop[tikv] table:t1 range:[1,4), keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11",
          "2 222 2.2000000000 12",
          "3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select * from t1 where t1.a = 1 and t1.b < \"333\"",
        "Plan": [
          "TableReader 0.82 root  data:TableRangeScan",
          "└─TableRangeScan 0.82 cop[tikv] table:t1 range:[1 -inf,1 \"333\"), keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11"
        ]
      },
      {
        "SQL": "select t1.a, t1.b, t1.c from t1 where t1.c = 3.3",
        "Plan": [
          "IndexReader 1.00 root  index:IndexRangeScan",
          "└─IndexRangeScan 1.00 cop[tikv] table:t1, index:c(c) range:[3.3000000000,3.3000000000], keep order:false"
        ],
        "Res": [
          "3 333 3.3000000000"
        ]
      },
      {
        "SQL": "select t1.b, t1.c from t1 where t1.c = 2.2",
        "Plan": [
          "IndexReader 1.00 root  index:IndexRangeScan",
          "└─IndexRangeScan 1.00 cop[tikv] table:t1, index:c(c) range:[2.2000000000,2.2000000000], keep order:false"
        ],
        "Res": [
          "222 2.2000000000"
        ]
      },
      {
        "SQL": "select /*+ use_index(t1, c) */ * from t1",
        "Plan": [
          "IndexLookUp 3.00 root  ",
          "├─IndexFullScan(Build) 3.00 cop[tikv] table:t1, index:c(c) keep order:false",
          "└─TableRowIDScan(Probe) 3.00 cop[tikv] table:t1 keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11",
          "2 222 2.2000000000 12",
          "3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select * from t1 use index(c) where t1.c in (2.2, 3.3)",
        "Plan": [
          "IndexLookUp 2.00 root  ",
          "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:c(c) range:[2.2000000000,2.2000000000], [3.3000000000,3.3000000000], keep order:false",
          "└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t1 keep order:false"
        ],
        "Res": [
          "2 222 2.2000000000 12",
          "3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select * from t1 where t1.a = 1 order by b",
        "Plan": [
          "TableReader 1.00 root  data:TableRangeScan",
          "└─TableRangeScan 1.00 cop[tikv] table:t1 range:[1,1], keep order:true"
        ],
        "Res": [
          "1 111 1.1000000000 11"
        ]
      },
      {
        "SQL": "select * from t1 order by a, b limit 1",
        "Plan": [
          "Limit 1.00 root  offset:0, count:1",
          "└─TableReader 1.00 root  data:Limit",
          "  └─Limit 1.00 cop[tikv]  offset:0, count:1",
          "    └─TableFullScan 1.00 cop[tikv] table:t1 keep order:true"
        ],
        "Res": [
          "1 111 1.1000000000 11"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(t1 primary, c) */ * from t1 where t1.a >= 1 or t1.c = 2.2",
        "Plan": [
          "IndexMerge 3.00 root  type: union",
          "├─TableRangeScan(Build) 3.00 cop[tikv] table:t1 range:[1,+inf], keep order:false",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:c(c) range:[2.2000000000,2.2000000000], keep order:false",
          "└─TableRowIDScan(Probe) 3.00 cop[tikv] table:t1 keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11",
          "2 222 2.2000000000 12",
          "3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(t1 primary, c) */ * from t1 where t1.a = 1 and t1.b = '111' or t1.c = 3.3",
        "Plan": [
          "IndexMerge 1.67 root  type: union",
          "├─TableRangeScan(Build) 1.00 cop[tikv] table:t1 range:[1 \"111\",1 \"111\"], keep order:false",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:c(c) range:[3.3000000000,3.3000000000], keep order:false",
          "└─TableRowIDScan(Probe) 1.67 cop[tikv] table:t1 keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11",
          "3 333 3.3000000000 13"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexJoinOnClusteredIndex",
    "Cases": [
      {
        "SQL": "select /*+ inl_join(t1, t2) */ * from t t1 join t t2 on t1.a = t2.a",
        "Plan": [
          "IndexJoin 3.00 root  inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)",
          "├─TableReader(Build) 3.00 root  data:TableFullScan",
          "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─TableReader(Probe) 3.00 root  data:TableRangeScan",
          "  └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11 1 111 1.1000000000 11",
          "2 222 2.2000000000 12 2 222 2.2000000000 12",
          "3 333 3.3000000000 13 3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ inl_merge_join(t1, t2) */ * from t t1 join t t2 on t1.a = t2.a",
        "Plan": [
          "IndexMergeJoin 3.00 root  inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a",
          "├─TableReader(Build) 3.00 root  data:TableFullScan",
          "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─TableReader(Probe) 3.00 root  data:TableRangeScan",
          "  └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:true"
        ],
        "Res": [
          "1 111 1.1000000000 11 1 111 1.1000000000 11",
          "2 222 2.2000000000 12 2 222 2.2000000000 12",
          "3 333 3.3000000000 13 3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ inl_hash_join(t1, t2) */ * from t t1 join t t2 on t1.a = t2.a",
        "Plan": [
          "IndexHashJoin 3.00 root  inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)",
          "├─TableReader(Build) 3.00 root  data:TableFullScan",
          "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─TableReader(Probe) 3.00 root  data:TableRangeScan",
          "  └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11 1 111 1.1000000000 11",
          "2 222 2.2000000000 12 2 222 2.2000000000 12",
          "3 333 3.3000000000 13 3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ inl_join(t1, t2) */ * from t t1 join t t2 on t1.a = t2.a and t1.b = t2.b",
        "Plan": [
          "IndexJoin 3.00 root  inner join, inner:TableReader, outer key:test.t.a, test.t.b, inner key:test.t.a, test.t.b, equal cond:eq(test.t.a, test.t.a), eq(test.t.b, test.t.b)",
          "├─TableReader(Build) 3.00 root  data:TableFullScan",
          "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─TableReader(Probe) 3.00 root  data:TableRangeScan",
          "  └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a) eq(test.t.b, test.t.b)], keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11 1 111 1.1000000000 11",
          "2 222 2.2000000000 12 2 222 2.2000000000 12",
          "3 333 3.3000000000 13 3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ inl_join(t1, t2) */ * from t t1 join t t2 on t1.c = t2.c",
        "Plan": [
          "IndexJoin 3.00 root  inner join, inner:IndexLookUp, outer key:test.t.c, inner key:test.t.c, equal cond:eq(test.t.c, test.t.c)",
          "├─TableReader(Build) 3.00 root  data:Selection",
          "│ └─Selection 3.00 cop[tikv]  not(isnull(test.t.c))",
          "│   └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false",
          "└─IndexLookUp(Probe) 3.00 root  ",
          "  ├─Selection(Build) 3.00 cop[tikv]  not(isnull(test.t.c))",
          "  │ └─IndexRangeScan 3.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, test.t.c)], keep order:false",
          "  └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false"
        ],
        "Res": [
          "1 111 1.1000000000 11 1 111 1.1000000000 11",
          "2 222 2.2000000000 12 2 222 2.2000000000 12",
          "3 333 3.3000000000 13 3 333 3.3000000000 13"
        ]
      },
      {
        "SQL": "select /*+ inl_merge_join(t1,t2) */ t2.a, t2.c, t2.d from t t1 left join t t2 on t1.a = t2.c;",
        "Plan": [
          "IndexMergeJoin 3.00 root  left outer join, inner:Projection, outer key:Column#9, inner key:test.t.c",
          "├─Projection(Build) 3.00 root  cast(test.t.a, decimal(10,0) BINARY)->Column#9",
          "│ └─IndexReader 3.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 3.00 cop[tikv] table:t1, index:c(c) keep order:false",
          "└─Projection(Probe) 3.00 root  test.t.a, test.t.c, test.t.d",
          "  └─IndexLookUp 3.00 root  ",
          "    ├─IndexRangeScan(Build) 3.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, Column#9)], keep order:true",
          "    └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false"
        ],
        "Res": [
          "<nil> <nil> <nil>",
          "<nil> <nil> <nil>",
          "<nil> <nil> <nil>"
        ]
      }
    ]
  },
  {
    "Name": "TestPartitionExplain",
    "Cases": [
      {
        "SQL": "select * from pt where c > 10",
        "Plan": [
          "TableReader_7 3333.33 root partition:dual data:Selection_6",
          "└─Selection_6 3333.33 cop[tikv]  gt(test.pt.c, 10)",
          "  └─TableFullScan_5 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from pt where c > 8",
        "Plan": [
          "TableReader_7 3333.33 root partition:p2 data:Selection_6",
          "└─Selection_6 3333.33 cop[tikv]  gt(test.pt.c, 8)",
          "  └─TableFullScan_5 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from pt where c < 2 or c >= 9",
        "Plan": [
          "TableReader_7 6656.67 root partition:p0,p2 data:Selection_6",
          "└─Selection_6 6656.67 cop[tikv]  or(lt(test.pt.c, 2), ge(test.pt.c, 9))",
          "  └─TableFullScan_5 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select c from pt",
        "Plan": [
          "IndexReader_7 10000.00 root partition:all index:IndexFullScan_6",
          "└─IndexFullScan_6 10000.00 cop[tikv] table:pt, index:i_c(c) keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select c from pt where c > 10",
        "Plan": [
          "IndexReader_6 3333.33 root partition:dual index:IndexRangeScan_5",
          "└─IndexRangeScan_5 3333.33 cop[tikv] table:pt, index:i_c(c) range:(10,+inf], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select c from pt where c > 8",
        "Plan": [
          "IndexReader_6 3333.33 root partition:p2 index:IndexRangeScan_5",
          "└─IndexRangeScan_5 3333.33 cop[tikv] table:pt, index:i_c(c) range:(8,+inf], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select c from pt where c < 2 or c >= 9",
        "Plan": [
          "IndexReader_6 6656.67 root partition:p0,p2 index:IndexRangeScan_5",
          "└─IndexRangeScan_5 6656.67 cop[tikv] table:pt, index:i_c(c) range:[-inf,2), [9,+inf], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select /*+ use_index(pt, i_id) */ * from pt",
        "Plan": [
          "IndexLookUp_6 10000.00 root partition:all ",
          "├─IndexFullScan_4(Build) 10000.00 cop[tikv] table:pt, index:i_id(id) keep order:false, stats:pseudo",
          "└─TableRowIDScan_5(Probe) 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select /*+ use_index(pt, i_id) */ * from pt where id < 4 and c > 10",
        "Plan": [
          "IndexLookUp_8 1107.78 root partition:dual ",
          "├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:pt, index:i_id(id) range:[-inf,4), keep order:false, stats:pseudo",
          "└─Selection_7(Probe) 1107.78 cop[tikv]  gt(test.pt.c, 10)",
          "  └─TableRowIDScan_6 3323.33 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select /*+ use_index(pt, i_id) */ * from pt where id < 10 and c > 8",
        "Plan": [
          "IndexLookUp_8 1107.78 root partition:p2 ",
          "├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:pt, index:i_id(id) range:[-inf,10), keep order:false, stats:pseudo",
          "└─Selection_7(Probe) 1107.78 cop[tikv]  gt(test.pt.c, 8)",
          "  └─TableRowIDScan_6 3323.33 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select /*+ use_index(pt, i_id) */ * from pt where id < 10 and c < 2 or c >= 9",
        "Plan": [
          "IndexLookUp_8 5325.33 root partition:p0,p2 ",
          "├─IndexFullScan_5(Build) 10000.00 cop[tikv] table:pt, index:i_id(id) keep order:false, stats:pseudo",
          "└─Selection_7(Probe) 5325.33 cop[tikv]  or(and(lt(test.pt.id, 10), lt(test.pt.c, 2)), ge(test.pt.c, 9))",
          "  └─TableRowIDScan_6 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from pt partition (p0) where c > 8",
        "Plan": [
          "TableReader_7 3333.33 root partition:dual data:Selection_6",
          "└─Selection_6 3333.33 cop[tikv]  gt(test.pt.c, 8)",
          "  └─TableFullScan_5 10000.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select c from pt partition (p0, p2) where c > 8",
        "Plan": [
          "IndexReader_6 3333.33 root partition:p2 index:IndexRangeScan_5",
          "└─IndexRangeScan_5 3333.33 cop[tikv] table:pt, index:i_c(c) range:(8,+inf], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select /*+ use_index(pt, i_id) */ * from pt partition (p1, p2) where c < 3 and id = 5",
        "Plan": [
          "IndexLookUp_8 3.32 root partition:dual ",
          "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:pt, index:i_id(id) range:[5,5], keep order:false, stats:pseudo",
          "└─Selection_7(Probe) 3.32 cop[tikv]  lt(test.pt.c, 3)",
          "  └─TableRowIDScan_6 10.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from pt where id = 4 or c < 7",
        "Plan": [
          "IndexMerge_11 3330.01 root partition:all type: union",
          "├─IndexRangeScan_8(Build) 10.00 cop[tikv] table:pt, index:i_id(id) range:[4,4], keep order:false, stats:pseudo",
          "├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:pt, index:i_c(c) range:[-inf,7), keep order:false, stats:pseudo",
          "└─TableRowIDScan_10(Probe) 3330.01 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from pt where id > 4 or c = 7",
        "Plan": [
          "IndexMerge_11 3340.00 root partition:all type: union",
          "├─IndexRangeScan_8(Build) 3333.33 cop[tikv] table:pt, index:i_id(id) range:(4,+inf], keep order:false, stats:pseudo",
          "├─IndexRangeScan_9(Build) 10.00 cop[tikv] table:pt, index:i_c(c) range:[7,7], keep order:false, stats:pseudo",
          "└─TableRowIDScan_10(Probe) 3340.00 cop[tikv] table:pt keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestInvalidHint",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ use_index_merge(tt) */ * from tt where a=10 or a=20;",
        "Plan": [
          "IndexReader 20.00 root  index:IndexRangeScan",
          "└─IndexRangeScan 20.00 cop[tikv] table:tt, index:a(a) range:[10,10], [20,20], keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Warning 1105 IndexMerge is inapplicable"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ use_index_merge(tt) */ * from tt where a=15 or (a < 10 or a > 20);",
        "Plan": [
          "IndexReader 6666.67 root  index:IndexRangeScan",
          "└─IndexRangeScan 6666.67 cop[tikv] table:tt, index:a(a) range:[-inf,10), [15,15], (20,+inf], keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Warning 1105 IndexMerge is inapplicable"
        ]
      }
    ]
  },
  {
    "Name": "TestApproxPercentile",
    "Cases": [
      {
        "SQL": "select approx_percentile(a, 50) from t",
        "Plan": [
          "HashAgg_5 1.00 root  funcs:approx_percentile(test.t.a, 50)->Column#4",
          "└─TableReader_11 10000.00 root  data:TableFullScan_10",
          "  └─TableFullScan_10 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "3"
        ]
      },
      {
        "SQL": "select approx_percentile(a, 10) from t",
        "Plan": [
          "HashAgg_5 1.00 root  funcs:approx_percentile(test.t.a, 10)->Column#4",
          "└─TableReader_11 10000.00 root  data:TableFullScan_10",
          "  └─TableFullScan_10 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select approx_percentile(a, 10+70) from t",
        "Plan": [
          "HashAgg_5 1.00 root  funcs:approx_percentile(test.t.a, 80)->Column#4",
          "└─TableReader_11 10000.00 root  data:TableFullScan_10",
          "  └─TableFullScan_10 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "4"
        ]
      },
      {
        "SQL": "select approx_percentile(a, 10*10) from t",
        "Plan": [
          "HashAgg_5 1.00 root  funcs:approx_percentile(test.t.a, 100)->Column#4",
          "└─TableReader_11 10000.00 root  data:TableFullScan_10",
          "  └─TableFullScan_10 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "5"
        ]
      },
      {
        "SQL": "select approx_percentile(a, 50) from t group by b order by b",
        "Plan": [
          "Projection_6 8000.00 root  Column#4",
          "└─Sort_7 8000.00 root  test.t.b",
          "  └─HashAgg_9 8000.00 root  group by:test.t.b, funcs:approx_percentile(test.t.a, 50)->Column#4, funcs:firstrow(test.t.b)->test.t.b",
          "    └─TableReader_13 10000.00 root  data:TableFullScan_12",
          "      └─TableFullScan_12 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Res": [
          "1",
          "4"
        ]
      }
    ]
  },
  {
    "Name": "TestConvertRangeToPoint",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t0 where a > 1 and a < 3 order by b limit 2",
        "Plan": [
          "Limit 2.00 root  offset:0, count:2",
          "└─IndexReader 2.00 root  index:Limit",
          "  └─Limit 2.00 cop[tikv]  offset:0, count:2",
          "    └─IndexRangeScan 2.50 cop[tikv] table:t0, index:a(a, b) range:[2,2], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t1 where a >= 2 and a <= 2 and b = 2 and c > 2",
        "Plan": [
          "IndexReader 0.33 root  index:IndexRangeScan",
          "└─IndexRangeScan 0.33 cop[tikv] table:t1, index:a(a, b, c) range:(2 2 2,2 2 +inf], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t2 where a >= 2.5 and a <= 2.5 order by b limit 2",
        "Plan": [
          "Limit 2.00 root  offset:0, count:2",
          "└─IndexReader 2.00 root  index:Limit",
          "  └─Limit 2.00 cop[tikv]  offset:0, count:2",
          "    └─IndexRangeScan 2.00 cop[tikv] table:t2, index:a(a, b) range:[2.5,2.5], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t3 where a >= 'a' and a <= 'a' and b = 'b' and c > 'c'",
        "Plan": [
          "IndexReader 0.33 root  index:IndexRangeScan",
          "└─IndexRangeScan 0.33 cop[tikv] table:t3, index:a(a, b, c) range:(\"a\" \"b\" \"c\",\"a\" \"b\" +inf], keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue22105",
    "Cases": [
      {
        "SQL": "explain format = 'brief' SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#10",
          "└─IndexMerge 0.02 root  type: union",
          "  ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:i4(key4) range:[42,42], keep order:false, stats:pseudo",
          "  ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:i1(key1) range:[4,4], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 0.02 cop[tikv]  or(and(eq(test.t1.key4, 42), not(isnull(test.t1.key6))), and(eq(test.t1.key1, 4), eq(test.t1.key3, 6)))",
          "    └─TableRowIDScan 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestReorderSimplifiedOuterJoins",
    "Cases": [
      {
        "SQL": "explain format = 'brief' SELECT t1.pk FROM t1 INNER JOIN t2 ON t1.col1 = t2.pk INNER JOIN t3 ON t1.col3 = t3.pk WHERE t2.col1 IN ('a' , 'b') AND t3.keycol = 'c' AND t1.col2 = 'a' AND t1.col1 != 'abcdef' AND t1.col1 != 'aaaaaa'",
        "Plan": [
          "IndexHashJoin 13.81 root  inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)",
          "├─IndexHashJoin(Build) 12.50 root  inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)",
          "│ ├─IndexLookUp(Build) 10.00 root  ",
          "│ │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t3, index:keycol(keycol, pad1, pad2) range:[\"c\",\"c\"], keep order:false, stats:pseudo",
          "│ │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│ └─IndexLookUp(Probe) 12.50 root  ",
          "│   ├─Selection(Build) 18.10 cop[tikv]  not(isnull(test.t1.col3))",
          "│   │ └─IndexRangeScan 18.12 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo",
          "│   └─Selection(Probe) 12.50 cop[tikv]  ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))",
          "│     └─TableRowIDScan 18.10 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12.50 root  ",
          "  ├─Selection(Build) 12.50 cop[tikv]  ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")",
          "  │ └─IndexRangeScan 12.50 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12.50 cop[tikv]  in(test.t2.col1, \"a\", \"b\")",
          "    └─TableRowIDScan 12.50 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' SELECT t1.pk FROM t1 LEFT JOIN t2 ON t1.col1 = t2.pk LEFT JOIN t3 ON t1.col3 = t3.pk WHERE t2.col1 IN ('a' , 'b') AND t3.keycol = 'c' AND t1.col2 = 'a' AND t1.col1 != 'abcdef' AND t1.col1 != 'aaaaaa'",
        "Plan": [
          "IndexHashJoin 13.81 root  inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)",
          "├─IndexHashJoin(Build) 12.50 root  inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)",
          "│ ├─IndexLookUp(Build) 10.00 root  ",
          "│ │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t3, index:keycol(keycol, pad1, pad2) range:[\"c\",\"c\"], keep order:false, stats:pseudo",
          "│ │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│ └─IndexLookUp(Probe) 12.50 root  ",
          "│   ├─Selection(Build) 18.10 cop[tikv]  not(isnull(test.t1.col3))",
          "│   │ └─IndexRangeScan 18.12 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo",
          "│   └─Selection(Probe) 12.50 cop[tikv]  ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))",
          "│     └─TableRowIDScan 18.10 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12.50 root  ",
          "  ├─Selection(Build) 12.50 cop[tikv]  ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")",
          "  │ └─IndexRangeScan 12.50 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12.50 cop[tikv]  in(test.t2.col1, \"a\", \"b\")",
          "    └─TableRowIDScan 12.50 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestDecorrelateInnerJoinInSubquery",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t where exists (select 1 from t t1 join t t2 where t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 8000.00 root  semi join, equal:[eq(test.t.a, test.t.a)]",
          "├─HashJoin(Build) 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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: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"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where exists (select 1 from t t1 join t t2 on t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 8000.00 root  semi join, equal:[eq(test.t.a, test.t.a)]",
          "├─HashJoin(Build) 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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: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"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 join t t2 where t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─HashAgg(Build) 8000.00 root  group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a",
          "│ └─HashJoin 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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: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"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 join t t2 on t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─HashAgg(Build) 8000.00 root  group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a",
          "│ └─HashJoin 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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: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"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ hash_join_build(t) */ * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 join t t2 where t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─HashAgg(Probe) 8000.00 root  group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a",
          "  └─HashJoin 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ hash_join_probe(t) */ * from t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from t t1 join t t2 where t1.a = t2.a and t1.a = t.a)",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─HashAgg(Build) 8000.00 root  group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a",
          "│ └─HashJoin 12500.00 root  inner join, equal:[eq(test.t.a, test.t.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: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"
        ]
      }
    ]
  },
  {
    "Name": "TestDecorrelateLimitInSubquery",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from test t1 where exists (select value from test t2 where t1.id = t2.id limit 1)",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(1)->Column#7",
          "└─HashJoin 7992.00 root  semi join, equal:[eq(test.test.id, test.test.id)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.test.id))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9990.00 root  data:Selection",
          "    └─Selection 9990.00 cop[tikv]  not(isnull(test.test.id))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from test t1 where exists (select value from test t2 where t1.id = t2.id)",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(1)->Column#7",
          "└─HashJoin 7992.00 root  semi join, equal:[eq(test.test.id, test.test.id)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.test.id))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9990.00 root  data:Selection",
          "    └─Selection 9990.00 cop[tikv]  not(isnull(test.test.id))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from test t1 where exists (select value from test t2 where t1.id = t2.id limit 1,2)",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(1)->Column#7",
          "└─Apply 10000.00 root  CARTESIAN semi join",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─Limit(Probe) 20000.00 root  offset:1, count:2",
          "    └─TableReader 30000.00 root  data:Limit",
          "      └─Limit 30000.00 cop[tikv]  offset:0, count:3",
          "        └─Selection 30000.00 cop[tikv]  eq(test.test.id, test.test.id)",
          "          └─TableFullScan 30000000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where 9 in (select c from t s where s.c < t.c limit 3)",
        "Plan": [
          "Apply 10000.00 root  CARTESIAN semi join",
          "├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─Selection(Probe) 24000.00 root  eq(9, test.t.c)",
          "  └─Limit 30000.00 root  offset:0, count:3",
          "    └─TableReader 30000.00 root  data:Limit",
          "      └─Limit 30000.00 cop[tikv]  offset:0, count:3",
          "        └─Selection 30000.00 cop[tikv]  lt(test.t.c, test.t.c)",
          "          └─TableFullScan 37500.00 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestMultiColMaxOneRow",
    "Cases": [
      {
        "SQL": "select (select c from t2 where t2.a = t1.a and t2.b = 1) from t1",
        "Plan": [
          "HashJoin 10000.00 root  left outer join, equal:[eq(test.t1.a, test.t2.a)]",
          "├─TableReader(Build) 10.00 root  data:Selection",
          "│ └─Selection 10.00 cop[tikv]  eq(test.t2.b, 1)",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select (select c from t2 where t2.a = t1.a and (t2.b = 1 or t2.b = 2)) from t1",
        "Plan": [
          "Projection 10000.00 root  test.t2.c",
          "└─Apply 10000.00 root  CARTESIAN left outer join",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─MaxOneRow(Probe) 10000.00 root  ",
          "    └─IndexLookUp 200.00 root  ",
          "      ├─Selection(Build) 200.00 cop[tikv]  or(eq(test.t2.b, 1), eq(test.t2.b, 2))",
          "      │ └─IndexRangeScan 100000.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo",
          "      └─TableRowIDScan(Probe) 200.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue24095",
    "Cases": [
      {
        "SQL": "select count(*) from t join (select t.id, t.value v1 from t join t t1 on t.id = t1.id order by t.value limit 1) v on v.id = t.id and v.v1 = t.value;",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#10",
          "└─HashJoin 1.00 root  inner join, equal:[eq(test.t.id, test.t.id) eq(test.t.value, test.t.value)]",
          "  ├─Selection(Build) 0.80 root  not(isnull(test.t.id)), not(isnull(test.t.value))",
          "  │ └─TopN 1.00 root  test.t.value, offset:0, count:1",
          "  │   └─HashJoin 12487.50 root  inner join, equal:[eq(test.t.id, test.t.id)]",
          "  │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t.id))",
          "  │     │   └─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.id))",
          "  │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9980.01 root  data:Selection",
          "    └─Selection 9980.01 cop[tikv]  not(isnull(test.t.id)), not(isnull(test.t.value))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestSequenceAsDataSource",
    "Cases": [
      {
        "SQL": "select 1 from s1",
        "Plan": [
          "Projection 1.00 root  1->Column#1",
          "└─TableDual 1.00 root  rows:1"
        ]
      },
      {
        "SQL": "select count(1) from s1",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#1",
          "└─TableDual 1.00 root  rows:1"
        ]
      },
      {
        "SQL": "select count(*) from s1",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#1",
          "└─TableDual 1.00 root  rows:1"
        ]
      },
      {
        "SQL": "select sum(1) from s1",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(1)->Column#1",
          "└─TableDual 1.00 root  rows:1"
        ]
      },
      {
        "SQL": "select count(1) as cnt from s1 union select count(1) as cnt from s2",
        "Plan": [
          "HashAgg 2.00 root  group by:Column#3, funcs:firstrow(Column#3)->Column#3",
          "└─Union 2.00 root  ",
          "  ├─StreamAgg 1.00 root  funcs:count(1)->Column#1",
          "  │ └─TableDual 1.00 root  rows:1",
          "  └─StreamAgg 1.00 root  funcs:count(1)->Column#2",
          "    └─TableDual 1.00 root  rows:1"
        ]
      }
    ]
  },
  {
    "Name": "TestIsMatchProp",
    "Cases": [
      {
        "SQL": "select a, b, c from t1 where a > 3 and b = 4 order by a, c",
        "Plan": [
          "IndexReader 3.33 root  index:Selection",
          "└─Selection 3.33 cop[tikv]  eq(test.t1.b, 4)",
          "  └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx_a_b_c(a, b, c) range:(3,+inf], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from t2 where a = 1 and c = 2 order by b, d",
        "Plan": [
          "IndexReader 0.01 root  index:Selection",
          "└─Selection 0.01 cop[tikv]  eq(test.t2.c, 2)",
          "  └─IndexRangeScan 10.00 cop[tikv] table:t2, index:idx_a_b_c_d(a, b, c, d) range:[1,1], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "select a, b, c from t1 where (a = 1 and b = 1 and c = 1) or (a = 1 and b = 1 and c = 2) order by c",
        "Plan": [
          "IndexReader 0.03 root  index:IndexRangeScan",
          "└─IndexRangeScan 0.03 cop[tikv] table:t1, index:idx_a_b_c(a, b, c) range:[1 1 1,1 1 2], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "select a, b, c from t1 where (a = 1 and b = 1 and c < 3) or (a = 1 and b = 1 and c > 6) order by c",
        "Plan": [
          "IndexReader 0.67 root  index:IndexRangeScan",
          "└─IndexRangeScan 0.67 cop[tikv] table:t1, index:idx_a_b_c(a, b, c) range:[1 1 -inf,1 1 3), (1 1 6,1 1 +inf], keep order:true, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from t2 where ((a = 1 and b = 1 and d < 3) or (a = 1 and b = 1 and d > 6)) and c = 3 order by d",
        "Plan": [
          "IndexReader 0.00 root  index:Selection",
          "└─Selection 0.00 cop[tikv]  eq(test.t2.c, 3), or(and(eq(test.t2.a, 1), and(eq(test.t2.b, 1), lt(test.t2.d, 3))), and(eq(test.t2.a, 1), and(eq(test.t2.b, 1), gt(test.t2.d, 6))))",
          "  └─IndexRangeScan 10.00 cop[tikv] table:t2, index:idx_a_b_c_d(a, b, c, d) range:[1,1], keep order:true, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestHeuristicIndexSelection",
    "Cases": [
      {
        "SQL": "select * from t1 where a = 3 or a = 5",
        "Plan": [
          "Batch_Point_Get_5 2.00 887.04 root table:t1 handle:[3 5], keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 handle of t1 is selected since the path only has point ranges"
        ]
      },
      {
        "SQL": "select f, g from t1 where f = 2 and g in (3, 4, 5)",
        "Plan": [
          "Batch_Point_Get_5 3.00 380.16 root table:t1, index:f_g(f, g) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 unique index f_g of t1 is selected since the path only has point ranges with single scan"
        ]
      },
      {
        "SQL": "select * from t1 where c = 1 and (d = 2 or d = 3) and e in (4, 5)",
        "Plan": [
          "Batch_Point_Get_5 4.00 1774.08 root table:t1, index:c_d_e(c, d, e) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 unique index c_d_e of t1 is selected since the path only has point ranges with double scan"
        ]
      },
      {
        "SQL": "select f, g from t1 where f = 2 and g > 3",
        "Plan": [
          "IndexReader_6 33.33 733.82 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 33.33 6783.33 cop[tikv] table:t1, index:f_g(f, g) range:(2 3,2 +inf], keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 unique index f_g of t1 is selected since the path only fetches limited number of rows with single scan"
        ]
      },
      {
        "SQL": "select a, b, c from t2 where a = 1 and b = 2 and c in (1, 2, 3, 4, 5)",
        "Plan": [
          "Selection_6 0.01 289.88 root  eq(test.t2.b, 2), in(test.t2.c, 1, 2, 3, 4, 5)",
          "└─Point_Get_5 1.00 190.08 root table:t2, index:idx_a(a) "
        ],
        "Warnings": [
          "Note 1105 unique index idx_a of t2 is selected since the path only has point ranges with double scan"
        ]
      },
      {
        "SQL": "select * from t3 where (a = 1 or a = 3) and b = 'xx'",
        "Plan": [
          "Batch_Point_Get_5 2.00 1449.36 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 handle of t3 is selected since the path only has point ranges"
        ]
      },
      {
        "SQL": "select * from t4 where (a = 1 or a = 3) and b = 'xx'",
        "Plan": [
          "Batch_Point_Get_5 2.00 1449.36 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 unique index PRIMARY of t4 is selected since the path only has point ranges with double scan"
        ]
      },
      {
        "SQL": "select a, b from t3 where (a = 1 or a = 3) and b = 'xx'",
        "Plan": [
          "Batch_Point_Get_5 2.00 1322.64 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 handle of t3 is selected since the path only has point ranges"
        ]
      },
      {
        "SQL": "select a, b from t4 where (a = 1 or a = 3) and b = 'xx'",
        "Plan": [
          "Batch_Point_Get_5 2.00 1322.64 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 unique index PRIMARY of t4 is selected since the path only has point ranges with single scan"
        ]
      },
      {
        "SQL": "update t1 set b = 2 where a = 4 or a = 6",
        "Plan": [
          "Update_4 N/A N/A root  N/A",
          "└─Batch_Point_Get_6 2.00 887.04 root table:t1 handle:[4 6], keep order:false, desc:false"
        ],
        "Warnings": [
          "Note 1105 handle of t1 is selected since the path only has point ranges"
        ]
      },
      {
        "SQL": "delete from t1 where f = 2 and g in (3, 4)",
        "Plan": [
          "Delete_4 N/A N/A root  N/A",
          "└─Selection_7 2.00 493.42 root  in(test.t1.g, 3, 4)",
          "  └─Point_Get_6 1.00 443.52 root table:t1, index:f(f) "
        ],
        "Warnings": [
          "Note 1105 unique index f of t1 is selected since the path only has point ranges with double scan"
        ]
      },
      {
        "SQL": "insert into t3 select a, b, c from t1 where f = 2",
        "Plan": [
          "Insert_1 N/A N/A root  N/A",
          "└─Projection_6 1.00 253.74 root  test.t1.a, test.t1.b, test.t1.c",
          "  └─Point_Get_7 1.00 253.44 root table:t1, index:f(f) "
        ],
        "Warnings": [
          "Note 1105 unique index f of t1 is selected since the path only has point ranges with double scan"
        ]
      },
      {
        "SQL": "replace into t3 select a, b, c from t1 where a = 3",
        "Plan": [
          "Insert_1 N/A N/A root  N/A",
          "└─Point_Get_7 1.00 190.08 root table:t1 handle:3"
        ],
        "Warnings": [
          "Note 1105 handle of t1 is selected since the path only has point ranges"
        ]
      }
    ]
  },
  {
    "Name": "TestOutputSkylinePruningInfo",
    "Cases": [
      {
        "SQL": "select * from t where a > 1 order by f",
        "Plan": [
          "Sort_5 3333.33 2146348.14 root  test.t.f",
          "└─TableReader_9 3333.33 160128.74 root  data:TableRangeScan_8",
          "  └─TableRangeScan_8 3333.33 923531.15 cop[tikv] table:t range:(1,+inf], keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [t] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "select * from t where f > 1",
        "Plan": [
          "TableReader_7 3333.33 316532.90 root  data:Selection_6",
          "└─Selection_6 3333.33 3269593.45 cop[tikv]  gt(test.t.f, 1)",
          "  └─TableFullScan_5 10000.00 2770593.45 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [t,f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "select f from t where f > 1",
        "Plan": [
          "IndexReader_6 3333.33 50257.78 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 3333.33 542666.67 cop[tikv] table:t, index:f(f) range:(1,+inf], keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "select * from t where f > 3 and g = 5",
        "Plan": [
          "IndexLookUp_15 3.33 19551.99 root  ",
          "├─IndexRangeScan_12(Build) 10.00 2035.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo",
          "└─Selection_14(Probe) 3.33 3269.59 cop[tikv]  gt(test.t.f, 3)",
          "  └─TableRowIDScan_13 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [t,f_g,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "select * from t where g = 5 order by f",
        "Plan": [
          "Sort_5 10.00 21321.97 root  test.t.f",
          "└─IndexLookUp_13 10.00 19545.34 root  ",
          "  ├─IndexRangeScan_11(Build) 10.00 2035.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo",
          "  └─TableRowIDScan_12(Probe) 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [t,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "select * from t where d = 3 order by c, e",
        "Plan": [
          "IndexLookUp_15 10.00 215519.24 root  ",
          "├─Selection_14(Build) 10.00 2941000.00 cop[tikv]  eq(test.t.d, 3)",
          "│ └─IndexFullScan_12 10000.00 2442000.00 cop[tikv] table:t, index:c_d_e(c, d, e) keep order:true, stats:pseudo",
          "└─TableRowIDScan_13(Probe) 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warnings": [
          "Note 1105 [t,c_d_e] remain after pruning paths for t given Prop{SortItems: [{test.t.c asc} {test.t.e asc}], TaskTp: rootTask}"
        ]
      }
    ]
  },
  {
    "Name": "TestPreferRangeScanForUnsignedIntHandle",
    "Cases": [
      {
        "SQL": "set tidb_opt_prefer_range_scan = 0",
        "Plan": null,
        "Warnings": null
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b > 5",
        "Plan": [
          "TableReader_7 3.00 130.42 root  data:Selection_6",
          "└─Selection_6 3.00 1386.04 cop[tikv]  gt(test.t.b, 5)",
          "  └─TableFullScan_5 5.00 1136.54 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b = 6 order by a limit 1",
        "Plan": [
          "Limit_11 0.00 98.74 root  offset:0, count:1",
          "└─TableReader_24 0.00 98.74 root  data:Limit_23",
          "  └─Limit_23 0.00 1386.04 cop[tikv]  offset:0, count:1",
          "    └─Selection_22 0.00 1386.04 cop[tikv]  eq(test.t.b, 6)",
          "      └─TableFullScan_21 5.00 1136.54 cop[tikv] table:t keep order:true"
        ],
        "Warnings": null
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b = 6 limit 1",
        "Plan": [
          "Limit_8 0.00 98.74 root  offset:0, count:1",
          "└─TableReader_13 0.00 98.74 root  data:Limit_12",
          "  └─Limit_12 0.00 1386.04 cop[tikv]  offset:0, count:1",
          "    └─Selection_11 0.00 1386.04 cop[tikv]  eq(test.t.b, 6)",
          "      └─TableFullScan_10 5.00 1136.54 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      },
      {
        "SQL": "set tidb_opt_prefer_range_scan = 1",
        "Plan": null,
        "Warnings": null
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b > 5",
        "Plan": [
          "IndexLookUp_7 3.00 5856.46 root  ",
          "├─IndexRangeScan_5(Build) 3.00 610.50 cop[tikv] table:t, index:idx_b(b) range:(5,+inf], keep order:false",
          "└─TableRowIDScan_6(Probe) 3.00 681.92 cop[tikv] table:t keep order:false"
        ],
        "Warnings": [
          "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b = 6 order by a limit 1",
        "Plan": [
          "TopN_9 0.00 1956.63 root  test.t.a, offset:0, count:1",
          "└─IndexLookUp_16 0.00 1951.83 root  ",
          "  ├─TopN_15(Build) 0.00 206.70 cop[tikv]  test.t.a, offset:0, count:1",
          "  │ └─IndexRangeScan_13 0.00 203.50 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false",
          "  └─TableRowIDScan_14(Probe) 0.00 186.61 cop[tikv] table:t keep order:false"
        ],
        "Warnings": [
          "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: copDoubleReadTask}"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t where b = 6 limit 1",
        "Plan": [
          "IndexLookUp_13 0.00 1170.97 root  limit embedded(offset:0, count:1)",
          "├─Limit_12(Build) 0.00 203.50 cop[tikv]  offset:0, count:1",
          "│ └─IndexRangeScan_10 0.00 203.50 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false",
          "└─TableRowIDScan_11(Probe) 0.00 186.61 cop[tikv] table:t keep order:false"
        ],
        "Warnings": [
          "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: copDoubleReadTask}"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue27083",
    "Cases": [
      {
        "SQL": "select * from t use index (idx_b) where b = 2 limit 1",
        "Plan": [
          "IndexLookUp 1.00 root  limit embedded(offset:0, count:1)",
          "├─Limit(Build) 1.00 cop[tikv]  offset:0, count:1",
          "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:idx_b(b) range:[2,2], keep order:false",
          "└─TableRowIDScan(Probe) 1.00 cop[tikv] table:t keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestGroupBySetVar",
    "Cases": [
      {
        "SQL": "select floor(dt.rn/2) rownum, count(c1) from (select @rownum := @rownum + 1 rn, c1 from (select @rownum := -1) drn, t1) dt group by floor(dt.rn/2) order by rownum;",
        "Plan": [
          "Sort 1.00 root  Column#6",
          "└─Projection 1.00 root  floor(div(cast(Column#4, decimal(20,0) BINARY), 2))->Column#6, Column#5",
          "  └─HashAgg 1.00 root  group by:Column#13, funcs:count(Column#11)->Column#5, funcs:firstrow(Column#12)->Column#4",
          "    └─Projection 10000.00 root  test.t1.c1, Column#4, floor(div(cast(Column#4, decimal(20,0) BINARY), 2))->Column#13",
          "      └─Projection 10000.00 root  setvar(rownum, plus(getvar(rownum), 1))->Column#4, test.t1.c1",
          "        └─HashJoin 10000.00 root  CARTESIAN inner join",
          "          ├─Projection(Build) 1.00 root  setvar(rownum, -1)->Column#1",
          "          │ └─TableDual 1.00 root  rows:1",
          "          └─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "            └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select @n:=@n+1 as e from ta group by e",
        "Plan": [
          "Projection 1.00 root  setvar(n, plus(getvar(n), 1))->Column#4",
          "└─HashAgg 1.00 root  group by:Column#8, funcs:firstrow(1)->Column#7",
          "  └─Projection 10000.00 root  setvar(n, plus(cast(getvar(n), double BINARY), 1))->Column#8",
          "    └─TableReader 10000.00 root  data:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select @n:=@n+a as e from ta group by e",
        "Plan": [
          "Projection 8000.00 root  setvar(n, plus(getvar(n), cast(test.ta.a, double BINARY)))->Column#4",
          "└─HashAgg 8000.00 root  group by:Column#7, funcs:firstrow(Column#6)->test.ta.a",
          "  └─Projection 10000.00 root  test.ta.a, setvar(n, plus(getvar(n), cast(test.ta.a, double BINARY)))->Column#7",
          "    └─TableReader 10000.00 root  data:TableFullScan",
          "      └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from (select @n:=@n+1 as e from ta) tt group by e",
        "Plan": [
          "HashAgg 1.00 root  group by:Column#4, funcs:firstrow(Column#4)->Column#4",
          "└─Projection 10000.00 root  setvar(n, plus(getvar(n), 1))->Column#4",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select * from (select @n:=@n+a as e from ta) tt group by e",
        "Plan": [
          "HashAgg 8000.00 root  group by:Column#4, funcs:firstrow(Column#4)->Column#4",
          "└─Projection 10000.00 root  setvar(n, plus(getvar(n), cast(test.ta.a, double BINARY)))->Column#4",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select a from ta group by @n:=@n+1",
        "Plan": [
          "HashAgg 1.00 root  group by:Column#5, funcs:firstrow(Column#4)->test.ta.a",
          "└─Projection 10000.00 root  test.ta.a, setvar(n, plus(getvar(n), 1))->Column#5",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "select a from ta group by @n:=@n+a",
        "Plan": [
          "HashAgg 8000.00 root  group by:Column#5, funcs:firstrow(Column#4)->test.ta.a",
          "└─Projection 10000.00 root  test.ta.a, setvar(n, plus(getvar(n), cast(test.ta.a, double BINARY)))->Column#5",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue30200",
    "Cases": [
      {
        "SQL": "select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and from_base64(to_base64(c1)) = 'ab';",
        "Plan": [
          "Projection 15.99 root  1->Column#5",
          "└─Selection 15.99 root  or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(from_base64(to_base64(test.t1.c1)), \"ab\")))",
          "  └─IndexMerge 19.99 root  type: union",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'ab' or c2 = '10' and char_length(left(c1, 10)) = 10;",
        "Plan": [
          "Projection 17.99 root  1->Column#5",
          "└─Selection 0.04 root  or(eq(test.t1.c1, \"ab\"), and(eq(test.t1.c2, \"10\"), eq(char_length(left(test.t1.c1, 10)), 10)))",
          "  └─IndexMerge 19.99 root  type: union",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"ab\",\"ab\"], keep order:false, stats:pseudo",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(tt1) */ 1 from tt1 where c1 = 'de' or c2 = '10' and from_base64(to_base64(c3)) = '10';",
        "Plan": [
          "Projection 15.99 root  1->Column#6",
          "└─Selection 15.99 root  or(eq(test.tt1.c1, \"de\"), and(eq(test.tt1.c2, \"10\"), eq(from_base64(to_base64(test.tt1.c3)), \"10\")))",
          "  └─IndexMerge 19.99 root  type: union",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tt1, index:idx_0(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo",
          "    ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tt1, index:idx_1(c2, c3) range:[\"10\",\"10\"], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 19.99 cop[tikv] table:tt1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge( tt2 ) */ 1 from tt2 where tt2.c1 in (-3896405) or tt2.pk in (1, 53330) and to_base64(left(pk, 5));",
        "Plan": [
          "Projection 2.40 root  1->Column#3",
          "└─Selection 2.40 root  or(eq(test.tt2.c1, -3896405), and(in(test.tt2.pk, 1, 53330), istrue_with_null(cast(to_base64(left(cast(test.tt2.pk, var_string(20)), 5)), double BINARY))))",
          "  └─IndexMerge 3.00 root  type: union",
          "    ├─IndexRangeScan(Build) 1.00 cop[tikv] table:tt2, index:c1(c1) range:[-3896405,-3896405], keep order:false, stats:pseudo",
          "    ├─TableRangeScan(Build) 2.00 cop[tikv] table:tt2 range:[1,1], [53330,53330], keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tt2 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select /*+ use_index_merge(tt3) */ 1 from tt3 where c1 < -10 or c2 < 10 and reverse(c3) = '2';",
        "Plan": [
          "Projection 5098.44 root  1->Column#5",
          "└─Selection 2825.66 root  or(lt(test.tt3.c1, -10), and(lt(test.tt3.c2, 10), eq(reverse(cast(test.tt3.c3, var_string(20))), \"2\")))",
          "  └─IndexMerge 5542.21 root  type: union",
          "    ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c1(c1) range:[-inf,-10), keep order:false, stats:pseudo",
          "    ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo",
          "    └─TableRowIDScan(Probe) 5542.21 cop[tikv] table:tt3 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      },
      {
        "SQL": "select 1 from t1 where c1 = 'de' or c2 = '10' and from_base64(to_base64(c1)) = 'ab';",
        "Plan": [
          "Projection 8000.00 root  1->Column#5",
          "└─Selection 8000.00 root  or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(from_base64(to_base64(test.t1.c1)), \"ab\")))",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexMergeWithCorrelatedColumns",
    "Cases": [
      {
        "SQL": "select * from t2 where c1 < all(select /*+ use_index_merge(t1) */ c1 from t1 where (c1 = 10 and c1 = t2.c3 or c2 = 1 and c2 = t2.c3) and substring(c3, 10)) order by c1;",
        "Plan": [
          "Sort 10000.00 root  test.t2.c1",
          "└─Projection 10000.00 root  test.t2.c1, test.t2.c2, test.t2.c3",
          "  └─Apply 10000.00 root  CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))",
          "    ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "    │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "    └─StreamAgg(Probe) 10000.00 root  funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10",
          "      └─IndexMerge 63.35 root  type: union",
          "        ├─Selection(Build) 10000.00 cop[tikv]  eq(10, test.t2.c3)",
          "        │ └─TableRangeScan 10000.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo",
          "        ├─Selection(Build) 80000.00 cop[tikv]  eq(1, test.t2.c3)",
          "        │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo",
          "        └─Selection(Probe) 63.35 cop[tikv]  or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)",
          "          └─TableRowIDScan 89992.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1 1 1",
          "2 2 2"
        ]
      },
      {
        "SQL": "select * from t2 where c1 < all(select /*+ use_index_merge(t1) */ c1 from t1 where (c1 = 10 and c1 = t2.c3 or c2 = 1 and c2 = t2.c3) and reverse(c3)) order by c1;",
        "Plan": [
          "Sort 10000.00 root  test.t2.c1",
          "└─Projection 10000.00 root  test.t2.c1, test.t2.c2, test.t2.c3",
          "  └─Apply 10000.00 root  CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))",
          "    ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "    │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "    └─StreamAgg(Probe) 10000.00 root  funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10",
          "      └─IndexMerge 63.35 root  type: union",
          "        ├─Selection(Build) 10000.00 cop[tikv]  eq(10, test.t2.c3)",
          "        │ └─TableRangeScan 10000.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo",
          "        ├─Selection(Build) 80000.00 cop[tikv]  eq(1, test.t2.c3)",
          "        │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo",
          "        └─Selection(Probe) 63.35 cop[tikv]  or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), reverse(cast(test.t1.c3, var_string(20)))",
          "          └─TableRowIDScan 89992.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "2 2 2"
        ]
      },
      {
        "SQL": "select * from t2 where c1 < all(select /*+ use_index_merge(t1) */ c1 from t1 where (c1 >= 10 and c1 = t2.c3 or c2 = 1 and c2 = t2.c3) and substring(c3, 10)) order by c1;",
        "Plan": [
          "Sort 10000.00 root  test.t2.c1",
          "└─Projection 10000.00 root  test.t2.c1, test.t2.c2, test.t2.c3",
          "  └─Apply 10000.00 root  CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))",
          "    ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "    │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "    └─StreamAgg(Probe) 10000.00 root  funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10",
          "      └─IndexMerge 30263.46 root  type: union",
          "        ├─Selection(Build) 33333.33 cop[tikv]  eq(test.t1.c1, test.t2.c3)",
          "        │ └─TableRangeScan 33333333.33 cop[tikv] table:t1 range:[10,+inf], keep order:false, stats:pseudo",
          "        ├─Selection(Build) 80000.00 cop[tikv]  eq(1, test.t2.c3)",
          "        │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo",
          "        └─Selection(Probe) 30263.46 cop[tikv]  or(and(ge(test.t1.c1, 10), eq(test.t1.c1, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)",
          "          └─TableRowIDScan 33386666.67 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1 1 1",
          "2 2 2"
        ]
      },
      {
        "SQL": "select c_int from tt1 where c_decimal < all (select /*+ use_index_merge(tt2) */ c_decimal from tt2 where tt1.c_int = tt2.c_int and tt1.c_datetime > tt2.c_datetime and tt2.c_decimal = 9.060 or tt2.c_str <= 'interesting shtern' and tt1.c_int = tt2.c_int) order by 1;",
        "Plan": [
          "Projection 10000.00 root  test.tt1.c_int",
          "└─Apply 10000.00 root  CARTESIAN inner join, other cond:or(and(lt(test.tt1.c_decimal, Column#9), if(ne(Column#10, 0), NULL, 1)), or(eq(Column#11, 0), if(isnull(test.tt1.c_decimal), NULL, 0)))",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:tt1 keep order:true, stats:pseudo",
          "  └─StreamAgg(Probe) 10000.00 root  funcs:min(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11",
          "    └─Projection 11.05 root  test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15",
          "      └─IndexMerge 11.05 root  type: union",
          "        ├─Selection(Build) 10.00 cop[tikv]  eq(test.tt1.c_int, test.tt2.c_int)",
          "        │ └─IndexRangeScan 10000.00 cop[tikv] table:tt2, index:c_decimal(c_decimal) range:[9.060000,9.060000], keep order:false, stats:pseudo",
          "        ├─Selection(Build) 33233.33 cop[tikv]  eq(test.tt1.c_int, test.tt2.c_int)",
          "        │ └─IndexRangeScan 33233333.33 cop[tikv] table:tt2, index:c_str(c_str) range:[-inf,\"interesting shtern\"], keep order:false, stats:pseudo",
          "        └─Selection(Probe) 11.05 cop[tikv]  or(and(eq(test.tt1.c_int, test.tt2.c_int), and(gt(test.tt1.c_datetime, test.tt2.c_datetime), eq(test.tt2.c_decimal, 9.060))), and(le(test.tt2.c_str, \"interesting shtern\"), eq(test.tt1.c_int, test.tt2.c_int)))",
          "          └─TableRowIDScan 33243.33 cop[tikv] table:tt2 keep order:false, stats:pseudo"
        ],
        "Res": [
          "7",
          "8",
          "10"
        ]
      },
      {
        "SQL": "select c_int from tt1 where c_decimal > all (select /*+ use_index_merge(tt2) */ c_decimal from tt2 where tt2.c_int = 7 and tt2.c_int < tt1.c_decimal or tt2.c_str >= 'zzzzzzzzzzzzzzzzzzz' and tt1.c_int = tt2.c_int) order by 1;",
        "Plan": [
          "Projection 10000.00 root  test.tt1.c_int",
          "└─Apply 10000.00 root  CARTESIAN inner join, other cond:or(and(gt(test.tt1.c_decimal, Column#9), if(ne(Column#10, 0), NULL, 1)), or(eq(Column#11, 0), if(isnull(test.tt1.c_decimal), NULL, 0)))",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:tt1 keep order:true, stats:pseudo",
          "  └─StreamAgg(Probe) 10000.00 root  funcs:max(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11",
          "    └─Projection 17.91 root  test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15",
          "      └─IndexMerge 17.91 root  type: union",
          "        ├─Selection(Build) 10000.00 cop[tikv]  lt(7, test.tt1.c_decimal)",
          "        │ └─TableRangeScan 10000.00 cop[tikv] table:tt2 range:[7,7], keep order:false, stats:pseudo",
          "        ├─Selection(Build) 33333.33 cop[tikv]  eq(test.tt1.c_int, test.tt2.c_int)",
          "        │ └─IndexRangeScan 33333333.33 cop[tikv] table:tt2, index:c_str(c_str) range:[\"zzzzzzzzzzzzzzzzzzz\",+inf], keep order:false, stats:pseudo",
          "        └─Selection(Probe) 17.91 cop[tikv]  or(and(eq(test.tt2.c_int, 7), lt(7, test.tt1.c_decimal)), and(ge(test.tt2.c_str, \"zzzzzzzzzzzzzzzzzzz\"), eq(test.tt1.c_int, test.tt2.c_int)))",
          "          └─TableRowIDScan 43330.00 cop[tikv] table:tt2 keep order:false, stats:pseudo"
        ],
        "Res": [
          "6",
          "7",
          "8",
          "9"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue31240",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from t31240;",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#6)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t31240._tidb_rowid)->Column#6",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t31240 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "set @@tidb_isolation_read_engines=\"tiflash,tidb\";",
        "Plan": null
      },
      {
        "SQL": "explain format = 'brief' select count(*) from t31240;",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#6)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t31240._tidb_rowid)->Column#6",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t31240 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestSelPushDownTiFlash",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t where t.a > 1 and t.b = \"flash\" or t.a + 3 * t.a = 5",
        "Plan": [
          "TableReader 8000.67 root  data:Selection",
          "└─Selection 8000.67 cop[tiflash]  or(and(gt(test.t.a, 1), eq(test.t.b, \"flash\")), eq(plus(test.t.a, mul(3, test.t.a)), 5))",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where cast(t.a as double) + 3 = 5.1",
        "Plan": [
          "TableReader 8000.00 root  data:Selection",
          "└─Selection 8000.00 cop[tiflash]  eq(plus(cast(test.t.a, double BINARY), 3), 5.1)",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where b > 'a' order by convert(b, unsigned) limit 2",
        "Plan": [
          "Projection 2.00 root  test.t.a, test.t.b",
          "└─TopN 2.00 root  Column#4, offset:0, count:2",
          "  └─Projection 2.00 root  test.t.a, test.t.b, cast(test.t.b, bigint(22) UNSIGNED BINARY)->Column#4",
          "    └─TableReader 2.00 root  data:Projection",
          "      └─Projection 2.00 batchCop[tiflash]  test.t.a, test.t.b",
          "        └─TopN 2.00 batchCop[tiflash]  Column#3, offset:0, count:2",
          "          └─Projection 3333.33 batchCop[tiflash]  test.t.a, test.t.b, cast(test.t.b, bigint(22) UNSIGNED BINARY)->Column#3",
          "            └─Selection 3333.33 batchCop[tiflash]  gt(test.t.b, \"a\")",
          "              └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where b > 'a' order by b limit 2",
        "Plan": [
          "TopN 2.00 root  test.t.b, offset:0, count:2",
          "└─TableReader 2.00 root  data:TopN",
          "  └─TopN 2.00 batchCop[tiflash]  test.t.b, offset:0, count:2",
          "    └─Selection 3333.33 batchCop[tiflash]  gt(test.t.b, \"a\")",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestVerboseExplain",
    "Cases": [
      {
        "SQL": "explain format = 'verbose' select count(*) from t3",
        "Plan": [
          "StreamAgg_20 1.00 102.69 root  funcs:count(Column#9)->Column#4",
          "└─IndexReader_21 1.00 52.79 root  index:StreamAgg_8",
          "  └─StreamAgg_8 1.00 760.20 cop[tikv]  funcs:count(1)->Column#9",
          "    └─IndexFullScan_19 3.00 610.50 cop[tikv] table:t3, index:c(b) keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select count(*) from t2",
        "Plan": [
          "StreamAgg_26 1.00 107.45 root  funcs:count(Column#7)->Column#4",
          "└─TableReader_27 1.00 57.55 root  data:StreamAgg_10",
          "  └─StreamAgg_10 1.00 831.62 cop[tikv]  funcs:count(1)->Column#7",
          "    └─TableFullScan_24 3.00 681.92 cop[tikv] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t3 order by a",
        "Plan": [
          "Sort_4 3.00 318.27 root  test.t3.a",
          "└─TableReader_8 3.00 70.81 root  data:TableFullScan_7",
          "  └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t3 order by b",
        "Plan": [
          "Sort_4 3.00 318.27 root  test.t3.b",
          "└─TableReader_8 3.00 70.81 root  data:TableFullScan_7",
          "  └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t3 order by a limit 1",
        "Plan": [
          "TopN_7 1.00 53.10 root  test.t3.a, offset:0, count:1",
          "└─TableReader_16 1.00 49.90 root  data:TopN_15",
          "  └─TopN_15 1.00 685.12 cop[tikv]  test.t3.a, offset:0, count:1",
          "    └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select * from t3 order by b limit 1",
        "Plan": [
          "TopN_7 1.00 53.10 root  test.t3.b, offset:0, count:1",
          "└─TableReader_16 1.00 49.90 root  data:TopN_15",
          "  └─TopN_15 1.00 685.12 cop[tikv]  test.t3.b, offset:0, count:1",
          "    └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select count(*) from t2 group by a",
        "Plan": [
          "HashAgg_8 3.00 1706.09 root  group by:test.t2.a, funcs:count(1)->Column#4",
          "└─TableReader_17 3.00 58.13 root  data:TableFullScan_16",
          "  └─TableFullScan_16 3.00 681.92 cop[tikv] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select count(*) from t3 where b = 0",
        "Plan": [
          "StreamAgg_10 1.00 64.98 root  funcs:count(1)->Column#4",
          "└─IndexReader_15 0.00 15.08 root  index:IndexRangeScan_14",
          "  └─IndexRangeScan_14 0.00 162.80 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select /*+ use_index(t3, c) */ count(a) from t3 where b = 0",
        "Plan": [
          "StreamAgg_10 1.00 2001.63 root  funcs:count(test.t3.a)->Column#4",
          "└─IndexLookUp_17 0.00 1951.73 root  ",
          "  ├─IndexRangeScan_15(Build) 0.00 203.50 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false",
          "  └─TableRowIDScan_16(Probe) 0.00 227.31 cop[tikv] table:t3 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select count(*) from t2 where a = 0",
        "Plan": [
          "StreamAgg_12 1.00 109.57 root  funcs:count(1)->Column#4",
          "└─TableReader_21 0.00 59.67 root  data:Selection_20",
          "  └─Selection_20 0.00 831.62 cop[tikv]  eq(test.t2.a, 0)",
          "    └─TableFullScan_19 3.00 681.92 cop[tikv] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select count(*) from t3 t join t3 on t.a = t3.b",
        "Plan": [
          "StreamAgg_10 1.00 2128.93 root  funcs:count(1)->Column#7",
          "└─HashJoin_40 3.00 1979.23 root  inner join, equal:[eq(test.t3.a, test.t3.b)]",
          "  ├─IndexReader_28(Build) 3.00 45.23 root  index:IndexFullScan_27",
          "  │ └─IndexFullScan_27 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false",
          "  └─TableReader_26(Probe) 3.00 68.11 root  data:Selection_25",
          "    └─Selection_25 3.00 831.62 cop[tikv]  not(isnull(test.t3.a))",
          "      └─TableFullScan_24 3.00 681.92 cop[tikv] table:t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a",
        "Plan": [
          "StreamAgg_15 1.00 62053.22 root  funcs:count(1)->Column#7",
          "└─TableReader_41 3.00 61903.52 root  data:ExchangeSender_40",
          "  └─ExchangeSender_40 3.00 928447.20 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin_37 3.00 928447.20 mpp[tiflash]  inner join, equal:[eq(test.t1.a, test.t2.a)]",
          "      ├─ExchangeReceiver_22(Build) 3.00 464290.40 mpp[tiflash]  ",
          "      │ └─ExchangeSender_21 3.00 464146.40 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection_20 3.00 464146.40 mpp[tiflash]  not(isnull(test.t1.a))",
          "      │     └─TableFullScan_19 3.00 464139.20 mpp[tiflash] table:t1 keep order:false",
          "      └─Selection_24(Probe) 3.00 464146.40 mpp[tiflash]  not(isnull(test.t2.a))",
          "        └─TableFullScan_23 3.00 464139.20 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b",
        "Plan": [
          "StreamAgg_15 1.00 71713.64 root  funcs:count(1)->Column#10",
          "└─HashJoin_59 3.00 71563.94 root  inner join, equal:[eq(test.t1.b, test.t3.b)]",
          "  ├─IndexReader_47(Build) 3.00 45.23 root  index:IndexFullScan_46",
          "  │ └─IndexFullScan_46 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false",
          "  └─TableReader_39(Probe) 3.00 69652.83 root  data:ExchangeSender_38",
          "    └─ExchangeSender_38 3.00 1044634.00 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─HashJoin_29 3.00 1044634.00 mpp[tiflash]  inner join, equal:[eq(test.t1.a, test.t2.a)]",
          "        ├─ExchangeReceiver_35(Build) 3.00 580476.40 mpp[tiflash]  ",
          "        │ └─ExchangeSender_34 3.00 580188.40 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection_33 3.00 580188.40 mpp[tiflash]  not(isnull(test.t1.a)), not(isnull(test.t1.b))",
          "        │     └─TableFullScan_32 3.00 580174.00 mpp[tiflash] table:t1 keep order:false",
          "        └─Selection_37(Probe) 3.00 464146.40 mpp[tiflash]  not(isnull(test.t2.a))",
          "          └─TableFullScan_36 3.00 464139.20 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select (2) in (select /*+ read_from_storage(tiflash[t1]) */ count(*) from t1) from (select t.b < (select /*+ read_from_storage(tiflash[t2]) */ t.b from t2 limit 1 )  from t3 t) t",
        "Plan": [
          "HashJoin_19 3.00 162261.76 root  CARTESIAN left outer semi join",
          "├─Selection_38(Build) 0.80 31045.01 root  eq(2, Column#18)",
          "│ └─StreamAgg_56 1.00 30995.11 root  funcs:count(Column#32)->Column#18",
          "│   └─TableReader_57 1.00 30945.21 root  data:StreamAgg_44",
          "│     └─StreamAgg_44 1.00 464146.40 batchCop[tiflash]  funcs:count(test.t1._tidb_rowid)->Column#32",
          "│       └─TableFullScan_55 3.00 464139.20 batchCop[tiflash] table:t1 keep order:false",
          "└─Projection_20(Probe) 3.00 129648.62 root  1->Column#28",
          "  └─Apply_22 3.00 129648.32 root  CARTESIAN left outer join",
          "    ├─IndexReader_26(Build) 3.00 53.37 root  index:IndexFullScan_25",
          "    │ └─IndexFullScan_25 3.00 610.50 cop[tikv] table:t, index:c(b) keep order:false",
          "    └─Projection_27(Probe) 3.00 43198.32 root  1->Column#26",
          "      └─Limit_30 3.00 43198.22 root  offset:0, count:1",
          "        └─TableReader_37 3.00 43198.22 root  data:ExchangeSender_36",
          "          └─ExchangeSender_36 3.00 647920.44 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─Limit_35 3.00 647920.44 mpp[tiflash]  offset:0, count:1",
          "              └─TableFullScan_34 3.00 647920.44 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'verbose' select /*+ merge_join(t1), read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a",
        "Plan": [
          "StreamAgg_14 1.00 62557.96 root  funcs:count(1)->Column#7",
          "└─MergeJoin_26 3.00 62408.26 root  inner join, left key:test.t1.a, right key:test.t2.a",
          "  ├─Sort_24(Build) 3.00 31202.63 root  test.t2.a",
          "  │ └─TableReader_23 3.00 30955.77 root  data:Selection_22",
          "  │   └─Selection_22 3.00 464146.40 cop[tiflash]  not(isnull(test.t2.a))",
          "  │     └─TableFullScan_21 3.00 464139.20 cop[tiflash] table:t2 keep order:false",
          "  └─Sort_20(Probe) 3.00 31202.63 root  test.t1.a",
          "    └─TableReader_19 3.00 30955.77 root  data:Selection_18",
          "      └─Selection_18 3.00 464146.40 cop[tiflash]  not(isnull(test.t1.a))",
          "        └─TableFullScan_17 3.00 464139.20 cop[tiflash] table:t1 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestRegardNULLAsPoint",
    "Cases": [
      {
        "SQL": "select * from tuk where a<=>null and b=1",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.01 root  index:Selection_6",
          "└─Selection_6 0.01 cop[tikv]  eq(test.tuk.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b=1",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tik, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.01 root  index:Selection_6",
          "└─Selection_6 0.01 cop[tikv]  eq(test.tik.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tuk where a<=>null and b>0 and b<2",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.25 root  index:Selection_6",
          "└─Selection_6 0.25 cop[tikv]  eq(test.tuk.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b>0 and b<2",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tik, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.25 root  index:Selection_6",
          "└─Selection_6 0.25 cop[tikv]  eq(test.tik.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tuk where a<=>null and b>=1 and b<2",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.25 root  index:Selection_6",
          "└─Selection_6 0.25 cop[tikv]  eq(test.tuk.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b>=1 and b<2",
        "PlanEnabled": [
          "IndexReader_6 0.10 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.10 cop[tikv] table:tik, index:a(a, b, c) range:[NULL 1,NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.25 root  index:Selection_6",
          "└─Selection_6 0.25 cop[tikv]  eq(test.tik.b, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 <nil>",
          "<nil> 1 <nil>",
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tuk where a<=>null and b=1 and c=1",
        "PlanEnabled": [
          "IndexReader_6 1.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 1.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL 1 1,NULL 1 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tuk.b, 1), eq(test.tuk.c, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b=1 and c=1",
        "PlanEnabled": [
          "IndexReader_6 0.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL 1 1,NULL 1 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tik.b, 1), eq(test.tik.c, 1)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> 1 1",
          "<nil> 1 1"
        ]
      },
      {
        "SQL": "select * from tuk where a=1 and b<=>null and c=1",
        "PlanEnabled": [
          "IndexReader_6 1.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 1.00 cop[tikv] table:tuk, index:a(a, b, c) range:[1 NULL 1,1 NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tuk.c, 1)",
          "  └─IndexRangeScan_5 0.10 cop[tikv] table:tuk, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "1 <nil> 1",
          "1 <nil> 1"
        ]
      },
      {
        "SQL": "select * from tik where a=1 and b<=>null and c=1",
        "PlanEnabled": [
          "IndexReader_6 0.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.00 cop[tikv] table:tik, index:a(a, b, c) range:[1 NULL 1,1 NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tik.c, 1)",
          "  └─IndexRangeScan_5 0.10 cop[tikv] table:tik, index:a(a, b, c) range:[1 NULL,1 NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "1 <nil> 1",
          "1 <nil> 1"
        ]
      },
      {
        "SQL": "select * from tuk where a<=>null and b<=>null and c=1",
        "PlanEnabled": [
          "IndexReader_6 1.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 1.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL NULL 1,NULL NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tuk.c, 1), nulleq(test.tuk.b, NULL)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> <nil> 1",
          "<nil> <nil> 1"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b<=>null and c=1",
        "PlanEnabled": [
          "IndexReader_6 0.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL NULL 1,NULL NULL 1], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  eq(test.tik.c, 1), nulleq(test.tik.b, NULL)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> <nil> 1",
          "<nil> <nil> 1"
        ]
      },
      {
        "SQL": "select * from tuk where a<=>null and b<=>null and c<=>null",
        "PlanEnabled": [
          "IndexReader_6 1.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 1.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL NULL NULL,NULL NULL NULL], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  nulleq(test.tuk.b, NULL), nulleq(test.tuk.c, NULL)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tuk, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> <nil> <nil>",
          "<nil> <nil> <nil>"
        ]
      },
      {
        "SQL": "select * from tik where a<=>null and b<=>null and c<=>null",
        "PlanEnabled": [
          "IndexReader_6 0.00 root  index:IndexRangeScan_5",
          "└─IndexRangeScan_5 0.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL NULL NULL,NULL NULL NULL], keep order:false, stats:pseudo"
        ],
        "PlanDisabled": [
          "IndexReader_7 0.00 root  index:Selection_6",
          "└─Selection_6 0.00 cop[tikv]  nulleq(test.tik.b, NULL), nulleq(test.tik.c, NULL)",
          "  └─IndexRangeScan_5 10.00 cop[tikv] table:tik, index:a(a, b, c) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil> <nil> <nil>",
          "<nil> <nil> <nil>"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownToTiFlashWithKeepOrder",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select max(a) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:max(test.t.a)->Column#3",
          "└─TopN 1.00 root  test.t.a:desc, offset:0, count:1",
          "  └─TableReader 1.00 root  data:TopN",
          "    └─TopN 1.00 batchCop[tiflash]  test.t.a:desc, offset:0, count:1",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(a) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:min(test.t.a)->Column#3",
          "└─Limit 1.00 root  offset:0, count:1",
          "  └─TableReader 1.00 root  data:Limit",
          "    └─Limit 1.00 cop[tiflash]  offset:0, count:1",
          "      └─TableFullScan 1.00 cop[tiflash] table:t keep order:true, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownToTiFlashWithKeepOrderInFastMode",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select max(a) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:max(test.t.a)->Column#3",
          "└─TopN 1.00 root  test.t.a:desc, offset:0, count:1",
          "  └─TableReader 1.00 root  data:TopN",
          "    └─TopN 1.00 batchCop[tiflash]  test.t.a:desc, offset:0, count:1",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select min(a) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:min(test.t.a)->Column#3",
          "└─TopN 1.00 root  test.t.a, offset:0, count:1",
          "  └─TableReader 1.00 root  data:TopN",
          "    └─TopN 1.00 batchCop[tiflash]  test.t.a, offset:0, count:1",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPJoin",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t where fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t, d2_t, d3_t where fact_t.d1_k = d1_t.d1_k and fact_t.d2_k = d2_t.d2_k and fact_t.d3_k = d3_t.d3_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#17",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d3_k, test.d3_t.d3_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d3_t.d3_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d3_t keep order:false",
          "      └─HashJoin(Probe) 8.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d2_k, test.d2_t.d2_k)]",
          "        ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d2_t.d2_k))",
          "        │     └─TableFullScan 2.00 mpp[tiflash] table:d2_t keep order:false",
          "        └─HashJoin(Probe) 8.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "          ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "          │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "          │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "          └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k)), not(isnull(test.fact_t.d2_k)), not(isnull(test.fact_t.d3_k))",
          "            └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t where fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 8.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "      │     └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col1 > d1_t.value",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)], other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col1 > 10",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], left cond:[gt(test.fact_t.col1, 10)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col2 > 10 and fact_t.col1 > d1_t.value",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], left cond:[gt(test.fact_t.col2, 10)], other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k and d1_t.value > 10",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], right cond:gt(test.d1_t.value, 10)",
          "      ├─ExchangeReceiver(Build) 8.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "      │     └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k and d1_t.value > 10 and fact_t.col1 > d1_t.value",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], right cond:gt(test.d1_t.value, 10), other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "      ├─ExchangeReceiver(Build) 8.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 8.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "      │     └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from d1_t where d1_k = fact_t.d1_k)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 8.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 8.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Projection 2.00 mpp[tiflash]  test.d1_t.d1_k",
          "      │     └─HashAgg 2.00 mpp[tiflash]  group by:test.d1_t.d1_k, funcs:firstrow(test.d1_t.d1_k)->test.d1_t.d1_k",
          "      │       └─ExchangeReceiver 2.00 mpp[tiflash]  ",
          "      │         └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "      │           └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │             └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select /*+ SEMI_JOIN_REWRITE() */ 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t join d1_t on fact_t.d1_k > d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 16.00 root  data:ExchangeSender",
          "  └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 16.00 mpp[tiflash]  CARTESIAN inner join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─Selection(Probe) 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "        └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k > d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 16.00 root  data:ExchangeSender",
          "  └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 16.00 mpp[tiflash]  CARTESIAN left outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k > d1_t.d1_k",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 16.00 root  data:ExchangeSender",
          "  └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 16.00 mpp[tiflash]  CARTESIAN right outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)",
          "      ├─ExchangeReceiver(Build) 8.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 8.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "      │     └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where d1_k not in (select d1_k from d1_t)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─TableReader 6.40 root  data:ExchangeSender",
          "  └─ExchangeSender 6.40 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 6.40 mpp[tiflash]  CARTESIAN anti semi join, other cond:eq(test.fact_t.d1_k, test.d1_t.d1_k)",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPLeftSemiJoin",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.a in (select a from test.t); -- left semi",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  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",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.a in (select a from test.t where b<t1.b); ",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  left outer semi join, equal:[eq(test.t.a, test.t.a)], other cond:lt(test.t.b, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.a not in (select a from test.t); -- left anti",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  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",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.a not in (select a from test.t where b<t1.b);",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  anti left outer semi join, equal:[eq(test.t.a, test.t.a)], other cond:lt(test.t.b, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.b in (select a from test.t); -- cartesian left semi",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.a in (select b from test.t where b<t1.b);",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.a, test.t.b), lt(test.t.b, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.b not in (select a from test.t); -- cartesian left anti",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from test.t t1 where t1.a>1 or t1.b not in (select a from test.t where b<t1.b);",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─Selection 8000.00 mpp[tiflash]  or(gt(test.t.a, 1), Column#7)",
          "      └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.a), lt(test.t.b, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select a in (select a from test.t), a not in (select a from test.t) from test.t; -- semi join as scalar",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#13, Column#17",
          "    └─HashJoin 10000.00 mpp[tiflash]  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",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─HashJoin(Probe) 10000.00 mpp[tiflash]  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",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select a in (select b from test.t), a not in (select b from test.t) from test.t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#13, Column#17",
          "    └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.a, test.t.b)",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.a, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select b in (select a from test.t), b not in (select a from test.t) from test.t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#13, Column#17",
          "    └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select b in (select b from test.t), b not in (select b from test.t) from test.t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#13, Column#17",
          "    └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.b)",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.b, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select a, b, a in (select a from test.t), a in (select b from test.t), b in (select a from test.t), b in (select b from test.t), a not in (select a from test.t), a not in (select b from test.t), b not in (select a from test.t), b not in (select b from test.t) from test.t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.b)",
          "    ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN anti left outer semi join, other cond:eq(test.t.a, test.t.b)",
          "        ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─HashJoin(Probe) 10000.00 mpp[tiflash]  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",
          "          │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "          └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.b, test.t.b)",
          "            ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "            │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "            │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "            └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.b, test.t.a)",
          "              ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "              │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "              └─HashJoin(Probe) 10000.00 mpp[tiflash]  CARTESIAN left outer semi join, other cond:eq(test.t.a, test.t.b)",
          "                ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "                │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "                │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "                └─HashJoin(Probe) 10000.00 mpp[tiflash]  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",
          "                  │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "                  └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      }
    ]
  },
  {
    "Name": "TestMPPOuterJoinBuildSideForBroadcastJoin",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from a left join b on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  left outer join, equal:[eq(test.a.id, test.b.id)]",
          "      ├─ExchangeReceiver(Build) 3.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "      │     └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:a keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from b right join a on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  right outer join, equal:[eq(test.b.id, test.a.id)]",
          "      ├─ExchangeReceiver(Build) 3.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "      │     └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false",
          "      └─TableFullScan(Probe) 2.00 mpp[tiflash] table:a keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPOuterJoinBuildSideForShuffleJoinWithFixedBuildSide",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from a left join b on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  left outer join, equal:[eq(test.a.id, test.b.id)]",
          "      ├─ExchangeReceiver(Build) 3.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.b.id, collate: binary]",
          "      │   └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "      │     └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false",
          "      └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "        └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.a.id, collate: binary]",
          "          └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from b right join a on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  right outer join, equal:[eq(test.b.id, test.a.id)]",
          "      ├─ExchangeReceiver(Build) 3.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.b.id, collate: binary]",
          "      │   └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "      │     └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false",
          "      └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "        └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.a.id, collate: binary]",
          "          └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPOuterJoinBuildSideForShuffleJoin",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from a left join b on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  left outer join, equal:[eq(test.a.id, test.b.id)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.a.id, collate: binary]",
          "      │   └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "      └─ExchangeReceiver(Probe) 3.00 mpp[tiflash]  ",
          "        └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.b.id, collate: binary]",
          "          └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "            └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from b right join a on a.id = b.id",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#7",
          "└─TableReader 2.00 root  data:ExchangeSender",
          "  └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 2.00 mpp[tiflash]  right outer join, equal:[eq(test.b.id, test.a.id)]",
          "      ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.a.id, collate: binary]",
          "      │   └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "      └─ExchangeReceiver(Probe) 3.00 mpp[tiflash]  ",
          "        └─ExchangeSender 3.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.b.id, collate: binary]",
          "          └─Selection 3.00 mpp[tiflash]  not(isnull(test.b.id))",
          "            └─TableFullScan 3.00 mpp[tiflash] table:b keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPShuffledJoin",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t where fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "              └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t, d2_t, d3_t where fact_t.d1_k = d1_t.d1_k and fact_t.d2_k = d2_t.d2_k and fact_t.d3_k = d3_t.d3_k",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#18)->Column#17",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#18",
          "      └─HashJoin 128.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d3_k, test.d3_t.d3_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d3_t.d3_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d3_t.d3_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d3_t keep order:false",
          "        └─ExchangeReceiver(Probe) 64.00 mpp[tiflash]  ",
          "          └─ExchangeSender 64.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d3_k, collate: binary]",
          "            └─HashJoin 64.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d2_k, test.d2_t.d2_k)]",
          "              ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d2_t.d2_k, collate: binary]",
          "              │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d2_t.d2_k))",
          "              │     └─TableFullScan 4.00 mpp[tiflash] table:d2_t keep order:false",
          "              └─ExchangeReceiver(Probe) 32.00 mpp[tiflash]  ",
          "                └─ExchangeSender 32.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d2_k, collate: binary]",
          "                  └─HashJoin 32.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "                    ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "                    │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "                    │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "                    │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "                    └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "                      └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "                        └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k)), not(isnull(test.fact_t.d2_k)), not(isnull(test.fact_t.d3_k))",
          "                          └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t where fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "              └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t, d1_t, d2_t, d3_t where fact_t.d1_k = d1_t.d1_k and fact_t.d1_k = d2_t.value and fact_t.d1_k = d3_t.value",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#18)->Column#17",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#18",
          "      └─HashJoin 128.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d1_k, test.d3_t.value)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d3_t.value, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d3_t.value))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d3_t keep order:false",
          "        └─HashJoin(Probe) 64.00 mpp[tiflash]  inner join, equal:[eq(test.fact_t.d1_k, test.d2_t.value)]",
          "          ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d2_t.value, collate: binary]",
          "          │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d2_t.value))",
          "          │     └─TableFullScan 4.00 mpp[tiflash] table:d2_t keep order:false",
          "          └─HashJoin(Probe) 32.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "            ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "            │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "            │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "            │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "            └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "              └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "                └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "                  └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "              └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col1 > d1_t.value",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)], other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "              └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col1 > 10",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], left cond:[gt(test.fact_t.col1, 10)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from (select case when t1.col1 is null then t2.col1 + 5 else 10 end as col1, t2.d1_k as d1_k from fact_t t1 right join fact_t t2 on t1.d1_k = t2.d1_k) fact_t join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col1 > 5",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#22)->Column#19",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#22",
          "      └─HashJoin 204.80 mpp[tiflash]  inner join, equal:[eq(test.d1_t.d1_k, test.fact_t.d1_k)]",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─Projection(Probe) 102.40 mpp[tiflash]  test.fact_t.d1_k",
          "          └─Selection 102.40 mpp[tiflash]  gt(case(isnull(test.fact_t.col1), plus(test.fact_t.col1, 5), 10), 5)",
          "            └─HashJoin 128.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.fact_t.d1_k)]",
          "              ├─ExchangeReceiver(Build) 16.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "              │   └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "              │     └─TableFullScan 16.00 mpp[tiflash] table:t1 keep order:false",
          "              └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "                └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "                  └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "                    └─TableFullScan 16.00 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k = d1_t.d1_k and fact_t.col2 > 10 and fact_t.col1 > d1_t.value",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  left outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], left cond:[gt(test.fact_t.col2, 10)], other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "        │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k and d1_t.value > 10",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], right cond:gt(test.d1_t.value, 10)",
          "        ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "        │   └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "        └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "          └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "            └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "              └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k = d1_t.d1_k and d1_t.value > 10 and fact_t.col1 > d1_t.value",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─HashJoin 32.00 mpp[tiflash]  right outer join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], right cond:gt(test.d1_t.value, 10), other cond:gt(test.fact_t.col1, test.d1_t.value)",
          "        ├─ExchangeReceiver(Build) 16.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "        │   └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "        │     └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false",
          "        └─ExchangeReceiver(Probe) 4.00 mpp[tiflash]  ",
          "          └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "            └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 12.80 root  data:ExchangeSender",
          "  └─ExchangeSender 12.80 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 12.80 mpp[tiflash]  semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "      │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k))",
          "      │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "        └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "          └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.d1_k))",
          "            └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 12.80 root  data:ExchangeSender",
          "  └─ExchangeSender 12.80 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 12.80 mpp[tiflash]  semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)",
          "      ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "      │   └─Selection 4.00 mpp[tiflash]  not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))",
          "      │     └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "        └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "          └─Selection 16.00 mpp[tiflash]  not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))",
          "            └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 12.80 root  data:ExchangeSender",
          "  └─ExchangeSender 12.80 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 12.80 mpp[tiflash]  anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]",
          "      ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "      │   └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "        └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "          └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#12",
          "└─TableReader 12.80 root  data:ExchangeSender",
          "  └─ExchangeSender 12.80 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 12.80 mpp[tiflash]  anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)",
          "      ├─ExchangeReceiver(Build) 4.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 4.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]",
          "      │   └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false",
          "      └─ExchangeReceiver(Probe) 16.00 mpp[tiflash]  ",
          "        └─ExchangeSender 16.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]",
          "          └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPJoinWithCanNotFoundColumnInSchemaColumnsError",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select v from t3 as a left join (select t1.v1, t1.v2, t1.v1 + t1.v2 as v from t1 left join t2 on t1.v1 = t2.v1 and t1.v2 = t2.v2) b on a.v1 = b.v1 and a.v2 = b.v2",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#13",
          "    └─HashJoin 1.00 mpp[tiflash]  left outer join, equal:[eq(test.t3.v1, test.t1.v1) eq(test.t3.v2, test.t1.v2)]",
          "      ├─ExchangeReceiver(Build) 1.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#23, collate: binary], [name: Column#24, collate: binary]",
          "      │   └─Projection 1.00 mpp[tiflash]  test.t3.v1, test.t3.v2, cast(test.t3.v1, decimal(20,2))->Column#23, cast(test.t3.v2, decimal(20,2))->Column#24",
          "      │     └─TableFullScan 1.00 mpp[tiflash] table:a keep order:false",
          "      └─Projection(Probe) 2.00 mpp[tiflash]  test.t1.v1, test.t1.v2, plus(test.t1.v1, test.t1.v2)->Column#13",
          "        └─HashJoin 2.00 mpp[tiflash]  left outer join, equal:[eq(test.t1.v1, test.t2.v1) eq(test.t1.v2, test.t2.v2)]",
          "          ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.v1, collate: binary], [name: test.t1.v2, collate: binary]",
          "          │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.t1.v1)), not(isnull(test.t1.v2))",
          "          │     └─TableFullScan 2.00 mpp[tiflash] table:t1 keep order:false",
          "          └─ExchangeReceiver(Probe) 8.00 mpp[tiflash]  ",
          "            └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#15, collate: binary], [name: Column#16, collate: binary]",
          "              └─Projection 8.00 mpp[tiflash]  test.t2.v1, test.t2.v2, cast(test.t2.v1, decimal(20,2))->Column#15, cast(test.t2.v2, decimal(20,2))->Column#16",
          "                └─Selection 8.00 mpp[tiflash]  not(isnull(test.t2.v1)), not(isnull(test.t2.v2))",
          "                  └─TableFullScan 8.00 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*), t2.v1, t2.v2 from t1 left join t2 on t1.v1 = t2.v1 and t1.v2 = t2.v2 group by t2.v1, t2.v2",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2.00 mpp[tiflash]  Column#9, test.t2.v1, test.t2.v2",
          "    └─HashAgg 2.00 mpp[tiflash]  group by:test.t2.v1, test.t2.v2, funcs:sum(Column#22)->Column#9, funcs:firstrow(test.t2.v1)->test.t2.v1, funcs:firstrow(test.t2.v2)->test.t2.v2",
          "      └─ExchangeReceiver 2.00 mpp[tiflash]  ",
          "        └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t2.v1, collate: binary], [name: test.t2.v2, collate: binary]",
          "          └─HashAgg 2.00 mpp[tiflash]  group by:test.t2.v1, test.t2.v2, funcs:count(1)->Column#22",
          "            └─HashJoin 2.00 mpp[tiflash]  left outer join, equal:[eq(test.t1.v1, test.t2.v1) eq(test.t1.v2, test.t2.v2)]",
          "              ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.v1, collate: binary], [name: test.t1.v2, collate: binary]",
          "              │   └─TableFullScan 2.00 mpp[tiflash] table:t1 keep order:false",
          "              └─ExchangeReceiver(Probe) 8.00 mpp[tiflash]  ",
          "                └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary], [name: Column#15, collate: binary]",
          "                  └─Projection 8.00 mpp[tiflash]  test.t2.v1, test.t2.v2, cast(test.t2.v1, decimal(20,2))->Column#14, cast(test.t2.v2, decimal(20,2))->Column#15",
          "                    └─Selection 8.00 mpp[tiflash]  not(isnull(test.t2.v1)), not(isnull(test.t2.v2))",
          "                      └─TableFullScan 8.00 mpp[tiflash] table:t2 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*), t2.v1, t2.v2 from t3 left join t2 on t3.v1 = t2.v1 and t3.v2 = t2.v2 group by t2.v1, t2.v2",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#9, test.t2.v1, test.t2.v2",
          "    └─HashAgg 1.00 mpp[tiflash]  group by:test.t2.v1, test.t2.v2, funcs:count(1)->Column#9, funcs:firstrow(test.t2.v1)->test.t2.v1, funcs:firstrow(test.t2.v2)->test.t2.v2",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t2.v1, collate: binary], [name: test.t2.v2, collate: binary]",
          "          └─HashJoin 1.00 mpp[tiflash]  left outer join, equal:[eq(test.t3.v1, test.t2.v1) eq(test.t3.v2, test.t2.v2)]",
          "            ├─ExchangeReceiver(Build) 1.00 mpp[tiflash]  ",
          "            │ └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t3.v1, collate: binary], [name: test.t3.v2, collate: binary]",
          "            │   └─TableFullScan 1.00 mpp[tiflash] table:t3 keep order:false",
          "            └─ExchangeReceiver(Probe) 8.00 mpp[tiflash]  ",
          "              └─ExchangeSender 8.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t2.v1, collate: binary], [name: test.t2.v2, collate: binary]",
          "                └─Selection 8.00 mpp[tiflash]  not(isnull(test.t2.v1)), not(isnull(test.t2.v2))",
          "                  └─TableFullScan 8.00 mpp[tiflash] table:t2 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestJoinNotSupportedByTiFlash",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from table_1 a, table_1 b where a.bit_col = b.bit_col",
        "Plan": [
          "HashJoin 2.00 root  inner join, equal:[eq(test.table_1.bit_col, test.table_1.bit_col)]",
          "├─TableReader(Build) 2.00 root  data:TableFullScan",
          "│ └─TableFullScan 2.00 cop[tiflash] table:b keep order:false",
          "└─TableReader(Probe) 2.00 root  data:TableFullScan",
          "  └─TableFullScan 2.00 cop[tiflash] table:a keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a left join table_1 b on a.id = b.id and dayofmonth(a.datetime_col) > 100",
        "Plan": [
          "HashJoin 2.00 root  left outer join, equal:[eq(test.table_1.id, test.table_1.id)], left cond:[gt(dayofmonth(test.table_1.datetime_col), 100)]",
          "├─TableReader(Build) 2.00 root  data:TableFullScan",
          "│ └─TableFullScan 2.00 cop[tiflash] table:b keep order:false",
          "└─TableReader(Probe) 2.00 root  data:TableFullScan",
          "  └─TableFullScan 2.00 cop[tiflash] table:a keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a right join table_1 b on a.id = b.id and dayofmonth(b.datetime_col) > 100",
        "Plan": [
          "HashJoin 2.00 root  right outer join, equal:[eq(test.table_1.id, test.table_1.id)], right cond:gt(dayofmonth(test.table_1.datetime_col), 100)",
          "├─TableReader(Build) 2.00 root  data:TableFullScan",
          "│ └─TableFullScan 2.00 cop[tiflash] table:a keep order:false",
          "└─TableReader(Probe) 2.00 root  data:TableFullScan",
          "  └─TableFullScan 2.00 cop[tiflash] table:b keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a join table_1 b on a.id = b.id and dayofmonth(a.datetime_col) > dayofmonth(b.datetime_col)",
        "Plan": [
          "HashJoin 2.00 root  inner join, equal:[eq(test.table_1.id, test.table_1.id)], other cond:gt(dayofmonth(test.table_1.datetime_col), dayofmonth(test.table_1.datetime_col))",
          "├─TableReader(Build) 2.00 root  data:TableFullScan",
          "│ └─TableFullScan 2.00 cop[tiflash] table:b keep order:false",
          "└─TableReader(Probe) 2.00 root  data:TableFullScan",
          "  └─TableFullScan 2.00 cop[tiflash] table:a keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPWithHashExchangeUnderNewCollation",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from table_1 a, table_1 b where a.value = b.value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_1.value)]",
          "    ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_general_ci]",
          "    │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "    │     └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "      └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_general_ci]",
          "        └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "          └─TableFullScan 2.00 mpp[tiflash] table:b keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a, table_2 b where a.value = b.value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_2.value)]",
          "    ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_bin]",
          "    │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "    │     └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "      └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_2.value, collate: utf8mb4_bin]",
          "        └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_2.value))",
          "          └─TableFullScan 2.00 mpp[tiflash] table:b keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a, table_2 b, table_1 c where a.value = b.value and b.value = c.value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_2.value, test.table_1.value)]",
          "    ├─HashJoin(Build) 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_2.value)]",
          "    │ ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_bin]",
          "    │ │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "    │ │     └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    │ └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "    │   └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_2.value, collate: utf8mb4_bin]",
          "    │     └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_2.value))",
          "    │       └─TableFullScan 2.00 mpp[tiflash] table:b keep order:false",
          "    └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "      └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_bin]",
          "        └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "          └─TableFullScan 2.00 mpp[tiflash] table:c keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from table_1 a, table_2 b, table_1 c where a.value = b.value and a.value = c.value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_1.value)]",
          "    ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_general_ci]",
          "    │   └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_2.value)]",
          "    │     ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │     │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_bin]",
          "    │     │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "    │     │     └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    │     └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "    │       └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_2.value, collate: utf8mb4_bin]",
          "    │         └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_2.value))",
          "    │           └─TableFullScan 2.00 mpp[tiflash] table:b keep order:false",
          "    └─ExchangeReceiver(Probe) 2.00 mpp[tiflash]  ",
          "      └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_general_ci]",
          "        └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "          └─TableFullScan 2.00 mpp[tiflash] table:c keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ agg_to_cop() */ count(*), value from table_1 group by value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2.00 mpp[tiflash]  Column#4, test.table_1.value",
          "    └─HashAgg 2.00 mpp[tiflash]  group by:test.table_1.value, funcs:count(1)->Column#4, funcs:firstrow(test.table_1.value)->test.table_1.value",
          "      └─ExchangeReceiver 2.00 mpp[tiflash]  ",
          "        └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.value, collate: utf8mb4_general_ci]",
          "          └─TableFullScan 2.00 mpp[tiflash] table:table_1 keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ agg_to_cop() */ count(*), value from table_2 group by value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2.00 mpp[tiflash]  Column#4, test.table_2.value",
          "    └─HashAgg 2.00 mpp[tiflash]  group by:test.table_2.value, funcs:count(1)->Column#4, funcs:firstrow(test.table_2.value)->test.table_2.value",
          "      └─ExchangeReceiver 2.00 mpp[tiflash]  ",
          "        └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_2.value, collate: utf8mb4_bin]",
          "          └─TableFullScan 2.00 mpp[tiflash] table:table_2 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPWithBroadcastExchangeUnderNewCollation",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ broadcast_join(a,b) */ * from table_1 a, table_1 b where a.id = b.id",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.id, test.table_1.id)]",
          "    ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    └─TableFullScan(Probe) 2.00 mpp[tiflash] table:b keep order:false"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ broadcast_join(a,b) */ * from table_1 a, table_1 b where a.value = b.value",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 2.00 mpp[tiflash]  inner join, equal:[eq(test.table_1.value, test.table_1.value)]",
          "    ├─ExchangeReceiver(Build) 2.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Selection 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "    │     └─TableFullScan 2.00 mpp[tiflash] table:a keep order:false",
          "    └─Selection(Probe) 2.00 mpp[tiflash]  not(isnull(test.table_1.value))",
          "      └─TableFullScan 2.00 mpp[tiflash] table:b keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestMPPAvgRewrite",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ avg_to_cop() */ id, avg(value+1),avg(value) from table_1 group by id",
        "Plan": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2.00 mpp[tiflash]  test.table_1.id, Column#4, Column#5",
          "    └─Projection 2.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#25, 0), 1, Column#25), decimal(20,0) BINARY))->Column#4, div(Column#5, cast(case(eq(Column#26, 0), 1, Column#26), decimal(20,0) BINARY))->Column#5, test.table_1.id",
          "      └─HashAgg 2.00 mpp[tiflash]  group by:Column#39, funcs:count(Column#34)->Column#25, funcs:sum(Column#35)->Column#4, funcs:count(Column#36)->Column#26, funcs:sum(Column#37)->Column#5, funcs:firstrow(Column#38)->test.table_1.id",
          "        └─Projection 2.00 mpp[tiflash]  plus(test.table_1.value, 1)->Column#34, plus(test.table_1.value, 1)->Column#35, test.table_1.value, test.table_1.value, test.table_1.id, test.table_1.id",
          "          └─ExchangeReceiver 2.00 mpp[tiflash]  ",
          "            └─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.table_1.id, collate: binary]",
          "              └─TableFullScan 2.00 mpp[tiflash] table:table_1 keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestReadFromStorageHint",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select avg(a) from t",
        "Plan": [
          "HashAgg 1.00 root  funcs:avg(Column#5, Column#6)->Column#4",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 batchCop[tiflash]  funcs:count(Column#9)->Column#5, funcs:sum(Column#10)->Column#6",
          "    └─Projection 10000.00 batchCop[tiflash]  test.t.a, cast(test.t.a, decimal(10,0) BINARY)->Column#10",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ avg(a) from t",
        "Plan": [
          "HashAgg 1.00 root  funcs:avg(Column#5, Column#6)->Column#4",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 batchCop[tiflash]  funcs:count(Column#9)->Column#5, funcs:sum(Column#10)->Column#6",
          "    └─Projection 10000.00 batchCop[tiflash]  test.t.a, cast(test.t.a, decimal(10,0) BINARY)->Column#10",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ sum(a) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#6)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#7)->Column#6",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(test.t.a, decimal(10,0) BINARY)->Column#7",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ sum(a+1) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#6)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#7)->Column#6",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(plus(test.t.a, 1), decimal(20,0) BINARY)->Column#7",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ sum(isnull(a)) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#6)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#7)->Column#6",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(isnull(test.t.a), decimal(20,0) BINARY)->Column#7",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ READ_FROM_STORAGE(TIKV[t1], TIKV[t2]) */ * from t t1, t t2 where t1.a = t2.a",
        "Plan": [
          "HashJoin 12487.50 root  inner join, equal:[eq(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:t2 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:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ READ_FROM_STORAGE(TIKV[t1], TIFLASH[t2]) */ * from t t1, t t2 where t1.a = t2.a",
        "Plan": [
          "HashJoin 12487.50 root  inner join, equal:[eq(test.t.a, test.t.a)]",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.a))",
          "│   └─TableFullScan 10000.00 cop[tiflash] table:t2 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:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select * from tt where (tt.a > 1 and tt.a < 20) or (tt.a >= 30 and tt.a < 55)",
        "Plan": [
          "TableReader 44.00 root  data:TableRangeScan",
          "└─TableRangeScan 44.00 cop[tikv] table:tt range:(1,20), [30,55), keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[tt]) */ * from tt where (tt.a > 1 and tt.a < 20) or (tt.a >= 30 and tt.a < 55)",
        "Plan": [
          "TableReader 44.00 root  data:TableRangeScan",
          "└─TableRangeScan 44.00 cop[tiflash] table:tt range:(1,20), [30,55), keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select * from ttt order by ttt.a desc",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tikv] table:ttt keep order:true, desc, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[ttt]) */ * from ttt order by ttt.a desc",
        "Plan": [
          "Sort 10000.00 root  test.ttt.a:desc",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:ttt keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[ttt]) */ * from ttt order by ttt.a",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tiflash] table:ttt keep order:true, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t, ttt]) */ * from ttt",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tikv] table:ttt keep order:false, stats:pseudo"
        ],
        "Warn": [
          "[planner:1815]There are no matching table names for (t) in optimizer hint /*+ READ_FROM_STORAGE(tikv[t, ttt]) */. Maybe you can use the table alias name"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t, ttt], tikv[tt]) */ * from ttt",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tiflash] table:ttt keep order:false, stats:pseudo"
        ],
        "Warn": [
          "[planner:1815]There are no matching table names for (t, tt) in optimizer hint /*+ READ_FROM_STORAGE(tiflash[t, ttt], tikv[tt]) */. Maybe you can use the table alias name"
        ]
      }
    ]
  },
  {
    "Name": "TestViewHint",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
        "Plan": [
          "HashJoin 9990.00 root  inner join, equal:[eq(test.t.a, Column#10)]",
          "├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#10",
          "│ └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   ├─Sort(Build) 9990.00 root  test.t2.b",
          "│   │ └─TableReader 9990.00 root  data:Selection",
          "│   │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│   │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│     └─TableReader 9990.00 root  data:Selection",
          "│       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel_1), merge_join(t@qb_v_1) */ * from v;",
        "Plan": [
          "MergeJoin 9990.00 root  inner join, left key:test.t.a, right key:Column#10",
          "├─Sort(Build) 7992.00 root  Column#10",
          "│ └─StreamAgg 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#10",
          "│   └─Sort 12487.50 root  test.t2.a",
          "│     └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│       ├─Sort(Build) 9990.00 root  test.t2.b",
          "│       │ └─TableReader 9990.00 root  data:Selection",
          "│       │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│       │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#17)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#17",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#16)]",
          "│   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#16",
          "│   │ └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   ├─Sort(Build) 9990.00 root  test.t2.b",
          "│   │   │ └─TableReader 9990.00 root  data:Selection",
          "│   │   │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│   │   │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │     └─TableReader 9990.00 root  data:Selection",
          "│   │       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#17)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#17",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t1.b, test.t.b)]",
          "│   ├─MergeJoin(Build) 9980.01 root  inner join, left key:test.t.a, right key:Column#16",
          "│   │ ├─Sort(Build) 7992.00 root  Column#16",
          "│   │ │ └─StreamAgg 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#16",
          "│   │ │   └─Sort 12487.50 root  test.t2.a",
          "│   │ │     └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │ │       ├─Sort(Build) 9990.00 root  test.t2.b",
          "│   │ │       │ └─TableReader 9990.00 root  data:Selection",
          "│   │ │       │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│   │ │       │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │ │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │ │         └─TableReader 9990.00 root  data:Selection",
          "│   │ │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │ │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │ └─Sort(Probe) 9980.01 root  test.t.a",
          "│   │   └─TableReader 9980.01 root  data:Selection",
          "│   │     └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─TableReader(Probe) 9990.00 root  data:Selection",
          "│     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#24)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#23)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#22)]",
          "│   │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│   │   │ └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   │   ├─Sort(Build) 9990.00 root  test.t2.b",
          "│   │   │   │ └─TableReader 9990.00 root  data:Selection",
          "│   │   │   │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│   │   │   │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   │   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │   │     └─TableReader 9990.00 root  data:Selection",
          "│   │   │       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#24)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#23)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t1.b, test.t.b)]",
          "│   │   ├─MergeJoin(Build) 9980.01 root  inner join, left key:test.t.a, right key:Column#22",
          "│   │   │ ├─Sort(Build) 7992.00 root  Column#22",
          "│   │   │ │ └─StreamAgg 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│   │   │ │   └─Sort 12487.50 root  test.t2.a",
          "│   │   │ │     └─MergeJoin 12487.50 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   │ │       ├─Sort(Build) 9990.00 root  test.t2.b",
          "│   │   │ │       │ └─TableReader 9990.00 root  data:Selection",
          "│   │   │ │       │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│   │   │ │       │     └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   │ │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │   │ │         └─TableReader 9990.00 root  data:Selection",
          "│   │   │ │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │ │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │   │ └─Sort(Probe) 9980.01 root  test.t.a",
          "│   │   │   └─TableReader 9980.01 root  data:Selection",
          "│   │   │     └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   │   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   │   └─TableReader(Probe) 9990.00 root  data:Selection",
          "│   │     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#17)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#17",
          "│ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#16)]",
          "│   │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#16",
          "│   │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │   └─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.t2.b))",
          "│   │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 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.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│     └─TableReader 9990.00 root  data:Selection",
          "│       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v1;",
        "Plan": [
          "MergeJoin 9980.01 root  inner join, left key:test.t.a, right key:Column#17",
          "├─Sort(Build) 7984.01 root  Column#17",
          "│ └─StreamAgg 7984.01 root  group by:test.t.a, funcs:count(1)->Column#17",
          "│   └─Sort 12475.01 root  test.t.a",
          "│     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│       ├─Sort(Build) 9980.01 root  test.t.b",
          "│       │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#16)]",
          "│       │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#16",
          "│       │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│       │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   │   │   └─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.t2.b))",
          "│       │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 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.b))",
          "│       │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#24)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#23)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│   │ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   │   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#22)]",
          "│   │   │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│   │   │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│   │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │   │   └─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.t2.b))",
          "│   │   │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 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.b))",
          "│   │   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   │   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │     └─TableReader 9990.00 root  data:Selection",
          "│   │       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t@qb_v1_1) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#24)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t1.b, test.t.b)]",
          "│   ├─MergeJoin(Build) 9980.01 root  inner join, left key:test.t.a, right key:Column#23",
          "│   │ ├─Sort(Build) 7984.01 root  Column#23",
          "│   │ │ └─StreamAgg 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│   │ │   └─Sort 12475.01 root  test.t.a",
          "│   │ │     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   │ │       ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │ │       │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#22)]",
          "│   │ │       │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│   │ │       │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│   │ │       │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ │       │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │ │       │   │   │   └─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.t2.b))",
          "│   │ │       │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 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.b))",
          "│   │ │       │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   │ │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │ │         └─TableReader 9990.00 root  data:Selection",
          "│   │ │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │ │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │ └─Sort(Probe) 9980.01 root  test.t.a",
          "│   │   └─TableReader 9980.01 root  data:Selection",
          "│   │     └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─TableReader(Probe) 9990.00 root  data:Selection",
          "│     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#24)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#23)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│   │   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#22)]",
          "│   │   │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│   │   │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│   │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │   │   └─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.t2.b))",
          "│   │   │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │     │   └─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.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t 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.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│     └─TableReader 9990.00 root  data:Selection",
          "│       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2), stream_agg(@qb_v2_2), qb_name(qb_v2_1, v2), merge_join(t@qb_v2_1) */ * from v2;",
        "Plan": [
          "MergeJoin 9980.01 root  inner join, left key:test.t.a, right key:Column#24",
          "├─Sort(Build) 7984.01 root  Column#24",
          "│ └─StreamAgg 7984.01 root  group by:test.t.a, funcs:count(1)->Column#24",
          "│   └─Sort 12475.01 root  test.t.a",
          "│     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│       ├─Sort(Build) 9980.01 root  test.t.b",
          "│       │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#23)]",
          "│       │   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#23",
          "│       │   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#22)]",
          "│       │   │   ├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#22",
          "│       │   │   │ └─HashJoin 12487.50 root  inner join, equal:[eq(test.t1.b, test.t2.b)]",
          "│       │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   │   │   │   └─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.t2.b))",
          "│       │   │   │       └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│       │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│       │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   │     │   └─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.b))",
          "│       │   │         └─TableFullScan 10000.00 cop[tikv] table:t 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.b))",
          "│       │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      }
    ]
  },
  {
    "Name": "TestViewHintScope",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v@sel_1 .@sel_2), qb_name(qb_v, v@sel_1 .@sel_1), merge_join(t1@qb_v) */ * from v;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│     │ └─TableReader 9980.01 root  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",
          "│     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│       └─TableReader 9990.00 root  data:Selection",
          "│         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│           └─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"
        ],
        "Warn": [
          "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_2), qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │     │ └─TableReader 9980.01 root  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",
          "│   │     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │       └─TableReader 9990.00 root  data:Selection",
          "│   │         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │           └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_2), qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   │     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │   │     │ └─TableReader 9980.01 root  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",
          "│   │   │     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │   │       └─TableReader 9990.00 root  data:Selection",
          "│   │   │         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │           └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "The qb_name hint qb_v1_2 is unused, please check whether the table list in the qb_name hint qb_v1_2 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "The qb_name hint qb_v1_2 is unused, please check whether the table list in the qb_name hint qb_v1_2 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, vv@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │     │   └─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.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t 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.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│     └─TableReader 9990.00 root  data:Selection",
          "│       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "The qb_name hint qb_v2_2 is unused, please check whether the table list in the qb_name hint qb_v2_2 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t2 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"
        ],
        "Warn": [
          "The qb_name hint qb_v_2 is unused, please check whether the table list in the qb_name hint qb_v_2 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v.@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─StreamAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─Sort 15593.77 root  test.t2.a",
          "│   └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│     │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│     └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│       ├─Sort(Build) 9980.01 root  test.t2.b",
          "│       │ └─TableReader 9980.01 root  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",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─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"
        ],
        "Warn": [
          "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "The qb_name hint qb_v_2 is unused, please check whether the table list in the qb_name hint qb_v_2 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1.v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─StreamAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─Sort 15593.77 root  test.t2.a",
          "│   │   └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │     │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │     └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │       ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │       │ └─TableReader 9980.01 root  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",
          "│   │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │         └─TableReader 9990.00 root  data:Selection",
          "│   │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│     │ └─TableReader 9980.01 root  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",
          "│     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│       └─TableReader 9990.00 root  data:Selection",
          "│         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│           └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2), qb_name(qb_v_1, v@sel_2 .@sel1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─StreamAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─Sort 15593.77 root  test.t2.a",
          "│   └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│     │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│     └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│       ├─Sort(Build) 9980.01 root  test.t2.b",
          "│       │ └─TableReader 9980.01 root  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",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─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"
        ],
        "Warn": [
          "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v1) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │     │ └─TableReader 9980.01 root  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",
          "│   │     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │       └─TableReader 9990.00 root  data:Selection",
          "│   │         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │           └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v1@sel_2 . v@sel_2 .@sel_1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v1) t;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t1.b, test.t.b)]",
          "│   ├─MergeJoin(Build) 9980.01 root  inner join, left key:test.t.a, right key:Column#19",
          "│   │ ├─Sort(Build) 7984.01 root  Column#19",
          "│   │ │ └─StreamAgg 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ │   └─Sort 15593.77 root  test.t2.a",
          "│   │ │     └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │ │       ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ │       │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │ │       │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │ │       └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │ │         ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │ │         │ └─TableReader 9980.01 root  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",
          "│   │ │         └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │ │           └─TableReader 9990.00 root  data:Selection",
          "│   │ │             └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │ │               └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │ └─Sort(Probe) 9980.01 root  test.t.a",
          "│   │   └─TableReader 9980.01 root  data:Selection",
          "│   │     └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─TableReader(Probe) 9990.00 root  data:Selection",
          "│     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2. v1@sel_2 .@sel_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t1@qb_v1_2, t@qb_v1_1), merge_join(t1@qb_v1_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   │   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 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.b))",
          "│   │   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   │   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │     └─TableReader 9990.00 root  data:Selection",
          "│   │       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": [
          "Only one query block name is allowed in a view hint, otherwise the hint will be invalid"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t1@qb_v_2, t3@qb_v_2) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │ └─MergeJoin 15593.77 root  inner join, left key:test.t2.a, right key:test.t3.a",
          "│   │   │   ├─Sort(Build) 9990.00 root  test.t3.a",
          "│   │   │   │ └─TableReader 9990.00 root  data:Selection",
          "│   │   │   │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │     └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   └─Sort(Probe) 12475.01 root  test.t2.a",
          "│   │   │     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   │       ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │   │       │ └─TableReader 9980.01 root  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",
          "│   │   │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │   │         └─TableReader 9990.00 root  data:Selection",
          "│   │   │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(@qb_v_2 t1, t3) */ * from v2;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │ └─MergeJoin 15593.77 root  inner join, left key:test.t2.a, right key:test.t3.a",
          "│   │   │   ├─Sort(Build) 9990.00 root  test.t3.a",
          "│   │   │   │ └─TableReader 9990.00 root  data:Selection",
          "│   │   │   │   └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │     └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   └─Sort(Probe) 12475.01 root  test.t2.a",
          "│   │   │     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │   │       ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │   │       │ └─TableReader 9980.01 root  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",
          "│   │   │       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │   │         └─TableReader 9990.00 root  data:Selection",
          "│   │   │           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │     │   └─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.b))",
          "│   │         └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│     │ └─TableReader 9980.01 root  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",
          "│     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│       └─TableReader 9990.00 root  data:Selection",
          "│         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│           └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v@sel_1), merge_join(t@qb_v_1) */ * from v;",
        "Plan": [
          "MergeJoin 9980.01 root  inner join, left key:test.t.a, right key:Column#13",
          "├─Sort(Build) 7984.01 root  Column#13",
          "│ └─HashAgg 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│   └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│     │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│     └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│       ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│           └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "│   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│   │     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│   │     │ └─TableReader 9980.01 root  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",
          "│   │     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│   │       └─TableReader 9990.00 root  data:Selection",
          "│   │         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │           └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│     │   └─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.b))",
          "│         └─TableFullScan 10000.00 cop[tikv] table:t 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v1 .v@sel_2), merge_join(t@qb_v_1) */ * from v1;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#20)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#20",
          "│ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t1.b, test.t.b)]",
          "│   ├─MergeJoin(Build) 9980.01 root  inner join, left key:test.t.a, right key:Column#19",
          "│   │ ├─Sort(Build) 7984.01 root  Column#19",
          "│   │ │ └─HashAgg 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│   │ │   └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │ │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │ │     │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │ │     └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │ │       ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ │       │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │ │       │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │ │           └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │ └─Sort(Probe) 9980.01 root  test.t.a",
          "│   │   └─TableReader 9980.01 root  data:Selection",
          "│   │     └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─TableReader(Probe) 9990.00 root  data:Selection",
          "│     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ merge_join(t1@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from v;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#13)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t3.a, test.t2.a)]",
          "│   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   └─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t1.b, right key:test.t2.b",
          "│     ├─Sort(Build) 9980.01 root  test.t2.b",
          "│     │ └─TableReader 9980.01 root  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",
          "│     └─Sort(Probe) 9990.00 root  test.t1.b",
          "│       └─TableReader 9990.00 root  data:Selection",
          "│         └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│           └─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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ merge_join(t@qb_v_1), stream_agg(@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel_1) */ * from v;",
        "Plan": [
          "MergeJoin 9980.01 root  inner join, left key:test.t.a, right key:Column#13",
          "├─Sort(Build) 7984.01 root  Column#13",
          "│ └─StreamAgg 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#13",
          "│   └─Sort 15593.77 root  test.t2.a",
          "│     └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│       ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│       │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│       └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│         ├─TableReader(Build) 9990.00 root  data:Selection",
          "│         │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2) */ * from v3;",
        "Plan": [
          "MergeJoin 9980.01 root  inner join, left key:test.t.a, right key:Column#27",
          "├─Sort(Build) 7984.01 root  Column#27",
          "│ └─StreamAgg 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│   └─Sort 12475.01 root  test.t.a",
          "│     └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│       ├─Sort(Build) 9980.01 root  test.t.b",
          "│       │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│       │   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│       │   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│       │   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│       │   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│       │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│       │   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│       │   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│       │   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│       │   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│       │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│       │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   │     │   └─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.b))",
          "│       │   │         └─TableFullScan 10000.00 cop[tikv] table:t 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.b))",
          "│       │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│       └─Sort(Probe) 9990.00 root  test.t1.b",
          "│         └─TableReader 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─Sort(Probe) 9990.00 root  test.t.a",
          "  └─TableReader 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"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2), hash_agg(@qb_v3_2), qb_name(qb_v3_1, v3@sel_1 .@sel_1), hash_join(t@qb_v3_1) */ * from v3;",
        "Plan": [
          "HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#27)]",
          "├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#27",
          "│ └─MergeJoin 12475.01 root  inner join, left key:test.t1.b, right key:test.t.b",
          "│   ├─Sort(Build) 9980.01 root  test.t.b",
          "│   │ └─HashJoin 9980.01 root  inner join, equal:[eq(test.t.a, Column#26)]",
          "│   │   ├─HashAgg(Build) 7984.01 root  group by:test.t.a, funcs:count(1)->Column#26",
          "│   │   │ └─HashJoin 12475.01 root  inner join, equal:[eq(test.t.a, Column#25)]",
          "│   │   │   ├─HashAgg(Build) 7984.01 root  group by:test.t2.a, funcs:count(1)->Column#25",
          "│   │   │   │ └─HashJoin 15593.77 root  inner join, equal:[eq(test.t2.a, test.t3.a)]",
          "│   │   │   │   ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │   │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t3.a))",
          "│   │   │   │   │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│   │   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│   │   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │   │     │   └─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.t2.a)), not(isnull(test.t2.b))",
          "│   │   │   │         └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "│   │   │   └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "│   │   │     ├─TableReader(Build) 9990.00 root  data:Selection",
          "│   │   │     │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│   │   │     │   └─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.b))",
          "│   │   │         └─TableFullScan 10000.00 cop[tikv] table:t 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.b))",
          "│   │       └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "│   └─Sort(Probe) 9990.00 root  test.t1.b",
          "│     └─TableReader 9990.00 root  data:Selection",
          "│       └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         └─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"
        ],
        "Warn": [
          "[planner:1815]Join hints are conflict, you can only specify one type of join",
          "[planner:1815]Optimizer aggregation hints are conflicted"
        ]
      },
      {
        "SQL": "explain with d1 as (\n    select a from (\n        select a from (\n            select /*+ qb_name(qb, v4) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n        ) as t0 where a < 9\n    ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;",
        "Plan": [
          "HashJoin_41 6944.44 root  CARTESIAN inner join",
          "├─IndexLookUp_50(Build) 83.33 root  ",
          "│ ├─IndexRangeScan_47(Build) 250.00 cop[tikv] table:t4, index:idx_b(b) range:(3,10), keep order:false, stats:pseudo",
          "│ └─Selection_49(Probe) 83.33 cop[tikv]  gt(test.t4.a, 2)",
          "│   └─TableRowIDScan_48 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo",
          "└─IndexLookUp_46(Probe) 83.33 root  ",
          "  ├─IndexRangeScan_43(Build) 250.00 cop[tikv] table:t4, index:idx_a(a) range:(2,8), keep order:false, stats:pseudo",
          "  └─Selection_45(Probe) 83.33 cop[tikv]  gt(test.t4.b, 3)",
          "    └─TableRowIDScan_44 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain with d1 as (\n    select a from (\n        select a from (\n            select a from v4 where a < 10\n        ) as t0 where a < 9\n    ) as t1 where a < 8\n), d2 as (select a from v4 where b < 10)\n\nselect /*+ qb_name(qb, v4@sel_4) use_index(t4@qb, idx_a)   qb_name(qb2, v4@sel_5) use_index(t4@qb, idx_b) */ * from (select * from d1) as t0 join (select * from d2) as t1;",
        "Plan": [
          "HashJoin_41 6944.44 root  CARTESIAN inner join",
          "├─TableReader_53(Build) 83.33 root  data:Selection_52",
          "│ └─Selection_52 83.33 cop[tikv]  gt(test.t4.a, 2), gt(test.t4.b, 3), lt(test.t4.b, 10)",
          "│   └─TableFullScan_51 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo",
          "└─IndexLookUp_46(Probe) 83.33 root  ",
          "  ├─IndexRangeScan_43(Build) 250.00 cop[tikv] table:t4, index:idx_a(a) range:(2,8), keep order:false, stats:pseudo",
          "  └─Selection_45(Probe) 83.33 cop[tikv]  gt(test.t4.b, 3)",
          "    └─TableRowIDScan_44 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain with d1 as (\n    select a from (\n        select a from (\n            select /*+ qb_name(qb, v5) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n        ) as t0 where a < 9\n    ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;",
        "Plan": [
          "HashJoin_41 6944.44 root  CARTESIAN inner join",
          "├─IndexLookUp_57(Build) 83.33 root  ",
          "│ ├─IndexRangeScan_54(Build) 250.00 cop[tikv] table:t4, index:idx_b(b) range:(3,10), keep order:false, stats:pseudo",
          "│ └─Selection_56(Probe) 83.33 cop[tikv]  gt(test.t4.a, 2)",
          "│   └─TableRowIDScan_55 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo",
          "└─TableReader_45(Probe) 83.33 root  data:Selection_44",
          "  └─Selection_44 83.33 cop[tikv]  gt(test.t4.a, 2), gt(test.t4.b, 3), lt(test.t4.a, 10), lt(test.t4.a, 8), lt(test.t4.a, 9)",
          "    └─TableFullScan_43 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "The qb_name hint qb is unused, please check whether the table list in the qb_name hint qb is correct"
        ]
      }
    ]
  },
  {
    "Name": "TestAllViewHintType",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 v, t2) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(v@qb_v1, t2@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 t3, t2) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(t3@qb_v1, t2@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), qb_name(qb_v, v1.v), leading(t2@qb_v1, t@qb_v) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Only one query block name is allowed in a view hint, otherwise the hint will be invalid"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(@qb_v1 v, t2) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t3.b)]",
          "  ├─TableReader(Build) 9980.01 root  data:Selection",
          "  │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9990.00 root  data:Selection",
          "    └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(t2@qb_v1, t3@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t3.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t3.b)]",
          "  ├─TableReader(Build) 9980.01 root  data:Selection",
          "  │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9990.00 root  data:Selection",
          "    └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─Projection(Probe) 12475.01 root  test.t2.a, test.t2.b, test.t3.a",
          "  └─HashJoin 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t3.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t3.b)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9980.01 root  data:Selection",
          "    └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─Projection(Probe) 12475.01 root  test.t2.a, test.t2.b, test.t3.a",
          "  └─HashJoin 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "    ├─TableReader(Build) 9980.01 root  data:Selection",
          "    │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "    │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "    └─TableReader(Probe) 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t3.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t2.b, test.t3.b)]",
          "  ├─TableReader(Build) 9990.00 root  data:Selection",
          "  │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "  │   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 9980.01 root  data:Selection",
          "    └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(@qb_v1 v) */ * from v1;",
        "Plan": [
          "MergeJoin 19492.21 root  inner join, left key:test.t3.a, right key:test.t.a",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─Sort(Probe) 12475.01 root  test.t3.a",
          "  └─Projection 12475.01 root  test.t2.a, test.t2.b, test.t3.a",
          "    └─HashJoin 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "      ├─TableReader(Build) 9980.01 root  data:Selection",
          "      │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "      │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "      └─TableReader(Probe) 9990.00 root  data:Selection",
          "        └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "          └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(t2@qb_v1) */ * from v1;",
        "Plan": [
          "HashJoin 19492.21 root  inner join, equal:[eq(test.t.a, test.t3.a)]",
          "├─MergeJoin(Build) 12500.00 root  inner join, left key:test.t.a, right key:test.t1.a",
          "│ ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
          "│ └─IndexReader(Probe) 10000.00 root  index:IndexFullScan",
          "│   └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
          "└─MergeJoin(Probe) 12475.01 root  inner join, left key:test.t2.b, right key:test.t3.b",
          "  ├─Sort(Build) 9980.01 root  test.t3.b",
          "  │ └─TableReader 9980.01 root  data:Selection",
          "  │   └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "  │     └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "  └─Sort(Probe) 9990.00 root  test.t2.b",
          "    └─TableReader 9990.00 root  data:Selection",
          "      └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(@qb_v t) */ * from v;",
        "Plan": [
          "IndexJoin 12500.00 root  inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12500.00 root  ",
          "  ├─IndexRangeScan(Build) 12500.00 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12500.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(t@qb_v) */ * from v;",
        "Plan": [
          "IndexJoin 12500.00 root  inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12500.00 root  ",
          "  ├─IndexRangeScan(Build) 12500.00 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12500.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), hash_agg(@qb_v2) */ * from v2;",
        "Plan": [
          "HashJoin 9990.00 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "├─HashAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│ └─HashJoin 24365.26 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "│   ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│   │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "│   └─HashJoin(Probe) 19492.21 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "│     ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│     │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "│     └─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│       ├─TableReader(Build) 9990.00 root  data:Selection",
          "│       │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       │   └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│       └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "│         ├─TableReader(Build) 9980.01 root  data:Selection",
          "│         │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "│         │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│         └─TableReader(Probe) 9990.00 root  data:Selection",
          "│           └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│             └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), stream_agg(@qb_v2) */ * from v2;",
        "Plan": [
          "HashJoin 9990.00 root  inner join, equal:[eq(test.t.a, Column#19)]",
          "├─StreamAgg(Build) 7992.00 root  group by:test.t2.a, funcs:count(1)->Column#19",
          "│ └─Sort 24365.26 root  test.t2.a",
          "│   └─HashJoin 24365.26 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "│     ├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│     │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "│     └─HashJoin(Probe) 19492.21 root  inner join, equal:[eq(test.t3.a, test.t.a)]",
          "│       ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│       │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "│       └─HashJoin(Probe) 15593.77 root  inner join, equal:[eq(test.t2.b, test.t1.b)]",
          "│         ├─TableReader(Build) 9990.00 root  data:Selection",
          "│         │ └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│         │   └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "│         └─HashJoin(Probe) 12475.01 root  inner join, equal:[eq(test.t3.b, test.t2.b)]",
          "│           ├─TableReader(Build) 9980.01 root  data:Selection",
          "│           │ └─Selection 9980.01 cop[tikv]  not(isnull(test.t3.a)), not(isnull(test.t3.b))",
          "│           │   └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
          "│           └─TableReader(Probe) 9990.00 root  data:Selection",
          "│             └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.b))",
          "│               └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(t5@qb_v3, idx_a) */ * from v3;",
        "Plan": [
          "IndexLookUp 1107.78 root  ",
          "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
          "└─Selection(Probe) 1107.78 cop[tikv]  lt(test.t5.b, 2)",
          "  └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(@qb_v3 t5, idx_b) */ * from v3;",
        "Plan": [
          "IndexLookUp 1107.78 root  ",
          "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
          "└─Selection(Probe) 1107.78 cop[tikv]  gt(test.t5.a, 1)",
          "  └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(t5@qb_v3, idx_a) */ * from v3;",
        "Plan": [
          "IndexLookUp 1107.78 root  ",
          "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
          "└─Selection(Probe) 1107.78 cop[tikv]  lt(test.t5.b, 2)",
          "  └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(@qb_v3 t5, idx_b) */ * from v3;",
        "Plan": [
          "IndexLookUp 1107.78 root  ",
          "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
          "└─Selection(Probe) 1107.78 cop[tikv]  gt(test.t5.a, 1)",
          "  └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(t5@qb_v3, idx_a) */ * from v3;",
        "Plan": [
          "TableReader 1107.78 root  data:Selection",
          "└─Selection 1107.78 cop[tikv]  gt(test.t5.a, 1), lt(test.t5.b, 2)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(@qb_v3 t5, idx_b) */ * from v3;",
        "Plan": [
          "TableReader 1107.78 root  data:Selection",
          "└─Selection 1107.78 cop[tikv]  gt(test.t5.a, 1), lt(test.t5.b, 2)",
          "  └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(t5@qb_v4, idx_a, idx_b) */ * from v4;",
        "Plan": [
          "IndexMerge 5548.89 root  type: union",
          "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
          "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(@qb_v4 t5, idx_b, idx_a) */ * from v4;",
        "Plan": [
          "IndexMerge 5548.89 root  type: union",
          "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
          "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), READ_FROM_STORAGE(TIFLASH[t@qb_v], TIKV[t1@qb_v]) */ * from v;",
        "Plan": [
          "HashJoin 12500.00 root  inner join, equal:[eq(test.t.a, test.t1.a)]",
          "├─IndexReader(Build) 10000.00 root  index:IndexFullScan",
          "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v5, v5.@sel_2), SEMI_JOIN_REWRITE(@qb_v5) */ * from v5;",
        "Plan": [
          "HashJoin 9990.00 root  inner join, equal:[eq(test.t.b, test.t1.b)]",
          "├─HashAgg(Build) 7992.00 root  group by:test.t1.b, funcs:firstrow(test.t1.b)->test.t1.b",
          "│ └─TableReader 7992.00 root  data:HashAgg",
          "│   └─HashAgg 7992.00 cop[tikv]  group by:test.t1.b, ",
          "│     └─Selection 9990.00 cop[tikv]  not(isnull(test.t1.b))",
          "│       └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.b))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v6, v6.@sel_2), NO_DECORRELATE(@qb_v6) */ * from v6;",
        "Plan": [
          "Projection 10000.00 root  test.t1.a, test.t1.b",
          "└─Apply 10000.00 root  CARTESIAN inner join, other cond:lt(cast(test.t1.a, decimal(10,0) BINARY), Column#7)",
          "  ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  └─MaxOneRow(Probe) 10000.00 root  ",
          "    └─StreamAgg 10000.00 root  funcs:sum(Column#9)->Column#7",
          "      └─TableReader 10000.00 root  data:StreamAgg",
          "        └─StreamAgg 10000.00 cop[tikv]  funcs:sum(test.t2.a)->Column#9",
          "          └─Selection 100000.00 cop[tikv]  eq(test.t2.b, test.t1.b)",
          "            └─TableFullScan 100000000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v7, v7), merge(@qb_v7) */ * from v7;",
        "Plan": [
          "TableReader 3544.89 root  data:ExchangeSender",
          "└─ExchangeSender 3544.89 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 3544.89 mpp[tiflash]  Column#14, Column#15",
          "    └─HashAgg 3544.89 mpp[tiflash]  group by:Column#14, Column#15, funcs:firstrow(Column#14)->Column#14, funcs:firstrow(Column#15)->Column#15",
          "      └─ExchangeReceiver 3544.89 mpp[tiflash]  ",
          "        └─ExchangeSender 3544.89 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary], [name: Column#15, collate: binary]",
          "          └─HashAgg 3544.89 mpp[tiflash]  group by:Column#14, Column#15, ",
          "            └─Union 4431.11 mpp[tiflash]  ",
          "              ├─Projection 3323.33 mpp[tiflash]  cast(test.t.a, int(11) BINARY)->Column#14, test.t.b",
          "              │ └─Selection 3323.33 mpp[tiflash]  lt(test.t.a, 18), lt(test.t.a, 60)",
          "              │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "              └─Projection 1107.78 mpp[tiflash]  cast(test.t.a, int(11) BINARY)->Column#14, test.t.b",
          "                └─Selection 1107.78 mpp[tiflash]  gt(test.t.b, 1), lt(test.t.a, 60)",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;",
        "Plan": [
          "HashAgg 16000.00 root  group by:Column#21, funcs:firstrow(Column#21)->Column#21",
          "└─Union 1000000010000.00 root  ",
          "  ├─HashJoin 1000000000000.00 root  CARTESIAN inner join",
          "  │ ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "  │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "  │ └─CTEFullScan(Probe) 100000000.00 root CTE:cte2 data:CTE_1",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "CTE_1 100000000.00 root  Non-Recursive CTE",
          "└─HashJoin(Seed Part) 100000000.00 root  CARTESIAN inner join",
          "  ├─CTEFullScan(Build) 10000.00 root CTE:cte4 data:CTE_3",
          "  └─CTEFullScan(Probe) 10000.00 root CTE:cte3 data:CTE_2",
          "CTE_3 10000.00 root  Non-Recursive CTE",
          "└─IndexReader(Seed Part) 10000.00 root  index:IndexFullScan",
          "  └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
          "CTE_2 10000.00 root  Non-Recursive CTE",
          "└─IndexReader(Seed Part) 10000.00 root  index:IndexFullScan",
          "  └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#7)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#9)->Column#7",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(test.t.a, decimal(10,0) BINARY)->Column#9",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb_v10, v10), LIMIT_TO_COP(@qb_v10) */ * from v10;",
        "Plan": [
          "TopN 1.00 root  test.t.b, offset:0, count:1",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─TopN 1.00 mpp[tiflash]  test.t.b, offset:0, count:1",
          "      └─Selection 3333.33 mpp[tiflash]  gt(test.t.a, 10)",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_1PHASE_AGG(@qb) */ * from v11;",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, Column#4",
          "    └─Projection 8000.00 mpp[tiflash]  Column#4, test.t.a",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:Column#9, funcs:sum(Column#7)->Column#4, funcs:firstrow(Column#8)->test.t.a",
          "        └─Projection 10000.00 mpp[tiflash]  cast(test.t.b, decimal(10,0) BINARY)->Column#7, test.t.a, test.t.a",
          "          └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_2PHASE_AGG(@qb) */ * from v11;",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.t.a, Column#4",
          "    └─Projection 8000.00 mpp[tiflash]  Column#4, test.t.a",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.a, funcs:sum(Column#9)->Column#4, funcs:firstrow(test.t.a)->test.t.a",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:Column#12, funcs:sum(Column#11)->Column#9",
          "              └─Projection 10000.00 mpp[tiflash]  cast(test.t.b, decimal(10,0) BINARY)->Column#11, test.t.a",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), shuffle_join(t1@qb, t@qb) */ * from v12;",
        "Plan": [
          "Projection 12500.00 root  test.t.a, test.t.b",
          "└─TableReader 12500.00 root  data:ExchangeSender",
          "  └─ExchangeSender 12500.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashJoin 12500.00 mpp[tiflash]  inner join, equal:[eq(test.t.a, test.t.a)]",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), broadcast_join(t1@qb, t@qb) */ * from v12;",
        "Plan": [
          "TableReader 12500.00 root  data:ExchangeSender",
          "└─ExchangeSender 12500.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 12500.00 mpp[tiflash]  test.t.a, test.t.b",
          "    └─HashJoin 12500.00 mpp[tiflash]  inner join, equal:[eq(test.t.a, test.t.a)]",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      }
    ]
  },
  {
    "Name": "TestReadFromStorageHintAndIsolationRead",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t], tiflash[t]) */ avg(a) from t",
        "Plan": [
          "HashAgg 1.00 root  funcs:avg(Column#5, Column#6)->Column#4",
          "└─IndexReader 1.00 root  index:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6",
          "    └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo"
        ],
        "Warn": [
          "[planner:1815]Storage hints are conflict, you can only specify one storage type of table test.t"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t]) */ avg(a) from t",
        "Plan": [
          "HashAgg 1.00 root  funcs:avg(Column#5, Column#6)->Column#4",
          "└─IndexReader 1.00 root  index:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6",
          "    └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ avg(a) from t",
        "Plan": [
          "HashAgg 1.00 root  funcs:avg(Column#5, Column#6)->Column#4",
          "└─IndexReader 1.00 root  index:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6",
          "    └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) 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:{}])"
        ]
      }
    ]
  },
  {
    "Name": "TestIsolationReadDoNotFilterSystemDB",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select * from metrics_schema.tidb_query_duration where time >= '2019-12-23 16:10:13' and time <= '2019-12-23 16:30:13'",
        "Plan": [
          "MemTableScan 10000.00 root table:tidb_query_duration PromQL:histogram_quantile(0.9, sum(rate(tidb_server_handle_query_duration_seconds_bucket{}[60s])) by (le,sql_type,instance)), start_time:2019-12-23 16:10:13, end_time:2019-12-23 16:30:13, step:1m0s"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from information_schema.tables",
        "Plan": [
          "MemTableScan 10000.00 root table:TABLES "
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from mysql.stats_meta",
        "Plan": [
          "TableReader 10000.00 root  data:TableFullScan",
          "└─TableFullScan 10000.00 cop[tikv] table:stats_meta keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIsolationReadTiFlashNotChoosePointGet",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t where t.a = 1",
        "Result": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableRangeScan 1.00 mpp[tiflash] table:t range:[1,1], keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t where t.a in (1, 2)",
        "Result": [
          "TableReader 2.00 root  data:ExchangeSender",
          "└─ExchangeSender 2.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableRangeScan 2.00 mpp[tiflash] table:t range:[1,1], [2,2], keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIsolationReadTiFlashUseIndexHint",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from t",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select * from t use index();",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "explain format = 'brief' select /*+ use_index(t, idx)*/ * from t",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": [
          "TiDB doesn't support index in the isolation read engines(value: 'tiflash')"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ use_index(t)*/ * from t",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ],
        "Warn": null
      }
    ]
  },
  {
    "Name": "TestIssue20710",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.b",
        "Plan": [
          "IndexJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12475.01 cop[tikv]  not(isnull(test.s.b))",
          "    └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.a",
        "Plan": [
          "IndexJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12475.01 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12487.50 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.a = s.b",
        "Plan": [
          "IndexJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)",
          "├─TableReader(Build) 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",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12475.01 cop[tikv]  not(isnull(test.s.b))",
          "    └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.b",
        "Plan": [
          "IndexHashJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12475.01 cop[tikv]  not(isnull(test.s.b))",
          "    └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.a",
        "Plan": [
          "IndexHashJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t.a)), not(isnull(test.t.b))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12475.01 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12487.50 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.a = s.b",
        "Plan": [
          "IndexHashJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)",
          "├─TableReader(Build) 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",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12487.50 cop[tikv]  not(isnull(test.s.a))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 12475.01 cop[tikv]  not(isnull(test.s.b))",
          "    └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownProjectionForTiKV",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select i * 2 from t",
        "Plan": [
          "TableReader 10000.00 root  data:Projection",
          "└─Projection 10000.00 cop[tikv]  mul(test.t.i, 2)->Column#13",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select DATE_FORMAT(t, '%Y-%m-%d %H') as date from t",
        "Plan": [
          "TableReader 10000.00 root  data:Projection",
          "└─Projection 10000.00 cop[tikv]  date_format(test.t.t, %Y-%m-%d %H)->Column#13",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select md5(s) from t",
        "Plan": [
          "TableReader 10000.00 root  data:Projection",
          "└─Projection 10000.00 cop[tikv]  md5(test.t.s)->Column#13",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select c from t where a+1=3",
        "Plan": [
          "Projection 8000.00 root  test.t.c",
          "└─TableReader 8000.00 root  data:Selection",
          "  └─Selection 8000.00 cop[tikv]  eq(plus(test.t.a, 1), 3)",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(plus(test.t.id, 1))->Column#16",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#15)->Column#14",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(1)->Column#15",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:sum(plus(test.t.id, 1))->Column#16",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:count(plus(test.t.id, 1))->Column#16",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#15)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:count(1)->Column#15",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:sum(plus(test.t.id, 1))->Column#16",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(Column#13, Column#26)]",
          "├─TableReader(Build) 8000.00 root  data:Projection",
          "│ └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#26",
          "│   └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 8000.00 root  data:Projection",
          "  └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#13",
          "    └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "      └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 8000.00 root  data:Projection",
          "│ └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#25",
          "│   └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tikv]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t left join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  left outer join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 8000.00 root  data:Projection",
          "│ └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#25",
          "│   └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 12487.50 root  right outer join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 10000.00 root  data:Projection",
          "│ └─Projection 10000.00 cop[tikv]  minus(test.t.id, 2)->Column#25",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tikv]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.b, B.b from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "Projection 10000.00 root  Column#26, Column#13",
          "└─HashJoin 10000.00 root  inner join, equal:[eq(Column#13, Column#26)]",
          "  ├─TableReader(Build) 8000.00 root  data:Projection",
          "  │ └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#26",
          "  │   └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "  │     └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 8000.00 root  data:Projection",
          "    └─Projection 8000.00 cop[tikv]  minus(test.t.id, 2)->Column#13",
          "      └─Selection 8000.00 cop[tikv]  not(isnull(minus(test.t.id, 2)))",
          "        └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where exists (select 1 from t where t.id=A.id)",
        "Plan": [
          "HashJoin 7992.00 root  semi join, equal:[eq(test.t.id, test.t.id)]",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tikv]  not(isnull(test.t.id))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tikv]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tikv] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where not exists  (select 1 from t where t.id=A.id)",
        "Plan": [
          "HashJoin 8000.00 root  anti semi join, equal:[eq(test.t.id, test.t.id)]",
          "├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tikv] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' SELECT FROM_UNIXTIME(name,'%Y-%m-%d')  FROM t;",
        "Plan": [
          "Projection 10000.00 root  from_unixtime(cast(test.t.name, decimal(65,6) BINARY), %Y-%m-%d)->Column#13",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownProjectionForTiFlashCoprocessor",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select i * 2 from t",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  mul(test.t.i, 2)->Column#13",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select DATE_FORMAT(t, '%Y-%m-%d %H') as date from t",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  date_format(test.t.t, %Y-%m-%d %H)->Column#13",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select md5(s) from t",
        "Plan": [
          "Projection 10000.00 root  md5(test.t.s)->Column#13",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select c from t where a+1=3",
        "Plan": [
          "Projection 8000.00 root  test.t.c",
          "└─TableReader 8000.00 root  data:Selection",
          "  └─Selection 8000.00 cop[tiflash]  eq(plus(test.t.a, 1), 3)",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#17)->Column#14",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(Column#19)->Column#17",
          "      └─Projection 10000.00 mpp[tiflash]  plus(test.t.id, 1)->Column#19",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(test.t._tidb_rowid)->Column#16",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#17)->Column#14",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#19)->Column#17",
          "      └─Projection 10000.00 mpp[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#19",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(Column#19)->Column#16",
          "    └─Projection 10000.00 batchCop[tiflash]  plus(test.t.id, 1)->Column#19",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#15)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t._tidb_rowid)->Column#15",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#16)->Column#14",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#19)->Column#16",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#19",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 10000.00 mpp[tiflash]  inner join, equal:[eq(Column#13, Column#26)]",
          "    ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#13",
          "    │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "    │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#26",
          "      └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 8000.00 root  data:ExchangeSender",
          "│ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "│   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#25",
          "│     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "│       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t left join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  left outer join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 8000.00 root  data:ExchangeSender",
          "│ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "│   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#25",
          "│     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "│       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 12487.50 root  right outer join, equal:[eq(test.t.id, Column#25)]",
          "├─TableReader(Build) 10000.00 root  data:ExchangeSender",
          "│ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "│   └─Projection 10000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#25",
          "│     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.b, B.b from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#26, Column#13",
          "    └─HashJoin 10000.00 mpp[tiflash]  inner join, equal:[eq(Column#13, Column#26)]",
          "      ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#13",
          "      │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─Projection(Probe) 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#26",
          "        └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where exists (select 1 from t where t.id=A.id)",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  semi join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where not exists  (select 1 from t where t.id=A.id)",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 8000.00 mpp[tiflash]  anti semi join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' SELECT FROM_UNIXTIME(name,'%Y-%m-%d')  FROM t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  from_unixtime(cast(test.t.name, decimal(65,6) BINARY), %Y-%m-%d)->Column#13",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownProjectionForTiFlash",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 batchCop[tiflash]  funcs:count(Column#9)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  plus(test.t.id, 1)->Column#9",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#7)->Column#6",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 batchCop[tiflash]  funcs:count(test.t._tidb_rowid)->Column#7",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:HashAgg",
          "  └─HashAgg 1.00 batchCop[tiflash]  funcs:sum(Column#9)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#9",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(Column#10)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  plus(test.t.id, 1)->Column#10",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#7)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t._tidb_rowid)->Column#7",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from  (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#10)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#10",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(Column#5, Column#10)]",
          "├─Projection(Build) 8000.00 root  minus(test.t.id, 2)->Column#10",
          "│ └─TableReader 8000.00 root  data:Selection",
          "│   └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─Projection(Probe) 8000.00 root  minus(test.t.id, 2)->Column#5",
          "  └─TableReader 8000.00 root  data:Selection",
          "    └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "      └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  inner join, equal:[eq(test.t.id, Column#9)]",
          "├─Projection(Build) 8000.00 root  minus(test.t.id, 2)->Column#9",
          "│ └─TableReader 8000.00 root  data:Selection",
          "│   └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t left join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 10000.00 root  left outer join, equal:[eq(test.t.id, Column#9)]",
          "├─Projection(Build) 8000.00 root  minus(test.t.id, 2)->Column#9",
          "│ └─TableReader 8000.00 root  data:Selection",
          "│   └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "│     └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "HashJoin 12487.50 root  right outer join, equal:[eq(test.t.id, Column#9)]",
          "├─Projection(Build) 10000.00 root  minus(test.t.id, 2)->Column#9",
          "│ └─TableReader 10000.00 root  data:TableFullScan",
          "│   └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.b, B.b from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "Projection 10000.00 root  Column#10, Column#5",
          "└─HashJoin 10000.00 root  inner join, equal:[eq(Column#5, Column#10)]",
          "  ├─Projection(Build) 8000.00 root  minus(test.t.id, 2)->Column#10",
          "  │ └─TableReader 8000.00 root  data:Selection",
          "  │   └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "  │     └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "  └─Projection(Probe) 8000.00 root  minus(test.t.id, 2)->Column#5",
          "    └─TableReader 8000.00 root  data:Selection",
          "      └─Selection 8000.00 cop[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "        └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where exists (select 1 from t where t.id=A.id)",
        "Plan": [
          "HashJoin 7992.00 root  semi join, equal:[eq(test.t.id, test.t.id)]",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "│   └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.id from t as A where not exists  (select 1 from t where t.id=A.id)",
        "Plan": [
          "HashJoin 8000.00 root  anti semi join, equal:[eq(test.t.id, test.t.id)]",
          "├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' SELECT FROM_UNIXTIME(name,'%Y-%m-%d')  FROM t;",
        "Plan": [
          "Projection 10000.00 root  from_unixtime(cast(test.t.name, decimal(65,6) BINARY), %Y-%m-%d)->Column#5",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownProjectionForMPP",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#9)->Column#6",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(Column#11)->Column#9",
          "      └─Projection 10000.00 mpp[tiflash]  plus(test.t.id, 1)->Column#11",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(test.t._tidb_rowid)->Column#8",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#9)->Column#6",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#11)->Column#9",
          "      └─Projection 10000.00 mpp[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#11",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(Column#11)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  plus(test.t.id, 1)->Column#11",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#7)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t._tidb_rowid)->Column#7",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "StreamAgg 1.00 root  funcs:sum(Column#8)->Column#6",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:sum(Column#11)->Column#8",
          "    └─Projection 10000.00 batchCop[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#11",
          "      └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select B.b+A.b from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  plus(Column#5, Column#10)->Column#11",
          "    └─HashJoin 10000.00 mpp[tiflash]  inner join, equal:[eq(Column#5, Column#10)]",
          "      ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#5",
          "      │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─Projection(Probe) 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#10",
          "        └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 10000.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, Column#9)]",
          "    ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#9",
          "    │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "    │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t left join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 10000.00 mpp[tiflash]  left outer join, equal:[eq(test.t.id, Column#9)]",
          "    ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#9",
          "    │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "    │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id",
        "Plan": [
          "TableReader 12487.50 root  data:ExchangeSender",
          "└─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 12487.50 mpp[tiflash]  right outer join, equal:[eq(test.t.id, Column#9)]",
          "    ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 10000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#9",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select A.b, B.b from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#10, Column#5",
          "    └─HashJoin 10000.00 mpp[tiflash]  inner join, equal:[eq(Column#5, Column#10)]",
          "      ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Projection 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#5",
          "      │     └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─Projection(Probe) 8000.00 mpp[tiflash]  minus(test.t.id, 2)->Column#10",
          "        └─Selection 8000.00 mpp[tiflash]  not(isnull(minus(test.t.id, 2)))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select id from t as A where exists (select 1 from t where t.id=A.id)",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  semi join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select id from t as A where not exists (select 1 from t where t.id=A.id)",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 8000.00 mpp[tiflash]  anti semi join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:A keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select b*2, id from (select avg(value+2) as b, id from t group by id) C order by id",
        "Plan": [
          "Sort 8000.00 root  test.t.id",
          "└─TableReader 8000.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Projection 8000.00 mpp[tiflash]  mul(Column#5, 2)->Column#6, test.t.id",
          "      └─Projection 8000.00 mpp[tiflash]  div(Column#5, cast(case(eq(Column#20, 0), 1, Column#20), decimal(20,0) BINARY))->Column#5, test.t.id",
          "        └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#21)->Column#20, funcs:sum(Column#22)->Column#5, funcs:firstrow(test.t.id)->test.t.id",
          "          └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─HashAgg 8000.00 mpp[tiflash]  group by:Column#26, funcs:count(Column#24)->Column#21, funcs:sum(Column#25)->Column#22",
          "                └─Projection 10000.00 mpp[tiflash]  plus(test.t.value, 2)->Column#24, plus(test.t.value, 2)->Column#25, test.t.id",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' SELECT FROM_UNIXTIME(name,'%Y-%m-%d')  FROM t;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  from_unixtime(cast(test.t.name, decimal(65,6) BINARY), %Y-%m-%d)->Column#5",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownSelectionForMPP",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) c, id from t group by id having id >c",
        "Plan": [
          "TableReader 6400.00 root  data:ExchangeSender",
          "└─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Selection 6400.00 mpp[tiflash]  gt(test.t.id, Column#5)",
          "    └─Projection 8000.00 mpp[tiflash]  Column#5, test.t.id",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#12)->Column#5, funcs:firstrow(test.t.id)->test.t.id",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#12",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t where id < 2",
        "Plan": [
          "TableReader 3323.33 root  data:ExchangeSender",
          "└─ExchangeSender 3323.33 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Selection 3323.33 mpp[tiflash]  lt(test.t.id, 2)",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestMppUnionAll",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select count(*) from (select a , b from t union all select a , b from t1) tt",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#12)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#12",
          "      └─Union 20000.00 mpp[tiflash]  ",
          "        ├─Projection 10000.00 mpp[tiflash]  cast(test.t.a, int(11) BINARY)->Column#9, test.t.b",
          "        │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Projection 10000.00 mpp[tiflash]  test.t1.a, cast(test.t1.b, int(11) BINARY)->Column#10",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from (select a , b from t union all select a , b from t1 union all select a, b from t where false) tt",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#16)->Column#15",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#16",
          "      └─Union 20000.00 mpp[tiflash]  ",
          "        ├─Projection 10000.00 mpp[tiflash]  cast(test.t.a, int(11) BINARY)->Column#13, test.t.b",
          "        │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Projection 10000.00 mpp[tiflash]  test.t1.a, cast(test.t1.b, int(11) BINARY)->Column#14",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from (select a , b from t union all select a , c from t1) tt",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#14)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#14",
          "      └─Union 20000.00 mpp[tiflash]  ",
          "        ├─Projection 10000.00 mpp[tiflash]  cast(Column#9, int(11) BINARY)->Column#9, Column#10",
          "        │ └─Projection 10000.00 mpp[tiflash]  test.t.a, cast(test.t.b, double BINARY)->Column#10",
          "        │   └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Projection 10000.00 mpp[tiflash]  test.t1.a, cast(test.t1.c, double BINARY)->Column#10",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from (select a , b from t union all select a , c from t1 where false) tt",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#14)->Column#11",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#14",
          "      └─Union 10000.00 mpp[tiflash]  ",
          "        └─Projection 10000.00 mpp[tiflash]  cast(Column#9, int(11) BINARY)->Column#9, Column#10",
          "          └─Projection 10000.00 mpp[tiflash]  test.t.a, cast(test.t.b, double BINARY)->Column#10",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from (select a , b from t where false union all select a , c from t1 where false) tt",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#11",
          "└─Union 0.00 root  ",
          "  ├─Projection 0.00 root  test.t.a, cast(test.t.b, double BINARY)->Column#10",
          "  │ └─TableDual 0.00 root  rows:0",
          "  └─Projection 0.00 root  test.t1.a, cast(test.t1.c, double BINARY)->Column#10",
          "    └─TableDual 0.00 root  rows:0"
        ]
      }
    ]
  },
  {
    "Name": "TestMppJoinDecimal",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select t1.c1, t1.c2, t2.c1, t2.c2, t2.c3 from t t1 join t t2 on t1.c1 + 1 = t2.c2 - 10 and t1.c1 * 3 = t2.c3 / 2",
        "Plan": [
          "TableReader 12500.00 root  data:ExchangeSender",
          "└─ExchangeSender 12500.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 12500.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c1, test.t.c2, test.t.c3",
          "    └─HashJoin 12500.00 mpp[tiflash]  inner join, equal:[eq(Column#13, Column#14) eq(Column#15, Column#16)]",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#23, collate: binary], [name: Column#24, collate: binary]",
          "      │   └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, Column#13, Column#15, cast(Column#13, decimal(13,8) BINARY)->Column#23, cast(Column#15, decimal(10,5) BINARY)->Column#24",
          "      │     └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, mul(test.t.c1, 3)->Column#13, plus(test.t.c1, 1)->Column#15",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary], [name: Column#16, collate: binary]",
          "          └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, div(test.t.c3, 2)->Column#14, minus(test.t.c2, 10)->Column#16",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select c1, c2, c5, count(*) c from t group by c1, c2, c5) t1 join (select c1, c2, c3, count(*) c from t group by c1, c2, c3) t2 on t1.c1 = t2.c2 and t1.c2 = t2.c3 and t1.c5 = t2.c1",
        "Plan": [
          "TableReader 7976.02 root  data:ExchangeSender",
          "└─ExchangeSender 7976.02 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 7976.02 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c5, Column#7, test.t.c1, test.t.c2, test.t.c3, Column#14",
          "    └─HashJoin 7976.02 mpp[tiflash]  inner join, equal:[eq(test.t.c1, test.t.c2) eq(test.t.c2, test.t.c3) eq(test.t.c5, test.t.c1)]",
          "      ├─ExchangeReceiver(Build) 7976.02 mpp[tiflash]  ",
          "      │ └─ExchangeSender 7976.02 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: Column#58, collate: binary], [name: test.t.c5, collate: binary]",
          "      │   └─Projection 7976.02 mpp[tiflash]  Column#7, test.t.c1, test.t.c2, test.t.c5, cast(test.t.c2, decimal(10,5))->Column#58",
          "      │     └─Projection 7976.02 mpp[tiflash]  Column#7, test.t.c1, test.t.c2, test.t.c5",
          "      │       └─HashAgg 7976.02 mpp[tiflash]  group by:test.t.c1, test.t.c2, test.t.c5, funcs:sum(Column#15)->Column#7, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c5)->test.t.c5",
          "      │         └─ExchangeReceiver 7976.02 mpp[tiflash]  ",
          "      │           └─ExchangeSender 7976.02 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: test.t.c2, collate: binary], [name: test.t.c5, collate: binary]",
          "      │             └─HashAgg 7976.02 mpp[tiflash]  group by:test.t.c1, test.t.c2, test.t.c5, funcs:count(1)->Column#15",
          "      │               └─Selection 9970.03 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "      │                 └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 7984.01 mpp[tiflash]  ",
          "        └─ExchangeSender 7984.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: Column#59, collate: binary], [name: Column#60, collate: binary]",
          "          └─Projection 7984.01 mpp[tiflash]  Column#14, test.t.c1, test.t.c2, test.t.c3, cast(test.t.c3, decimal(10,5))->Column#59, cast(test.t.c1, decimal(40,20))->Column#60",
          "            └─Projection 7984.01 mpp[tiflash]  Column#14, test.t.c1, test.t.c2, test.t.c3",
          "              └─HashAgg 7984.01 mpp[tiflash]  group by:test.t.c1, test.t.c2, test.t.c3, funcs:sum(Column#23)->Column#14, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c3)->test.t.c3",
          "                └─ExchangeReceiver 7984.01 mpp[tiflash]  ",
          "                  └─ExchangeSender 7984.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c1, collate: binary]",
          "                    └─HashAgg 7984.01 mpp[tiflash]  group by:test.t.c1, test.t.c2, test.t.c3, funcs:count(1)->Column#23",
          "                      └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2))",
          "                        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t t1 join t t2 on t1.c1 = t2.c2 and t1.c2 = t2.c2 and t1.c3 = t2.c3 and t1.c4 = t2.c4 and t1.c5 = t2.c5",
        "Plan": [
          "TableReader 12462.54 root  data:ExchangeSender",
          "└─ExchangeSender 12462.54 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 12462.54 mpp[tiflash]  inner join, equal:[eq(test.t.c1, test.t.c2) eq(test.t.c2, test.t.c2) eq(test.t.c3, test.t.c3) eq(test.t.c4, test.t.c4) eq(test.t.c5, test.t.c5)]",
          "    ├─ExchangeReceiver(Build) 9970.03 mpp[tiflash]  ",
          "    │ └─ExchangeSender 9970.03 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: test.t.c2, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c4, collate: binary], [name: test.t.c5, collate: binary]",
          "    │   └─Selection 9970.03 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "    │     └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo",
          "    └─ExchangeReceiver(Probe) 9980.01 mpp[tiflash]  ",
          "      └─ExchangeSender 9980.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: test.t.c2, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c4, collate: binary], [name: test.t.c5, collate: binary]",
          "        └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t t1 join t t2 on t1.c1 = t2.c2 and t1.c2 = t2.c3 and t1.c3 = t2.c1 and t1.c4 = t2.c3 and t1.c1 = t2.c5",
        "Plan": [
          "TableReader 12462.54 root  data:ExchangeSender",
          "└─ExchangeSender 12462.54 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 12462.54 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5",
          "    └─HashJoin 12462.54 mpp[tiflash]  inner join, equal:[eq(test.t.c2, test.t.c1) eq(test.t.c3, test.t.c2) eq(test.t.c1, test.t.c3) eq(test.t.c3, test.t.c4) eq(test.t.c5, test.t.c1)]",
          "      ├─ExchangeReceiver(Build) 9970.03 mpp[tiflash]  ",
          "      │ └─ExchangeSender 9970.03 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: Column#18, collate: binary], [name: Column#20, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c5, collate: binary]",
          "      │   └─Projection 9970.03 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(10,5))->Column#18, cast(test.t.c1, decimal(10,5))->Column#20",
          "      │     └─Selection 9970.03 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 9980.01 mpp[tiflash]  ",
          "        └─ExchangeSender 9980.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: Column#19, collate: binary], [name: Column#21, collate: binary], [name: test.t.c4, collate: binary], [name: Column#22, collate: binary]",
          "          └─Projection 9980.01 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c2, decimal(10,5))->Column#19, cast(test.t.c3, decimal(10,5))->Column#21, cast(test.t.c1, decimal(40,20))->Column#22",
          "            └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2))",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t t1 join t t2 on t1.c1 + t1.c2 = t2.c2 / t2.c3",
        "Plan": [
          "TableReader 12500.00 root  data:ExchangeSender",
          "└─ExchangeSender 12500.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 12500.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5",
          "    └─HashJoin 12500.00 mpp[tiflash]  inner join, equal:[eq(Column#13, Column#14)]",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#18, collate: binary]",
          "      │   └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, Column#13, cast(Column#13, decimal(17,9) BINARY)->Column#18",
          "      │     └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, plus(test.t.c1, test.t.c2)->Column#13",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary]",
          "          └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, div(test.t.c2, test.t.c3)->Column#14",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t t1 where exists (select * from t t2 where t1.c1 = t2.c2 and t1.c2 = t2.c3 and t1.c3 = t2.c1 and t1.c4 = t2.c3 and t1.c1 = t2.c5)",
        "Plan": [
          "TableReader 7984.01 root  data:ExchangeSender",
          "└─ExchangeSender 7984.01 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 7984.01 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5",
          "    └─HashJoin 7984.01 mpp[tiflash]  semi join, equal:[eq(test.t.c1, test.t.c2) eq(test.t.c2, test.t.c3) eq(test.t.c3, test.t.c1) eq(test.t.c4, test.t.c3) eq(test.t.c1, test.t.c5)]",
          "      ├─ExchangeReceiver(Build) 9970.03 mpp[tiflash]  ",
          "      │ └─ExchangeSender 9970.03 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: Column#19, collate: binary], [name: Column#21, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c5, collate: binary]",
          "      │   └─Projection 9970.03 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c5, cast(test.t.c3, decimal(10,5))->Column#19, cast(test.t.c1, decimal(10,5))->Column#21",
          "      │     └─Selection 9970.03 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "      │       └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo",
          "      └─ExchangeReceiver(Probe) 9980.01 mpp[tiflash]  ",
          "        └─ExchangeSender 9980.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: Column#18, collate: binary], [name: Column#20, collate: binary], [name: test.t.c4, collate: binary], [name: Column#22, collate: binary]",
          "          └─Projection 9980.01 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c2, decimal(10,5))->Column#18, cast(test.t.c3, decimal(10,5))->Column#20, cast(test.t.c1, decimal(40,20))->Column#22",
          "            └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.c1)), not(isnull(test.t.c2))",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t t1 left join t t2 on t1.c1 = t2.c2 join t t3 on t2.c5 = t3.c3 right join t t4 on t3.c3 = t4.c4 ",
        "Plan": [
          "TableReader 19492.21 root  data:ExchangeSender",
          "└─ExchangeSender 19492.21 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 19492.21 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5",
          "    └─HashJoin 19492.21 mpp[tiflash]  right outer join, equal:[eq(test.t.c3, test.t.c4)]",
          "      ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "      │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#29, collate: binary]",
          "      │   └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c4, decimal(40,20))->Column#29",
          "      │     └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo",
          "      └─Projection(Probe) 15593.77 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5",
          "        └─HashJoin 15593.77 mpp[tiflash]  inner join, equal:[eq(test.t.c5, test.t.c3)]",
          "          ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#25, collate: binary]",
          "          │   └─Projection 10000.00 mpp[tiflash]  test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(40,20))->Column#25",
          "          │     └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo",
          "          └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash]  ",
          "            └─ExchangeSender 12475.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c5, collate: binary]",
          "              └─HashJoin 12475.01 mpp[tiflash]  inner join, equal:[eq(test.t.c2, test.t.c1)]",
          "                ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash]  ",
          "                │ └─ExchangeSender 9980.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary]",
          "                │   └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.c2)), not(isnull(test.t.c5))",
          "                │     └─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, Hash Cols: [name: test.t.c1, collate: binary]",
          "                    └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.c1))",
          "                      └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' SELECT STRAIGHT_JOIN t1 . col_varchar_64 , t1 . col_char_64_not_null FROM tt AS t1 INNER JOIN( tt AS t2 JOIN tt AS t3 ON(t3 . col_decimal_30_10_key = t2 . col_tinyint)) ON(t3 . col_varchar_64 = t2 . col_varchar_key) WHERE t3 . col_varchar_64 = t1 . col_char_64_not_null GROUP BY 1 , 2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  test.tt.col_varchar_64, test.tt.col_char_64_not_null",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.tt.col_char_64_not_null, test.tt.col_varchar_64, funcs:firstrow(test.tt.col_varchar_64)->test.tt.col_varchar_64, funcs:firstrow(test.tt.col_char_64_not_null)->test.tt.col_char_64_not_null",
          "      └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.tt.col_varchar_64, collate: utf8mb4_bin], [name: test.tt.col_char_64_not_null, collate: utf8mb4_bin]",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:test.tt.col_char_64_not_null, test.tt.col_varchar_64, ",
          "            └─HashJoin 15609.38 mpp[tiflash]  inner join, equal:[eq(test.tt.col_char_64_not_null, test.tt.col_varchar_64)]",
          "              ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.tt.col_char_64_not_null, collate: utf8mb4_bin]",
          "              │   └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo",
          "              └─HashJoin(Probe) 12487.50 mpp[tiflash]  inner join, equal:[eq(test.tt.col_varchar_key, test.tt.col_varchar_64) eq(Column#19, test.tt.col_decimal_30_10_key)]",
          "                ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "                │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.tt.col_varchar_key, collate: utf8mb4_bin]",
          "                │   └─Projection 9990.00 mpp[tiflash]  test.tt.col_varchar_key, cast(test.tt.col_tinyint, decimal(3,0) BINARY)->Column#19",
          "                │     └─Selection 9990.00 mpp[tiflash]  not(isnull(test.tt.col_varchar_key))",
          "                │       └─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, Hash Cols: [name: test.tt.col_varchar_64, collate: utf8mb4_bin]",
          "                    └─Selection 9990.00 mpp[tiflash]  not(isnull(test.tt.col_varchar_64))",
          "                      └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestMppJoinExchangeColumnPrune",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select * from tt t1 where exists (select * from t t2 where t1.b1 = t2.c3 and t2.c1 < t2.c2)",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  semi join, equal:[eq(test.tt.b1, test.t.c3)]",
          "    ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.c3, collate: binary]",
          "    │   └─Projection 8000.00 mpp[tiflash]  test.t.c3",
          "    │     └─Selection 8000.00 mpp[tiflash]  lt(test.t.c1, test.t.c2)",
          "    │       └─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, Hash Cols: [name: test.tt.b1, collate: binary]",
          "        └─Selection 9990.00 mpp[tiflash]  not(isnull(test.tt.b1))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownAggForMPP",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#8)->Column#5",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(Column#10)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  plus(test.t.id, 1)->Column#10",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from  (select id+1 from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#7)->Column#5",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(test.t._tidb_rowid)->Column#7",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from  (select id + 1 as b from t)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#8)->Column#5",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#10)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#10",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*) from t",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#7)->Column#4",
          "└─TableReader 1.00 root  data:StreamAgg",
          "  └─StreamAgg 1.00 batchCop[tiflash]  funcs:count(test.t._tidb_rowid)->Column#7",
          "    └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*), id from t group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#4, test.t.id",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#11)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "      └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#11",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*), id + 1 from t group by id + 1",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#4, plus(test.t.id, 1)->Column#5",
          "    └─Projection 8000.00 mpp[tiflash]  Column#4, test.t.id",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:Column#16, funcs:sum(Column#17)->Column#4, funcs:firstrow(Column#18)->test.t.id",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#16, collate: binary]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:Column#20, funcs:count(1)->Column#17, funcs:firstrow(Column#19)->Column#18",
          "              └─Projection 10000.00 mpp[tiflash]  test.t.id, plus(test.t.id, 1)->Column#20",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(*), id from t group by id) as A on A.id = t.id",
        "Plan": [
          "TableReader 9990.00 root  data:ExchangeSender",
          "└─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─Projection(Build) 7992.00 mpp[tiflash]  Column#7, test.t.id",
          "    │ └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "    │   └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │     └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │       └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#8",
          "    │         └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │           └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash]  ",
          "      └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "        └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select /*+ hash_agg()*/  count(*) as a from t) as A on A.a = t.id",
        "Plan": [
          "HashJoin 1.25 root  inner join, equal:[eq(test.t.id, Column#7)]",
          "├─HashAgg(Build) 1.00 root  funcs:count(Column#11)->Column#7",
          "│ └─TableReader 1.00 root  data:ExchangeSender",
          "│   └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "│     └─HashAgg 1.00 mpp[tiflash]  funcs:count(test.t._tidb_rowid)->Column#11",
          "│       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select avg(value) as b,id from t group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#17, 0), 1, Column#17), decimal(20,0) BINARY))->Column#4, test.t.id",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#18)->Column#17, funcs:sum(Column#19)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "      └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(test.t.value)->Column#18, funcs:sum(test.t.value)->Column#19",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+hash_agg()*/ sum(b) from (select avg(value) as b, id from t group by id)A",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#18)->Column#5",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#4)->Column#18",
          "      └─Projection 8000.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#15, 0), 1, Column#15), decimal(20,0) BINARY))->Column#4",
          "        └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#16)->Column#15, funcs:sum(Column#17)->Column#4",
          "          └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(test.t.value)->Column#16, funcs:sum(test.t.value)->Column#17",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select id from t group by id having avg(value)>0",
        "Plan": [
          "TableReader 6400.00 root  data:ExchangeSender",
          "└─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 6400.00 mpp[tiflash]  test.t.id",
          "    └─Selection 6400.00 mpp[tiflash]  gt(Column#4, 0)",
          "      └─Projection 8000.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#18, 0), 1, Column#18), decimal(20,0) BINARY))->Column#4, test.t.id",
          "        └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#19)->Column#18, funcs:sum(Column#20)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "          └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(test.t.value)->Column#19, funcs:sum(test.t.value)->Column#20",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select avg(value),id from t group by id having avg(value)>0",
        "Plan": [
          "TableReader 6400.00 root  data:ExchangeSender",
          "└─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Selection 6400.00 mpp[tiflash]  gt(Column#4, 0)",
          "    └─Projection 8000.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#4, test.t.id",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#20)->Column#19, funcs:sum(Column#21)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(test.t.value)->Column#20, funcs:sum(test.t.value)->Column#21",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select avg(value) +1,id from t group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  plus(Column#4, 1)->Column#5, test.t.id",
          "    └─Projection 8000.00 mpp[tiflash]  div(Column#4, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#4, test.t.id",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#20)->Column#19, funcs:sum(Column#21)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(test.t.value)->Column#20, funcs:sum(test.t.value)->Column#21",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select sum(b) from (select t.id, t1.id as b from t join t t1 on t.id=t1.id)A group by id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 7992.00 mpp[tiflash]  Column#7",
          "    └─HashAgg 7992.00 mpp[tiflash]  group by:Column#12, funcs:sum(Column#11)->Column#7",
          "      └─Projection 12487.50 mpp[tiflash]  cast(test.t.id, decimal(10,0) BINARY)->Column#11, test.t.id",
          "        └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "          ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "          │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "          └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash]  ",
          "            └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id from t group by id) C join (select sum(b),id from (select t.id, t1.id as b from t join (select id, count(*) as c from t group by id) t1 on t.id=t1.id)A group by id)B on C.id=b.id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─Projection(Build) 7992.00 mpp[tiflash]  test.t.id",
          "    │ └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id",
          "    │   └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │     └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │       └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, ",
          "    │         └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │           └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 7992.00 mpp[tiflash]  Column#11, test.t.id",
          "      └─HashAgg 7992.00 mpp[tiflash]  group by:Column#39, funcs:sum(Column#37)->Column#11, funcs:firstrow(Column#38)->test.t.id",
          "        └─Projection 9990.00 mpp[tiflash]  cast(test.t.id, decimal(10,0) BINARY)->Column#37, test.t.id, test.t.id",
          "          └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "            ├─Projection(Build) 7992.00 mpp[tiflash]  test.t.id, Column#13",
          "            │ └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:sum(Column#17)->Column#13",
          "            │   └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "            │     └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            │       └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#17",
          "            │         └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "            │           └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "            └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash]  ",
          "              └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "                └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(distinct value),id from t group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#4, test.t.id",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(distinct test.t.value)->Column#4, funcs:firstrow(test.t.id)->test.t.id",
          "      └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.value, ",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(distinct value),sum(distinct value),id from t group by id",
        "Plan": [
          "HashAgg 8000.00 root  group by:test.t.id, funcs:count(distinct test.t.value)->Column#4, funcs:sum(distinct test.t.value)->Column#5, funcs:firstrow(test.t.id)->test.t.id",
          "└─TableReader 10000.00 root  data:TableFullScan",
          "  └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(distinct value), id from t group by id) as A on A.id = t.id",
        "Plan": [
          "TableReader 9990.00 root  data:ExchangeSender",
          "└─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─Projection(Build) 7992.00 mpp[tiflash]  Column#7, test.t.id",
          "    │ └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:count(distinct test.t.value)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "    │   └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │     └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │       └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, test.t.value, ",
          "    │         └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │           └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash]  ",
          "      └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "        └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(1/value), id from t group by id) as A on A.id = t.id",
        "Plan": [
          "TableReader 9990.00 root  data:ExchangeSender",
          "└─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─Projection(Build) 7992.00 mpp[tiflash]  Column#7, test.t.id",
          "    │ └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "    │   └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │     └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │       └─HashAgg 7992.00 mpp[tiflash]  group by:Column#19, funcs:count(Column#18)->Column#8",
          "    │         └─Projection 9990.00 mpp[tiflash]  div(1, test.t.value)->Column#18, test.t.id",
          "    │           └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │             └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash]  ",
          "      └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "        └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+hash_agg()*/ sum(id) from (select value, id from t where id > value group by id, value)A group by value /*the exchange should have only one partition column: test.t.value*/",
        "Plan": [
          "TableReader 6400.00 root  data:ExchangeSender",
          "└─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 6400.00 mpp[tiflash]  Column#4",
          "    └─HashAgg 6400.00 mpp[tiflash]  group by:Column#21, funcs:sum(Column#20)->Column#4",
          "      └─Projection 6400.00 mpp[tiflash]  cast(test.t.id, decimal(10,0) BINARY)->Column#20, test.t.value",
          "        └─Projection 6400.00 mpp[tiflash]  test.t.id, test.t.value",
          "          └─HashAgg 6400.00 mpp[tiflash]  group by:test.t.id, test.t.value, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value",
          "            └─ExchangeReceiver 6400.00 mpp[tiflash]  ",
          "              └─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary]",
          "                └─HashAgg 6400.00 mpp[tiflash]  group by:test.t.id, test.t.value, ",
          "                  └─Selection 8000.00 mpp[tiflash]  gt(cast(test.t.id, decimal(10,0) BINARY), test.t.value)",
          "                    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+hash_agg()*/ sum(B.value) from t as B where B.id+1 > (select count(*) from t where t.id= B.id and t.value=B.value) group by B.id /*the exchange should have only one partition column: test.t.id*/",
        "Plan": [
          "TableReader 6400.00 root  data:ExchangeSender",
          "└─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 6400.00 mpp[tiflash]  Column#8",
          "    └─HashAgg 6400.00 mpp[tiflash]  group by:test.t.id, funcs:sum(test.t.value)->Column#8",
          "      └─Selection 8000.00 mpp[tiflash]  gt(plus(test.t.id, 1), ifnull(Column#7, 0))",
          "        └─HashJoin 10000.00 mpp[tiflash]  left outer join, equal:[eq(test.t.id, test.t.id) eq(test.t.value, test.t.value)]",
          "          ├─Projection(Build) 7984.01 mpp[tiflash]  Column#7, test.t.id, test.t.value",
          "          │ └─HashAgg 7984.01 mpp[tiflash]  group by:test.t.id, test.t.value, funcs:sum(Column#24)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value",
          "          │   └─ExchangeReceiver 7984.01 mpp[tiflash]  ",
          "          │     └─ExchangeSender 7984.01 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "          │       └─HashAgg 7984.01 mpp[tiflash]  group by:test.t.id, test.t.value, funcs:count(1)->Column#24",
          "          │         └─Selection 9980.01 mpp[tiflash]  not(isnull(test.t.id)), not(isnull(test.t.value))",
          "          │           └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "          └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:B keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(distinct value) from t",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#4",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#6)->Column#4",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  funcs:count(distinct test.t.value)->Column#6",
          "            └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "              └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary]",
          "                └─HashAgg 1.00 mpp[tiflash]  group by:test.t.value, ",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(distinct x ) from (select count(distinct value) x from t) t",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(distinct Column#4)->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  Column#4",
          "        └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#7)->Column#4",
          "          └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "            └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "              └─HashAgg 1.00 mpp[tiflash]  funcs:count(distinct test.t.value)->Column#7",
          "                └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "                  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary]",
          "                    └─HashAgg 1.00 mpp[tiflash]  group by:test.t.value, ",
          "                      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(distinct value), count(value), avg(value) from t",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#4, Column#5, div(Column#6, cast(case(eq(Column#15, 0), 1, Column#15), decimal(20,0) BINARY))->Column#6",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(Column#19)->Column#4, funcs:sum(Column#20)->Column#5, funcs:sum(Column#21)->Column#15, funcs:sum(Column#22)->Column#6",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  funcs:count(distinct test.t.value)->Column#19, funcs:sum(Column#16)->Column#20, funcs:sum(Column#17)->Column#21, funcs:sum(Column#18)->Column#22",
          "            └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "              └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary]",
          "                └─HashAgg 1.00 mpp[tiflash]  group by:test.t.value, funcs:count(test.t.value)->Column#16, funcs:count(test.t.value)->Column#17, funcs:sum(test.t.value)->Column#18",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestMppAggTopNWithJoin",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(*), id from t group by id) as A on A.id = t.id",
        "Plan": [
          "TableReader 9990.00 root  data:ExchangeSender",
          "└─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 7992.00 mpp[tiflash]  Column#7, test.t.id",
          "    │     └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "    │       └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │         └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │           └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#8",
          "    │             └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │               └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(*)+id as v from t group by id) as A on A.v = t.id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 8000.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, Column#8)]",
          "    ├─ExchangeReceiver(Build) 6400.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 6400.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 6400.00 mpp[tiflash]  plus(Column#7, test.t.id)->Column#8",
          "    │     └─Selection 6400.00 mpp[tiflash]  not(isnull(plus(Column#7, test.t.id)))",
          "    │       └─Projection 8000.00 mpp[tiflash]  Column#7, test.t.id",
          "    │         └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#11)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "    │           └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "    │             └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │               └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#11",
          "    │                 └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select count(*) as v, id from t group by value,id having value+v <10) as A on A.id = t.id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 7992.00 mpp[tiflash]  test.t.id, test.t.value, Column#7, test.t.id",
          "    └─HashJoin 7992.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "      ├─ExchangeReceiver(Build) 6393.60 mpp[tiflash]  ",
          "      │ └─ExchangeSender 6393.60 mpp[tiflash]  ExchangeType: Broadcast",
          "      │   └─Selection 6393.60 mpp[tiflash]  lt(plus(test.t.value, cast(Column#7, decimal(20,0) BINARY)), 10)",
          "      │     └─Projection 7992.00 mpp[tiflash]  Column#7, test.t.id, test.t.value",
          "      │       └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, test.t.value, funcs:sum(Column#10)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value",
          "      │         └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "      │           └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary], [name: test.t.id, collate: binary]",
          "      │             └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, test.t.value, funcs:count(1)->Column#10",
          "      │               └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "      │                 └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "      └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join ( select /*+ hash_agg()*/  count(*) as a from t) as A on A.a = t.id",
        "Plan": [
          "HashJoin 1.25 root  inner join, equal:[eq(test.t.id, Column#7)]",
          "├─HashAgg(Build) 1.00 root  funcs:count(Column#10)->Column#7",
          "│ └─TableReader 1.00 root  data:ExchangeSender",
          "│   └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "│     └─HashAgg 1.00 mpp[tiflash]  funcs:count(test.t._tidb_rowid)->Column#10",
          "│       └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9990.00 root  data:Selection",
          "  └─Selection 9990.00 cop[tiflash]  not(isnull(test.t.id))",
          "    └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select sum(b) from (select t.id, t1.id as b from t join t t1 on t.id=t1.id)A group by id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 7992.00 mpp[tiflash]  Column#7",
          "    └─HashAgg 7992.00 mpp[tiflash]  group by:Column#12, funcs:sum(Column#11)->Column#7",
          "      └─Projection 12487.50 mpp[tiflash]  cast(test.t.id, decimal(10,0) BINARY)->Column#11, test.t.id",
          "        └─ExchangeReceiver 12487.50 mpp[tiflash]  ",
          "          └─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "              ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "              │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "              │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "              └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id from t group by id) C join (select sum(value),id from t group by id)B on C.id=B.id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 7992.00 mpp[tiflash]  test.t.id",
          "    │     └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id",
          "    │       └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │         └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │           └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, ",
          "    │             └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │               └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 7992.00 mpp[tiflash]  Column#7, test.t.id",
          "      └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:sum(Column#9)->Column#7, funcs:firstrow(test.t.id)->test.t.id",
          "        └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "          └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "            └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:sum(test.t.value)->Column#9",
          "              └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id from t group by id) C join (select sum(b),id from (select t.id, t1.id as b from t join (select id, count(*) as c from t group by id) t1 on t.id=t1.id)A group by id)B on C.id=b.id",
        "Plan": [
          "TableReader 7992.00 root  data:ExchangeSender",
          "└─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─HashJoin 7992.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "    ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash]  ",
          "    │ └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: Broadcast",
          "    │   └─Projection 7992.00 mpp[tiflash]  test.t.id",
          "    │     └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id",
          "    │       └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "    │         └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "    │           └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, ",
          "    │             └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "    │               └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 7992.00 mpp[tiflash]  Column#11, test.t.id",
          "      └─HashAgg 7992.00 mpp[tiflash]  group by:Column#34, funcs:sum(Column#32)->Column#11, funcs:firstrow(Column#33)->test.t.id",
          "        └─Projection 9990.00 mpp[tiflash]  cast(test.t.id, decimal(10,0) BINARY)->Column#32, test.t.id, test.t.id",
          "          └─ExchangeReceiver 9990.00 mpp[tiflash]  ",
          "            └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "              └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "                ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash]  ",
          "                │ └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: Broadcast",
          "                │   └─Projection 7992.00 mpp[tiflash]  test.t.id, Column#13",
          "                │     └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:sum(Column#16)->Column#13",
          "                │       └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "                │         └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "                │           └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:count(1)->Column#16",
          "                │             └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                │               └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "                └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join t t1 on t.id = t1.id order by t.value limit 1",
        "Plan": [
          "TopN 1.00 root  test.t.value, offset:0, count:1",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─TopN 1.00 mpp[tiflash]  test.t.value, offset:0, count:1",
          "      └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "        ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join t t1 on t.id = t1.id order by t.value % 100 limit 1",
        "Plan": [
          "Projection 1.00 root  test.t.id, test.t.value, test.t.id, test.t.value",
          "└─TopN 1.00 root  Column#8, offset:0, count:1",
          "  └─Projection 1.00 root  test.t.id, test.t.value, test.t.id, test.t.value, mod(test.t.value, 100)->Column#8",
          "    └─TableReader 1.00 root  data:ExchangeSender",
          "      └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "        └─Projection 1.00 mpp[tiflash]  test.t.id, test.t.value, test.t.id, test.t.value",
          "          └─TopN 1.00 mpp[tiflash]  Column#7, offset:0, count:1",
          "            └─Projection 12487.50 mpp[tiflash]  test.t.id, test.t.value, test.t.id, test.t.value, mod(test.t.value, 100)->Column#7",
          "              └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "                ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "                │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "                │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "                └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*) from (select t.id, t.value v1 from t join t t1 on t.id = t1.id order by t.value limit 20) v group by v.v1",
        "Plan": [
          "StreamAgg 20.00 root  group by:test.t.value, funcs:count(1)->Column#7",
          "└─TopN 20.00 root  test.t.value, offset:0, count:20",
          "  └─TableReader 20.00 root  data:ExchangeSender",
          "    └─ExchangeSender 20.00 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─TopN 20.00 mpp[tiflash]  test.t.value, offset:0, count:20",
          "        └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "          ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "          │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "          └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join t t1 on t.id = t1.id limit 1",
        "Plan": [
          "Limit 1.00 root  offset:0, count:1",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Limit 1.00 mpp[tiflash]  offset:0, count:1",
          "      └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "        ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Selection(Probe) 0.80 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 0.80 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t join t t1 on t.id = t1.id limit 1",
        "Plan": [
          "Limit 1.00 root  offset:0, count:1",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Limit 1.00 mpp[tiflash]  offset:0, count:1",
          "      └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "        ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Selection(Probe) 0.80 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 0.80 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*) from (select t.id, t.value v1 from t join t t1 on t.id = t1.id limit 20) v group by v.v1",
        "Plan": [
          "HashAgg 20.00 root  group by:test.t.value, funcs:count(1)->Column#7",
          "└─Limit 20.00 root  offset:0, count:20",
          "  └─TableReader 20.00 root  data:ExchangeSender",
          "    └─ExchangeSender 20.00 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─Limit 20.00 mpp[tiflash]  offset:0, count:20",
          "        └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "          ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "          │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "          └─Selection(Probe) 16.00 mpp[tiflash]  not(isnull(test.t.id))",
          "            └─TableFullScan 16.02 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexMergeSerial",
    "Cases": [
      {
        "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where a =1 or (b=1 and b+2>1)",
        "Plan": [
          "IndexMerge 8.00 root  type: union",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false",
          "├─Selection(Build) 1.00 cop[tikv]  1",
          "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false",
          "└─TableRowIDScan(Probe) 8.00 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      },
      {
        "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where a =1 or (b=1 and length(b)=1)",
        "Plan": [
          "IndexMerge 8.00 root  type: union",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false",
          "├─Selection(Build) 1.00 cop[tikv]  1",
          "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false",
          "└─TableRowIDScan(Probe) 8.00 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      },
      {
        "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where (a=1 and length(a)=1) or (b=1 and length(b)=1)",
        "Plan": [
          "IndexMerge 8.00 root  type: union",
          "├─Selection(Build) 1.00 cop[tikv]  1",
          "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false",
          "├─Selection(Build) 1.00 cop[tikv]  1",
          "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false",
          "└─TableRowIDScan(Probe) 8.00 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      },
      {
        "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where (a=1 and length(b)=1) or (b=1 and length(a)=1)",
        "Plan": [
          "IndexMerge 0.29 root  type: union",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false",
          "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false",
          "└─Selection(Probe) 0.29 cop[tikv]  or(and(eq(test.t.a, 1), eq(length(cast(test.t.b, var_string(20))), 1)), and(eq(test.t.b, 1), eq(length(cast(test.t.a, var_string(20))), 1)))",
          "  └─TableRowIDScan 1.90 cop[tikv] table:t keep order:false"
        ],
        "Warnings": null
      }
    ]
  },
  {
    "Name": "TestLimitIndexLookUpKeepOrder",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select * from t where a = 1 and b > 2 and b < 10 and d = 10 order by b,c limit 10",
        "Plan": [
          "Limit 0.00 root  offset:0, count:10",
          "└─Projection 0.00 root  test.t.a, test.t.b, test.t.c, test.t.d",
          "  └─IndexLookUp 0.00 root  ",
          "    ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:true, stats:pseudo",
          "    └─Selection(Probe) 0.00 cop[tikv]  eq(test.t.d, 10)",
          "      └─TableRowIDScan 2.50 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from t where a = 1 and b > 2 and b < 10 and d = 10 order by b desc, c desc limit 10",
        "Plan": [
          "Limit 0.00 root  offset:0, count:10",
          "└─Projection 0.00 root  test.t.a, test.t.b, test.t.c, test.t.d",
          "  └─IndexLookUp 0.00 root  ",
          "    ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:true, desc, stats:pseudo",
          "    └─Selection(Probe) 0.00 cop[tikv]  eq(test.t.d, 10)",
          "      └─TableRowIDScan 2.50 cop[tikv] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue23887",
    "Cases": [
      {
        "SQL": "select (2) in (select b from t) from (select t.a < (select t.a from t t1 limit 1) from t) t",
        "Plan": [
          "HashJoin 10000.00 root  CARTESIAN left outer semi join, other cond:eq(2, test.t.b)",
          "├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "└─Projection(Probe) 10000.00 root  1->Column#27",
          "  └─Apply 10000.00 root  CARTESIAN left outer join",
          "    ├─TableReader(Build) 10000.00 root  data:TableFullScan",
          "    │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
          "    └─Projection(Probe) 10000.00 root  1->Column#25",
          "      └─Limit 10000.00 root  offset:0, count:1",
          "        └─TableReader 10000.00 root  data:Limit",
          "          └─Limit 10000.00 cop[tikv]  offset:0, count:1",
          "            └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Res": [
          "1",
          "1"
        ]
      }
    ]
  },
  {
    "Name": "TestMergeContinuousSelections",
    "Cases": [
      {
        "SQL": "desc format = 'brief' SELECT table2 . `col_char_64` AS field1 FROM `ts` AS table2 INNER JOIN (SELECT DISTINCT SUBQUERY3_t1 . * FROM `ts` AS SUBQUERY3_t1 LEFT OUTER JOIN `ts` AS SUBQUERY3_t2 ON SUBQUERY3_t2 . `col_varchar_64_not_null` = SUBQUERY3_t1 . `col_varchar_key`) AS table3 ON (table3 . `col_varchar_key` = table2 . `col_varchar_64`) WHERE table3 . `col_char_64_not_null` >= SOME (SELECT SUBQUERY4_t1 . `col_varchar_64` AS SUBQUERY4_field1 FROM `ts` AS SUBQUERY4_t1) GROUP BY field1 ;",
        "Plan": [
          "HashAgg 7992.00 root  group by:test.ts.col_char_64, funcs:firstrow(test.ts.col_char_64)->test.ts.col_char_64",
          "└─HashJoin 9990.00 root  CARTESIAN inner join, other cond:or(ge(test.ts.col_char_64_not_null, Column#25), if(ne(Column#26, 0), NULL, 0))",
          "  ├─Selection(Build) 0.80 root  ne(Column#27, 0)",
          "  │ └─HashAgg 1.00 root  funcs:min(Column#36)->Column#25, funcs:sum(Column#37)->Column#26, funcs:count(Column#38)->Column#27",
          "  │   └─TableReader 1.00 root  data:ExchangeSender",
          "  │     └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  │       └─HashAgg 1.00 mpp[tiflash]  funcs:min(Column#42)->Column#36, funcs:sum(Column#43)->Column#37, funcs:count(1)->Column#38",
          "  │         └─Projection 10000.00 mpp[tiflash]  test.ts.col_varchar_64, cast(isnull(test.ts.col_varchar_64), decimal(20,0) BINARY)->Column#43",
          "  │           └─TableFullScan 10000.00 mpp[tiflash] table:SUBQUERY4_t1 keep order:false, stats:pseudo",
          "  └─TableReader(Probe) 12487.50 root  data:ExchangeSender",
          "    └─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.ts.col_varchar_64, test.ts.col_varchar_key)]",
          "        ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.ts.col_varchar_64))",
          "        │     └─TableFullScan 10000.00 mpp[tiflash] table:table2 keep order:false, stats:pseudo",
          "        └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.ts.col_varchar_key))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:SUBQUERY3_t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestPushDownGroupConcatToTiFlash",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id) from ts",
        "Plan": [
          "HashAgg 1.00 root  funcs:group_concat(Column#7 separator \",\")->Column#5",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#9, Column#10, Column#11 separator \",\")->Column#7",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#11",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#6, Column#7, Column#8 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:test.ts.col_0, test.ts.col_1, test.ts.id, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id order by col_0) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#6, Column#7, Column#8 order by Column#9 separator \",\")->Column#5",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8, test.ts.col_0",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id order by col_0) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#6, Column#7, Column#8 order by Column#9 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8, test.ts.col_0",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:test.ts.col_0, test.ts.col_1, test.ts.id, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id order by col_0),count(*),min(col_1) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#8, Column#9, Column#10 order by Column#11 separator \",\")->Column#5, funcs:count(1)->Column#6, funcs:min(Column#12)->Column#7",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#10, test.ts.col_0, test.ts.col_1",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id order by col_0),count(*),max(col_0) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#12, Column#13, Column#14 order by Column#15 separator \",\")->Column#5, funcs:sum(Column#16)->Column#6, funcs:max(Column#17)->Column#7",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#14, test.ts.col_0, Column#10, Column#11",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:test.ts.col_0, test.ts.col_1, test.ts.id, funcs:count(1)->Column#10, funcs:max(test.ts.col_0)->Column#11",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#13, funcs:group_concat(Column#10, Column#11, Column#12 separator \",\")->Column#5",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#12, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#9, funcs:group_concat(distinct Column#6, Column#7, Column#8 separator \",\")->Column#5",
          "      └─Projection 8000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8, test.ts.col_2",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.ts.col_0, test.ts.col_1, test.ts.col_2, test.ts.id, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id order by col_0) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#10, funcs:group_concat(Column#6, Column#7, Column#8 order by Column#9 separator \",\")->Column#5",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8, test.ts.col_0, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id order by col_0) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#10, funcs:group_concat(distinct Column#6, Column#7, Column#8 order by Column#9 separator \",\")->Column#5",
          "      └─Projection 8000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#8, test.ts.col_0, test.ts.col_2",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.ts.col_0, test.ts.col_1, test.ts.col_2, test.ts.id, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_1, id order by col_0) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#9, funcs:group_concat(Column#6, Column#7 order by Column#8 separator \",\")->Column#5",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_1, cast(test.ts.id, var_string(20))->Column#7, test.ts.col_0, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_1, id order by col_0) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#9, funcs:group_concat(distinct Column#6, Column#7 order by Column#8 separator \",\")->Column#5",
          "      └─Projection 8000.00 mpp[tiflash]  test.ts.col_1, cast(test.ts.id, var_string(20))->Column#7, test.ts.col_0, test.ts.col_2",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.ts.col_1, test.ts.col_2, test.ts.id, funcs:firstrow(test.ts.col_0)->test.ts.col_0",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id order by col_0),count(*),min(col_0),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#11, 0), 1, Column#11), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#20, funcs:group_concat(Column#13, Column#14, Column#15 order by Column#16 separator \",\")->Column#5, funcs:count(1)->Column#6, funcs:min(Column#17)->Column#7, funcs:count(Column#18)->Column#11, funcs:sum(Column#19)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#15, test.ts.col_0, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#19, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id order by col_0),count(*),max(col_1),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#32, funcs:group_concat(distinct Column#25, Column#26, Column#27 order by Column#28 separator \",\")->Column#5, funcs:count(1)->Column#6, funcs:max(Column#29)->Column#7, funcs:count(Column#30)->Column#19, funcs:sum(Column#31)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#27, test.ts.col_0, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#31, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id order by col_0),count(distinct id),min(col_0),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#10, 0), 1, Column#10), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#11, Column#12, Column#13 order by Column#14 separator \",\")->Column#5, funcs:count(Column#15)->Column#6, funcs:min(Column#16)->Column#7, funcs:count(Column#17)->Column#10, funcs:sum(Column#18)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#13, test.ts.col_0, test.ts.id, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#18",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id order by col_0),count(distinct id),max(col_1),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#14, 0), 1, Column#14), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#26, Column#27, Column#28 order by Column#29 separator \",\")->Column#5, funcs:sum(Column#30)->Column#6, funcs:max(Column#31)->Column#7, funcs:sum(Column#32)->Column#14, funcs:sum(Column#33)->Column#8",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#28, test.ts.col_0, Column#15, Column#16, Column#17, Column#18",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:Column#23, Column#24, Column#25, funcs:count(Column#19)->Column#15, funcs:max(Column#20)->Column#16, funcs:count(Column#21)->Column#17, funcs:sum(Column#22)->Column#18",
          "              └─Projection 10000.00 mpp[tiflash]  test.ts.id, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#22, test.ts.col_0, test.ts.col_1, test.ts.id",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id),count(distinct id),min(col_0),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#26, 0), 1, Column#26), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#40, funcs:group_concat(Column#33, Column#34, Column#35 separator \",\")->Column#5, funcs:count(Column#36)->Column#6, funcs:min(Column#37)->Column#7, funcs:count(Column#38)->Column#26, funcs:sum(Column#39)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#35, test.ts.id, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#39, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id),count(distinct id),max(col_1),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#32, funcs:group_concat(distinct Column#25, Column#26, Column#27 separator \",\")->Column#5, funcs:count(Column#28)->Column#6, funcs:max(Column#29)->Column#7, funcs:count(Column#30)->Column#19, funcs:sum(Column#31)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#27, test.ts.id, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#31, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id),count(distinct id),min(col_0),avg(id) from ts",
        "Plan": [
          "HashAgg 1.00 root  funcs:group_concat(Column#14 separator \",\")->Column#5, funcs:count(Column#15)->Column#6, funcs:min(Column#16)->Column#7, funcs:avg(Column#17, Column#18)->Column#8",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#24, Column#25, Column#26 separator \",\")->Column#14, funcs:count(Column#27)->Column#15, funcs:min(Column#28)->Column#16, funcs:count(Column#29)->Column#17, funcs:sum(Column#30)->Column#18",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#26, test.ts.id, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#30",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id),count(distinct id),max(col_1),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#14, 0), 1, Column#14), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#26, Column#27, Column#28 separator \",\")->Column#5, funcs:sum(Column#29)->Column#6, funcs:max(Column#30)->Column#7, funcs:sum(Column#31)->Column#14, funcs:sum(Column#32)->Column#8",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#28, Column#15, Column#16, Column#17, Column#18",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:Column#23, Column#24, Column#25, funcs:count(Column#19)->Column#15, funcs:max(Column#20)->Column#16, funcs:count(Column#21)->Column#17, funcs:sum(Column#22)->Column#18",
          "              └─Projection 10000.00 mpp[tiflash]  test.ts.id, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#22, test.ts.col_0, test.ts.col_1, test.ts.id",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_1, id),count(distinct id),group_concat(col_0 order by 1),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#17, 0), 1, Column#17), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#29, funcs:group_concat(Column#21, Column#22, Column#23 separator \",\")->Column#5, funcs:count(Column#24)->Column#6, funcs:group_concat(Column#25 order by Column#26 separator \",\")->Column#7, funcs:count(Column#27)->Column#17, funcs:sum(Column#28)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#23, test.ts.id, test.ts.col_0, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#28, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0),count(distinct id),group_concat(col_1, id order by 1,2),avg(id) from ts group by col_2",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, div(Column#8, cast(case(eq(Column#13, 0), 1, Column#13), decimal(20,0) BINARY))->Column#8",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#24, funcs:group_concat(distinct Column#16 separator \",\")->Column#5, funcs:count(Column#17)->Column#6, funcs:group_concat(Column#18, Column#19 order by Column#20, Column#21 separator \",\")->Column#7, funcs:count(Column#22)->Column#13, funcs:sum(Column#23)->Column#8",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.id, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#19, test.ts.col_1, test.ts.id, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#23, test.ts.col_2",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_2, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, id),count(distinct id),group_concat(col_1, id order by 1,2),min(col_0),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, Column#8, div(Column#9, cast(case(eq(Column#15, 0), 1, Column#15), decimal(20,0) BINARY))->Column#9",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(Column#18, Column#19 separator \",\")->Column#5, funcs:count(Column#20)->Column#6, funcs:group_concat(Column#21, Column#22 order by Column#23, Column#24 separator \",\")->Column#7, funcs:min(Column#25)->Column#8, funcs:count(Column#26)->Column#15, funcs:sum(Column#27)->Column#9",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, cast(test.ts.id, var_string(20))->Column#19, test.ts.id, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#22, test.ts.col_1, test.ts.id, test.ts.col_0, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#27",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id),count(distinct id),group_concat(col_1, id order by 1,2),max(col_1),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, Column#8, div(Column#9, cast(case(eq(Column#12, 0), 1, Column#12), decimal(20,0) BINARY))->Column#9",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#14, Column#15, Column#16 separator \",\")->Column#5, funcs:count(Column#17)->Column#6, funcs:group_concat(Column#18, Column#19 order by Column#20, Column#21 separator \",\")->Column#7, funcs:max(Column#22)->Column#8, funcs:count(Column#23)->Column#12, funcs:sum(Column#24)->Column#9",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#16, test.ts.id, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#19, test.ts.col_1, test.ts.id, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#24",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id),count(distinct col_2),group_concat(col_1, id),max(col_1),avg(id) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5, Column#6, Column#7, Column#8, div(Column#9, cast(case(eq(Column#15, 0), 1, Column#15), decimal(20,0) BINARY))->Column#9",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#29, Column#30, Column#31 separator \",\")->Column#5, funcs:count(distinct Column#32)->Column#6, funcs:group_concat(Column#33 separator \",\")->Column#7, funcs:max(Column#34)->Column#8, funcs:sum(Column#35)->Column#15, funcs:sum(Column#36)->Column#9",
          "      └─Projection 1.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#31, test.ts.col_2, Column#16, Column#17, Column#18, Column#19",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:Column#25, Column#26, Column#27, Column#28, funcs:group_concat(Column#20, Column#21 separator \",\")->Column#16, funcs:max(Column#22)->Column#17, funcs:count(Column#23)->Column#18, funcs:sum(Column#24)->Column#19",
          "              └─Projection 10000.00 mpp[tiflash]  test.ts.col_1, cast(test.ts.id, var_string(20))->Column#21, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#24, test.ts.col_0, test.ts.col_1, test.ts.id, test.ts.col_2",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0, col_1, id),count(distinct col_2),group_concat(col_1, id),max(col_1),avg(id) from ts group by col_0",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5, Column#6, Column#7, Column#8, div(Column#9, cast(case(eq(Column#20, 0), 1, Column#20), decimal(20,0) BINARY))->Column#9",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#35, funcs:group_concat(distinct Column#26, Column#27, Column#28 separator \",\")->Column#5, funcs:count(distinct Column#29)->Column#6, funcs:group_concat(Column#30, Column#31 separator \",\")->Column#7, funcs:max(Column#32)->Column#8, funcs:count(Column#33)->Column#20, funcs:sum(Column#34)->Column#9",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#28, test.ts.col_2, test.ts.col_1, cast(test.ts.id, var_string(20))->Column#31, test.ts.col_1, test.ts.id, cast(test.ts.id, decimal(10,0) BINARY)->Column#34, test.ts.col_0",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_0, collate: utf8mb4_bin]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,'GG') from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#10, Column#11 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#8, var_string(20))->Column#10, Column#9",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:\"GG\", 0, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,'01') from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#10, Column#11 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#8, var_string(20))->Column#10, Column#9",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:\"01\", 0, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,1) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#10, Column#11 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#8, var_string(20))->Column#10, cast(Column#9, var_string(20))->Column#11",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:0, 1, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,0) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#8, Column#9 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#7, var_string(20))->Column#8, cast(Column#7, var_string(20))->Column#9",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:0, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,10) from ts group by '010'",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  group by:Column#17, funcs:group_concat(distinct Column#15, Column#16 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#13, var_string(20))->Column#15, cast(Column#14, var_string(20))->Column#16, Column#12",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#12, collate: binary]",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:0, 1, 10, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,0) from ts group by '011'",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  group by:Column#14, funcs:group_concat(distinct Column#12, Column#13 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#11, var_string(20))->Column#12, cast(Column#11, var_string(20))->Column#13, Column#10",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#10, collate: binary]",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:0, 1, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 0,'GG') from ts group by 'GG'",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  group by:Column#17, funcs:group_concat(distinct Column#15, Column#16 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  cast(Column#13, var_string(20))->Column#15, Column#14, Column#12",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: Column#12, collate: binary]",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:\"GG\", 0, 1, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'",
          "[types:1292]Truncated incorrect DOUBLE value: 'GG'"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 'GG','GG') from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#7, Column#7 separator \",\")->Column#5",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  group by:\"GG\", ",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 'Gg','GG') from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#8, Column#9 separator \",\")->Column#5",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  group by:\"GG\", \"Gg\", ",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct 'GG-10','GG') from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#8, Column#9 separator \",\")->Column#5",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  group by:\"GG\", \"GG-10\", ",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct '1200-01-01 00:00:00.023',1200) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct Column#10, Column#11 separator \",\")->Column#5",
          "      └─Projection 1.00 mpp[tiflash]  Column#8, cast(Column#9, var_string(20))->Column#11",
          "        └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "          └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─HashAgg 1.00 mpp[tiflash]  group by:\"1200-01-01 00:00:00.023\", 1200, ",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable",
          "[types:1292]Truncated incorrect DOUBLE value: '1200-01-01 00:00:00.023'",
          "[types:1292]Truncated incorrect DOUBLE value: '1200-01-01 00:00:00.023'"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_0) from ts group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.ts.id, funcs:group_concat(test.ts.col_0, test.ts.col_0 separator \",\")->Column#5",
          "      └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.id, collate: binary]",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(col_0, col_0,id) from ts group by id",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#13, funcs:group_concat(Column#10, Column#11, Column#12 separator \",\")->Column#5",
          "      └─Projection 10000.00 mpp[tiflash]  test.ts.col_0, test.ts.col_0, cast(test.ts.id, var_string(20))->Column#12, test.ts.id",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.id, collate: binary]",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0 order by id<10) from ts",
        "Plan": [
          "TableReader 1.00 root  data:ExchangeSender",
          "└─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 1.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:group_concat(distinct test.ts.col_0 order by Column#7 separator \",\")->Column#5",
          "      └─ExchangeReceiver 1.00 mpp[tiflash]  ",
          "        └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "          └─HashAgg 1.00 mpp[tiflash]  group by:Column#9, funcs:firstrow(Column#8)->Column#7",
          "            └─Projection 10000.00 mpp[tiflash]  lt(test.ts.id, 10)->Column#8, test.ts.col_0",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0 order by id<10) from ts group by col_1",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:test.ts.col_1, funcs:group_concat(distinct test.ts.col_0 order by Column#8 separator \",\")->Column#5",
          "      └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "        └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_1, collate: utf8mb4_bin]",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:Column#10, Column#11, funcs:firstrow(Column#9)->Column#8",
          "            └─Projection 10000.00 mpp[tiflash]  lt(test.ts.id, 10)->Column#9, test.ts.col_1, test.ts.col_0",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0>10 order by id<10) from ts group by col_1",
        "Plan": [
          "TableReader 8000.00 root  data:ExchangeSender",
          "└─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    └─HashAgg 8000.00 mpp[tiflash]  group by:Column#17, funcs:group_concat(distinct Column#15 order by Column#16 separator \",\")->Column#5",
          "      └─Projection 8000.00 mpp[tiflash]  cast(Column#10, var_string(20))->Column#15, Column#11, test.ts.col_1",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.ts.col_1, collate: utf8mb4_bin]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:Column#13, Column#14, funcs:firstrow(Column#12)->Column#11",
          "              └─Projection 10000.00 mpp[tiflash]  lt(test.ts.id, 10)->Column#12, test.ts.col_1, gt(cast(test.ts.col_0, double BINARY), 10)->Column#14",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable"
        ]
      },
      {
        "SQL": "desc format = 'brief' select /*+ hash_agg(),agg_to_cop() */ group_concat(distinct col_0 order by col_0<=>null) from ts",
        "Plan": [
          "HashAgg 1.00 root  funcs:group_concat(distinct Column#6 order by Column#7 separator \",\")->Column#5",
          "└─Projection 10000.00 root  test.ts.col_0, nulleq(test.ts.col_0, <nil>)->Column#7",
          "  └─TableReader 10000.00 root  data:TableFullScan",
          "    └─TableFullScan 10000.00 cop[tiflash] table:ts keep order:false, stats:pseudo"
        ],
        "Warning": [
          "[planner:1815]Optimizer Hint AGG_TO_COP is inapplicable",
          "Scalar function 'nulleq'(signature: NullEQString, return type: bigint(1)) is not supported to push down to tiflash now.",
          "Aggregation can not be pushed to tiflash because arguments of AggFunc `group_concat` contains unsupported exprs in order-by clause",
          "Scalar function 'nulleq'(signature: NullEQString, return type: bigint(1)) is not supported to push down to tiflash now.",
          "Aggregation can not be pushed to tiflash because arguments of AggFunc `group_concat` contains unsupported exprs in order-by clause"
        ]
      }
    ]
  },
  {
    "Name": "TestRejectSortForMPP",
    "Cases": [
      {
        "SQL": "desc format = 'brief' select count(*) from (select * from t order by id)a group by name,id order by id",
        "Plan": [
          "Projection 8000.00 root  Column#5",
          "└─Sort 8000.00 root  test.t.id",
          "  └─TableReader 8000.00 root  data:ExchangeSender",
          "    └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─Projection 8000.00 mpp[tiflash]  Column#5, test.t.id",
          "        └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.id)->test.t.id",
          "          └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "            └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]",
          "              └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, funcs:count(1)->Column#7",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*) from (select * from t order by id)a group by name order by 1",
        "Plan": [
          "Sort 8000.00 root  Column#5",
          "└─TableReader 8000.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Projection 8000.00 mpp[tiflash]  Column#5",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.name, funcs:sum(Column#8)->Column#5",
          "        └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin]",
          "            └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.name, funcs:count(1)->Column#8",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select count(*) from (select id,name from t group by id,name order by id,name)a group by name order by 1",
        "Plan": [
          "Sort 8000.00 root  Column#5",
          "└─TableReader 8000.00 root  data:ExchangeSender",
          "  └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Projection 8000.00 mpp[tiflash]  Column#5",
          "      └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.name, funcs:count(1)->Column#5",
          "        └─Projection 8000.00 mpp[tiflash]  test.t.id, test.t.name",
          "          └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.name)->test.t.name",
          "            └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "              └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin]",
          "                └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, ",
          "                  └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select id from t group by id order by id)a join t on a.id=t.id order by 1",
        "Plan": [
          "Sort 9990.00 root  test.t.id",
          "└─TableReader 9990.00 root  data:ExchangeSender",
          "  └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Projection 9990.00 mpp[tiflash]  test.t.id, test.t.id, test.t.value, test.t.name",
          "      └─HashJoin 9990.00 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "        ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Projection 7992.00 mpp[tiflash]  test.t.id",
          "        │     └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id",
          "        │       └─ExchangeReceiver 7992.00 mpp[tiflash]  ",
          "        │         └─ExchangeSender 7992.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]",
          "        │           └─HashAgg 7992.00 mpp[tiflash]  group by:test.t.id, ",
          "        │             └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        │               └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select * from t order by id)a join t on a.id=t.id order by 1",
        "Plan": [
          "Sort 12487.50 root  test.t.id",
          "└─TableReader 12487.50 root  data:ExchangeSender",
          "  └─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─Projection 12487.50 mpp[tiflash]  test.t.id, test.t.value, test.t.name, test.t.id, test.t.value, test.t.name",
          "      └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t.id, test.t.id)]",
          "        ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "        │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "        │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "        │     └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "        └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t.id))",
          "          └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from ((select id from t order by 1)  union all (select id+1 from t order by 1))c",
        "Plan": [
          "TableReader 20000.00 root  data:ExchangeSender",
          "└─ExchangeSender 20000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Union 20000.00 mpp[tiflash]  ",
          "    ├─Projection 10000.00 mpp[tiflash]  cast(test.t.id, bigint(20) BINARY)->Column#10",
          "    │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection 10000.00 mpp[tiflash]  plus(test.t.id, 1)->Column#10",
          "      └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from ((select count(*) from (select id,name from t order by id)a group by name,id order by id)  union all (select id+1 from t order by 1))c",
        "Plan": [
          "TableReader 18000.00 root  data:ExchangeSender",
          "└─ExchangeSender 18000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Union 18000.00 mpp[tiflash]  ",
          "    ├─Projection 8000.00 mpp[tiflash]  cast(Column#12, bigint(21) BINARY)->Column#12",
          "    │ └─Projection 8000.00 mpp[tiflash]  Column#5",
          "    │   └─Projection 8000.00 mpp[tiflash]  Column#5, test.t.id",
          "    │     └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, funcs:sum(Column#19)->Column#5, funcs:firstrow(test.t.id)->test.t.id",
          "    │       └─ExchangeReceiver 8000.00 mpp[tiflash]  ",
          "    │         └─ExchangeSender 8000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]",
          "    │           └─HashAgg 8000.00 mpp[tiflash]  group by:test.t.id, test.t.name, funcs:count(1)->Column#19",
          "    │             └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo",
          "    └─Projection 10000.00 mpp[tiflash]  cast(Column#11, bigint(21) BINARY)->Column#12",
          "      └─Projection 10000.00 mpp[tiflash]  plus(test.t.id, 1)->Column#11",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "desc format = 'brief' select * from (select * from t order by id)a order by name",
        "Plan": [
          "Sort 10000.00 root  test.t.name",
          "└─TableReader 10000.00 root  data:ExchangeSender",
          "  └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIssue32632",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select sum(ps_supplycost) from partsupp, supplier where ps_suppkey = s_suppkey;",
        "Plan": [
          "HashAgg 1.00 root  funcs:sum(Column#15)->Column#14",
          "└─TableReader 1.00 root  data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:sum(test.partsupp.ps_supplycost)->Column#15",
          "      └─Projection 12500.00 mpp[tiflash]  test.partsupp.ps_supplycost",
          "        └─HashJoin 12500.00 mpp[tiflash]  inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]",
          "          ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash]  ",
          "          │ └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: Broadcast",
          "          │   └─TableFullScan 10000.00 mpp[tiflash] table:supplier keep order:false",
          "          └─TableFullScan(Probe) 800000.00 mpp[tiflash] table:partsupp keep order:false"
        ]
      }
    ]
  },
  {
    "Name": "TestTiFlashPartitionTableScan",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select * from rp_t where a = 1 or a = 20",
        "Plan": [
          "TableReader 20.00 root partition:p0,p3 data:ExchangeSender",
          "└─ExchangeSender 20.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Selection 20.00 mpp[tiflash]  or(eq(test.rp_t.a, 1), eq(test.rp_t.a, 20))",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:rp_t keep order:false, stats:pseudo, PartitionTableScan:true"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from hp_t where a = 1 or a = 20",
        "Plan": [
          "TableReader 20.00 root partition:p0,p1 data:ExchangeSender",
          "└─ExchangeSender 20.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Selection 20.00 mpp[tiflash]  or(eq(test.hp_t.a, 1), eq(test.hp_t.a, 20))",
          "    └─TableFullScan 10000.00 mpp[tiflash] table:hp_t keep order:false, stats:pseudo, PartitionTableScan:true"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from rp_t where a = 1 or a = 20",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#5)->Column#3",
          "└─TableReader 1.00 root partition:p0,p3 data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#5",
          "      └─Selection 20.00 mpp[tiflash]  or(eq(test.rp_t.a, 1), eq(test.rp_t.a, 20))",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:rp_t keep order:false, stats:pseudo, PartitionTableScan:true"
        ]
      },
      {
        "SQL": "explain format = 'brief' select count(*) from hp_t where a = 1 or a = 20",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#5)->Column#3",
          "└─TableReader 1.00 root partition:p0,p1 data:ExchangeSender",
          "  └─ExchangeSender 1.00 mpp[tiflash]  ExchangeType: PassThrough",
          "    └─HashAgg 1.00 mpp[tiflash]  funcs:count(1)->Column#5",
          "      └─Selection 20.00 mpp[tiflash]  or(eq(test.hp_t.a, 1), eq(test.hp_t.a, 20))",
          "        └─TableFullScan 10000.00 mpp[tiflash] table:hp_t keep order:false, stats:pseudo, PartitionTableScan:true"
        ]
      }
    ]
  },
  {
    "Name": "TestTiFlashFineGrainedShuffle",
    "Cases": [
      {
        "SQL": "explain format = 'brief' select row_number() over w1 from t1 window w1 as (partition by c1 order by c1);",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#5, stream_count: 8",
          "    └─Window 10000.00 mpp[tiflash]  row_number()->Column#5 over(partition by test.t1.c1 order by test.t1.c1 rows between current row and current row), stream_count: 8",
          "      └─Sort 10000.00 mpp[tiflash]  test.t1.c1, test.t1.c1, stream_count: 8",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1, rank() over w2 from t1 window w1 as (partition by c1 order by c1), w2 as (partition by c2);",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#7, Column#6, stream_count: 8",
          "    └─Window 10000.00 mpp[tiflash]  row_number()->Column#7 over(partition by test.t1.c1 order by test.t1.c1 rows between current row and current row), stream_count: 8",
          "      └─Sort 10000.00 mpp[tiflash]  test.t1.c1, test.t1.c1, stream_count: 8",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "            └─Window 10000.00 mpp[tiflash]  rank()->Column#6 over(partition by test.t1.c2), stream_count: 8",
          "              └─Sort 10000.00 mpp[tiflash]  test.t1.c2, stream_count: 8",
          "                └─ExchangeReceiver 10000.00 mpp[tiflash]  stream_count: 8",
          "                  └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary], stream_count: 8",
          "                    └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1, rank() over w2 from t1 window w1 as (partition by c1 order by c1), w2 as (partition by c2) order by 1, 2 limit 10;",
        "Plan": [
          "Projection 10.00 root  Column#7, Column#6",
          "└─TopN 10.00 root  Column#7, Column#6, offset:0, count:10",
          "  └─TableReader 10.00 root  data:ExchangeSender",
          "    └─ExchangeSender 10.00 mpp[tiflash]  ExchangeType: PassThrough",
          "      └─TopN 10.00 mpp[tiflash]  Column#7, Column#6, offset:0, count:10",
          "        └─Window 10000.00 mpp[tiflash]  row_number()->Column#7 over(partition by test.t1.c1 order by test.t1.c1 rows between current row and current row), stream_count: 8",
          "          └─Sort 10000.00 mpp[tiflash]  test.t1.c1, test.t1.c1, stream_count: 8",
          "            └─ExchangeReceiver 10000.00 mpp[tiflash]  stream_count: 8",
          "              └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "                └─Window 10000.00 mpp[tiflash]  rank()->Column#6 over(partition by test.t1.c2), stream_count: 8",
          "                  └─Sort 10000.00 mpp[tiflash]  test.t1.c2, stream_count: 8",
          "                    └─ExchangeReceiver 10000.00 mpp[tiflash]  stream_count: 8",
          "                      └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary], stream_count: 8",
          "                        └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1, count(c2) from t1 group by c1 having c1 > 10 window w1 as (partition by c2 order by c2);",
        "Plan": [
          "TableReader 2666.67 root  data:ExchangeSender",
          "└─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2666.67 mpp[tiflash]  Column#6, Column#4, stream_count: 8",
          "    └─Window 2666.67 mpp[tiflash]  row_number()->Column#6 over(partition by test.t1.c2 order by test.t1.c2 rows between current row and current row), stream_count: 8",
          "      └─Sort 2666.67 mpp[tiflash]  test.t1.c2, test.t1.c2, stream_count: 8",
          "        └─ExchangeReceiver 2666.67 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary], stream_count: 8",
          "            └─Projection 2666.67 mpp[tiflash]  Column#4, test.t1.c2",
          "              └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c1, funcs:sum(Column#9)->Column#4, funcs:firstrow(Column#10)->test.t1.c2",
          "                └─ExchangeReceiver 2666.67 mpp[tiflash]  ",
          "                  └─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]",
          "                    └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c1, funcs:count(test.t1.c2)->Column#9, funcs:firstrow(test.t1.c2)->Column#10",
          "                      └─Selection 3333.33 mpp[tiflash]  gt(test.t1.c1, 10)",
          "                        └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1, count(c1) from t1 group by c2 having c2 > 10 window w1 as (partition by c1 order by c2);",
        "Plan": [
          "TableReader 2666.67 root  data:ExchangeSender",
          "└─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2666.67 mpp[tiflash]  Column#6, Column#4, stream_count: 8",
          "    └─Window 2666.67 mpp[tiflash]  row_number()->Column#6 over(partition by test.t1.c1 order by test.t1.c2 rows between current row and current row), stream_count: 8",
          "      └─Sort 2666.67 mpp[tiflash]  test.t1.c1, test.t1.c2, stream_count: 8",
          "        └─ExchangeReceiver 2666.67 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "            └─Projection 2666.67 mpp[tiflash]  Column#4, test.t1.c1, test.t1.c2",
          "              └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c2, funcs:sum(Column#9)->Column#4, funcs:firstrow(Column#10)->test.t1.c1, funcs:firstrow(test.t1.c2)->test.t1.c2",
          "                └─ExchangeReceiver 2666.67 mpp[tiflash]  ",
          "                  └─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary]",
          "                    └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c2, funcs:count(test.t1.c1)->Column#9, funcs:firstrow(test.t1.c1)->Column#10",
          "                      └─Selection 3333.33 mpp[tiflash]  gt(test.t1.c2, 10)",
          "                        └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1 from t1 a join t1 b on a.c1 = b.c2 window w1 as (partition by a.c1);",
        "Plan": [
          "TableReader 12487.50 root  data:ExchangeSender",
          "└─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 12487.50 mpp[tiflash]  Column#8, stream_count: 8",
          "    └─Window 12487.50 mpp[tiflash]  row_number()->Column#8 over(partition by test.t1.c1 rows between current row and current row), stream_count: 8",
          "      └─Sort 12487.50 mpp[tiflash]  test.t1.c1, stream_count: 8",
          "        └─ExchangeReceiver 12487.50 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 12487.50 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "            └─HashJoin 12487.50 mpp[tiflash]  inner join, equal:[eq(test.t1.c1, test.t1.c2)]",
          "              ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash]  ",
          "              │ └─ExchangeSender 9990.00 mpp[tiflash]  ExchangeType: Broadcast",
          "              │   └─Selection 9990.00 mpp[tiflash]  not(isnull(test.t1.c1))",
          "              │     └─TableFullScan 10000.00 mpp[tiflash] table:a keep order:false, stats:pseudo",
          "              └─Selection(Probe) 9990.00 mpp[tiflash]  not(isnull(test.t1.c2))",
          "                └─TableFullScan 10000.00 mpp[tiflash] table:b keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1 from t1 where c1 < 100 window w1 as (partition by c1 order by c1);",
        "Plan": [
          "TableReader 3323.33 root  data:ExchangeSender",
          "└─ExchangeSender 3323.33 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 3323.33 mpp[tiflash]  Column#5, stream_count: 8",
          "    └─Window 3323.33 mpp[tiflash]  row_number()->Column#5 over(partition by test.t1.c1 order by test.t1.c1 rows between current row and current row), stream_count: 8",
          "      └─Sort 3323.33 mpp[tiflash]  test.t1.c1, test.t1.c1, stream_count: 8",
          "        └─ExchangeReceiver 3323.33 mpp[tiflash]  stream_count: 8",
          "          └─ExchangeSender 3323.33 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8",
          "            └─Selection 3323.33 mpp[tiflash]  lt(test.t1.c1, 100)",
          "              └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select * from t1;",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1 from t1 window w1 as (order by c1);",
        "Plan": [
          "TableReader 10000.00 root  data:ExchangeSender",
          "└─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 10000.00 mpp[tiflash]  Column#5",
          "    └─Window 10000.00 mpp[tiflash]  row_number()->Column#5 over(order by test.t1.c1 rows between current row and current row)",
          "      └─Sort 10000.00 mpp[tiflash]  test.t1.c1",
          "        └─ExchangeReceiver 10000.00 mpp[tiflash]  ",
          "          └─ExchangeSender 10000.00 mpp[tiflash]  ExchangeType: PassThrough",
          "            └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      },
      {
        "SQL": "explain format = 'brief' select row_number() over w1, count(c2) from t1 group by c1 having c1 > 10 window w1 as (partition by c1 order by c2);",
        "Plan": [
          "TableReader 2666.67 root  data:ExchangeSender",
          "└─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: PassThrough",
          "  └─Projection 2666.67 mpp[tiflash]  Column#6, Column#4",
          "    └─Window 2666.67 mpp[tiflash]  row_number()->Column#6 over(partition by test.t1.c1 order by test.t1.c2 rows between current row and current row)",
          "      └─Sort 2666.67 mpp[tiflash]  test.t1.c1, test.t1.c2",
          "        └─Projection 2666.67 mpp[tiflash]  Column#4, test.t1.c1, test.t1.c2",
          "          └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c1, funcs:sum(Column#9)->Column#4, funcs:firstrow(test.t1.c1)->test.t1.c1, funcs:firstrow(Column#11)->test.t1.c2",
          "            └─ExchangeReceiver 2666.67 mpp[tiflash]  ",
          "              └─ExchangeSender 2666.67 mpp[tiflash]  ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]",
          "                └─HashAgg 2666.67 mpp[tiflash]  group by:test.t1.c1, funcs:count(test.t1.c2)->Column#9, funcs:firstrow(test.t1.c2)->Column#11",
          "                  └─Selection 3333.33 mpp[tiflash]  gt(test.t1.c1, 10)",
          "                    └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo"
        ]
      }
    ]
  },
  {
    "Name": "TestIndexJoinRangeFallback",
    "Cases": [
      {
        "SQL": "set @@tidb_opt_range_max_size = 0",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.b = t2.e and t1.d = t2.g where t1.a in (1, 3) and t1.c in ('aaa', 'bbb')",
        "Plan": [
          "IndexJoin 0.50 root  inner join, inner:IndexLookUp, outer key:test.t2.e, test.t2.g, inner key:test.t1.b, test.t1.d, equal cond:eq(test.t2.e, test.t1.b), eq(test.t2.g, test.t1.d)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.g))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 0.50 root  ",
          "  ├─Selection(Build) 249.50 cop[tikv]  not(isnull(test.t1.b)), not(isnull(test.t1.d))",
          "  │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) eq(test.t1.d, test.t2.g) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 0.50 cop[tikv]  in(test.t1.c, \"aaa\", \"bbb\")",
          "    └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 2900",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.b = t2.e and t1.d = t2.g where t1.a in (1, 3) and t1.c in ('aaa', 'bbb')",
        "Plan": [
          "IndexJoin 0.50 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.b, equal cond:eq(test.t2.e, test.t1.b), eq(test.t2.g, test.t1.d)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.g))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 0.50 root  ",
          "  ├─Selection(Build) 249.50 cop[tikv]  not(isnull(test.t1.b)), not(isnull(test.t1.d))",
          "  │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 0.50 cop[tikv]  in(test.t1.c, \"aaa\", \"bbb\")",
          "    └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Memory capacity of 2900 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen"
        ]
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 2300",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.b = t2.e and t1.d = t2.g where t1.a in (1, 3) and t1.c in ('aaa', 'bbb')",
        "Plan": [
          "IndexJoin 0.50 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.b, equal cond:eq(test.t2.e, test.t1.b), eq(test.t2.g, test.t1.d)",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.g))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 0.50 root  ",
          "  ├─Selection(Build) 249.50 cop[tikv]  not(isnull(test.t1.b)), not(isnull(test.t1.d))",
          "  │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3)], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 0.50 cop[tikv]  in(test.t1.c, \"aaa\", \"bbb\")",
          "    └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Memory capacity of 2300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen"
        ]
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 700",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.b = t2.e and t1.d = t2.g where t1.a in (1, 3) and t1.c in ('aaa', 'bbb')",
        "Plan": [
          "HashJoin 0.05 root  inner join, equal:[eq(test.t1.b, test.t2.e) eq(test.t1.d, test.t2.g)]",
          "├─IndexLookUp(Build) 0.04 root  ",
          "│ ├─Selection(Build) 19.96 cop[tikv]  not(isnull(test.t1.b)), not(isnull(test.t1.d))",
          "│ │ └─IndexRangeScan 20.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range:[1,1], [3,3], keep order:false, stats:pseudo",
          "│ └─Selection(Probe) 0.04 cop[tikv]  in(test.t1.c, \"aaa\", \"bbb\")",
          "│   └─TableRowIDScan 19.96 cop[tikv] table:t1 keep order:false, stats:pseudo",
          "└─TableReader(Probe) 9980.01 root  data:Selection",
          "  └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.g))",
          "    └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Memory capacity of 700 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen",
          "[planner:1815]Optimizer Hint /*+ INL_JOIN(t1) */ or /*+ TIDB_INLJ(t1) */ is inapplicable"
        ]
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 0",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.e where t1.b > 1 and t1.b < 10",
        "Plan": [
          "IndexJoin 312.19 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.a, equal cond:eq(test.t2.e, test.t1.a)",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.e))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 312.19 root  ",
          "  ├─Selection(Build) 312.19 cop[tikv]  not(isnull(test.t1.a))",
          "  │ └─IndexRangeScan 312.50 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, 1) lt(test.t1.b, 10)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 312.19 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 300",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.e where t1.b > 1 and t1.b < 10",
        "Plan": [
          "IndexJoin 312.19 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.a, equal cond:eq(test.t2.e, test.t1.a)",
          "├─TableReader(Build) 9990.00 root  data:Selection",
          "│ └─Selection 9990.00 cop[tikv]  not(isnull(test.t2.e))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 312.19 root  ",
          "  ├─Selection(Build) 312.19 cop[tikv]  gt(test.t1.b, 1), lt(test.t1.b, 10), not(isnull(test.t1.a))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 312.19 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Memory capacity of 300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen"
        ]
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 0",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.e where t1.b > t2.f and t1.b < t2.f + 10",
        "Plan": [
          "IndexJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.a, equal cond:eq(test.t2.e, test.t1.a), other cond:gt(test.t1.b, test.t2.f), lt(test.t1.b, plus(test.t2.f, 10))",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.f))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12475.01 cop[tikv]  not(isnull(test.t1.a)), not(isnull(test.t1.b))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, test.t2.f) lt(test.t1.b, plus(test.t2.f, 10))], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": null
      },
      {
        "SQL": "set @@tidb_opt_range_max_size = 300",
        "Plan": null,
        "Warn": null
      },
      {
        "SQL": "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.e where t1.b > t2.f and t1.b < t2.f + 10",
        "Plan": [
          "IndexJoin 12475.01 root  inner join, inner:IndexLookUp, outer key:test.t2.e, inner key:test.t1.a, equal cond:eq(test.t2.e, test.t1.a), other cond:gt(test.t1.b, test.t2.f), lt(test.t1.b, plus(test.t2.f, 10))",
          "├─TableReader(Build) 9980.01 root  data:Selection",
          "│ └─Selection 9980.01 cop[tikv]  not(isnull(test.t2.e)), not(isnull(test.t2.f))",
          "│   └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
          "└─IndexLookUp(Probe) 12475.01 root  ",
          "  ├─Selection(Build) 12475.01 cop[tikv]  not(isnull(test.t1.a)), not(isnull(test.t1.b))",
          "  │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Warn": [
          "Memory capacity of 300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen"
        ]
      }
    ]
  },
  {
    "Name": "TestNullConditionForPrefixIndex",
    "Cases": [
      {
        "SQL": "select count(1) from t1 where c1 = '0xfff' and c2 is not null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#7)->Column#5",
          "└─IndexReader 1.00 root  index:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:count(1)->Column#7",
          "    └─IndexRangeScan 99.90 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" -inf,\"0xfff\" +inf], keep order:false, stats:pseudo"
        ],
        "Result": [
          "3"
        ]
      },
      {
        "SQL": "select count(1) from t1 where c1 = '0xfff' and c2 is null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#5",
          "└─IndexReader 0.10 root  index:IndexRangeScan",
          "  └─IndexRangeScan 0.10 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" NULL,\"0xfff\" NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "1"
        ]
      },
      {
        "SQL": "select count(1) from t1 where c1 >= '0xfff' and c2 is not null",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#6)->Column#5",
          "└─IndexReader 1.00 root  index:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(1)->Column#6",
          "    └─Selection 3330.00 cop[tikv]  not(isnull(test.t1.c2))",
          "      └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo"
        ],
        "Result": [
          "3"
        ]
      },
      {
        "SQL": "select count(1) from t1 where c1 >= '0xfff' and c2 is null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#7)->Column#5",
          "└─IndexReader 1.00 root  index:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:count(1)->Column#7",
          "    └─Selection 3.33 cop[tikv]  isnull(test.t1.c2)",
          "      └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo"
        ],
        "Result": [
          "1"
        ]
      },
      {
        "SQL": "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is not null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#5",
          "└─IndexLookUp 8.00 root  ",
          "  ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:idx1(c1) range:[\"0xfff\",\"0xfff\"], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 8.00 cop[tikv]  not(isnull(plus(cast(test.t1.c2, double BINARY), 1)))",
          "    └─TableRowIDScan 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "3"
        ]
      },
      {
        "SQL": "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(1)->Column#5",
          "└─IndexLookUp 8.00 root  ",
          "  ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:idx1(c1) range:[\"0xfff\",\"0xfff\"], keep order:false, stats:pseudo",
          "  └─Selection(Probe) 8.00 cop[tikv]  isnull(plus(cast(test.t1.c2, double BINARY), 1))",
          "    └─TableRowIDScan 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "1"
        ]
      },
      {
        "SQL": "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is not null",
        "Plan": [
          "Projection 99.90 root  test.t1.c2",
          "└─IndexLookUp 99.90 root  ",
          "  ├─IndexRangeScan(Build) 99.90 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" -inf,\"0xfff\" +inf], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 99.90 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "",
          "111111",
          "22    "
        ]
      },
      {
        "SQL": "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is null",
        "Plan": [
          "Projection 0.10 root  test.t1.c2",
          "└─IndexLookUp 0.10 root  ",
          "  ├─IndexRangeScan(Build) 0.10 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" NULL,\"0xfff\" NULL], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 0.10 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil>"
        ]
      },
      {
        "SQL": "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is not null",
        "Plan": [
          "Projection 3330.00 root  test.t1.c2",
          "└─IndexLookUp 3330.00 root  ",
          "  ├─Selection(Build) 3330.00 cop[tikv]  not(isnull(test.t1.c2))",
          "  │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 3330.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "",
          "111111",
          "22    "
        ]
      },
      {
        "SQL": "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is null",
        "Plan": [
          "Projection 3.33 root  test.t1.c2",
          "└─IndexLookUp 3.33 root  ",
          "  ├─Selection(Build) 3.33 cop[tikv]  isnull(test.t1.c2)",
          "  │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo",
          "  └─TableRowIDScan(Probe) 3.33 cop[tikv] table:t1 keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil>"
        ]
      },
      {
        "SQL": "select count(1) from t2 use index(idx) where b is not null",
        "Plan": [
          "HashAgg 1.00 root  funcs:count(Column#5)->Column#4",
          "└─IndexReader 1.00 root  index:HashAgg",
          "  └─HashAgg 1.00 cop[tikv]  funcs:count(1)->Column#5",
          "    └─IndexFullScan 9990.00 cop[tikv] table:t2, index:idx(b) keep order:false, stats:pseudo"
        ],
        "Result": [
          "3"
        ]
      },
      {
        "SQL": "select count(1) from t2 use index(idx) where b is null",
        "Plan": [
          "StreamAgg 1.00 root  funcs:count(Column#6)->Column#4",
          "└─IndexReader 1.00 root  index:StreamAgg",
          "  └─StreamAgg 1.00 cop[tikv]  funcs:count(1)->Column#6",
          "    └─IndexRangeScan 10.00 cop[tikv] table:t2, index:idx(b) range:[NULL,NULL], keep order:false, stats:pseudo"
        ],
        "Result": [
          "1"
        ]
      },
      {
        "SQL": "select b from t2 use index(idx) where b is not null",
        "Plan": [
          "IndexLookUp 9990.00 root  ",
          "├─IndexFullScan(Build) 9990.00 cop[tikv] table:t2, index:idx(b) keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 9990.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Result": [
          "",
          "aaaaaa",
          "bb    "
        ]
      },
      {
        "SQL": "select b from t2 use index(idx) where b is null",
        "Plan": [
          "IndexLookUp 10.00 root  ",
          "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t2, index:idx(b) range:[NULL,NULL], keep order:false, stats:pseudo",
          "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t2 keep order:false, stats:pseudo"
        ],
        "Result": [
          "<nil>"
        ]
      },
      {
        "SQL": "select b from t3 where a = 1 and b is not null",
        "Plan": [
          "Projection 10.00 root  test.t3.b",
          "└─TableReader 10.00 root  data:TableRangeScan",
          "  └─TableRangeScan 10.00 cop[tikv] table:t3 range:[1,1], keep order:false, stats:pseudo"
        ],
        "Result": [
          "",
          "aaaaaa",
          "bb    "
        ]
      },
      {
        "SQL": "select b from t3 where a = 1 and b is null",
        "Plan": [
          "TableDual 0.00 root  rows:0"
        ],
        "Result": null
      }
    ]
  }
]
