set tidb_cost_model_version=1;
///// SUBQUERY
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
drop table if exists t2;
create table t2(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t2 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
// IN
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 in (select c3 from t1) order by 1;
id	estRows	task	access object	operator info
Sort_8	4433.77	root		index_merge.t1.c1
└─Projection_10	4433.77	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Selection_11	4433.77	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), Column#9))
    └─HashJoin_12	5542.21	root		CARTESIAN left outer semi join, other cond:eq(index_merge.t1.c3, index_merge.t1.c3)
      ├─TableReader_18(Build)	10000.00	root		data:TableFullScan_17
      │ └─TableFullScan_17	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
      └─IndexMerge_16(Probe)	5542.21	root		type: union
        ├─IndexRangeScan_13(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
        ├─IndexRangeScan_14(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
        └─TableRowIDScan_15(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 in (select c3 from t1) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// NOT IN
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 not in (select c3 from t1) order by 1;
id	estRows	task	access object	operator info
Sort_8	4433.77	root		index_merge.t1.c1
└─Projection_10	4433.77	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Selection_11	4433.77	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), Column#9))
    └─HashJoin_12	5542.21	root		Null-aware anti left outer semi join, equal:[eq(index_merge.t1.c3, index_merge.t1.c3)]
      ├─TableReader_18(Build)	10000.00	root		data:TableFullScan_17
      │ └─TableFullScan_17	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
      └─IndexMerge_16(Probe)	5542.21	root		type: union
        ├─IndexRangeScan_13(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
        ├─IndexRangeScan_14(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
        └─TableRowIDScan_15(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 not in (select c3 from t1) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// MAX
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select max(c3) from t1) order by 1;
id	estRows	task	access object	operator info
Sort_33	3325.55	root		index_merge.t1.c1
└─IndexMerge_40	1843.09	root		type: union
  ├─IndexRangeScan_36(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_37(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_39(Probe)	1843.09	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, 5)))
    └─TableRowIDScan_38	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select max(c3) from t1) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// EXISTS
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and EXISTS(select 1 from t2 where t2.c1 = t1.c1) order by 1;
id	estRows	task	access object	operator info
Sort_9	4433.77	root		index_merge.t1.c1
└─Projection_11	4433.77	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Selection_12	4433.77	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), Column#10))
    └─HashJoin_22	5542.21	root		left outer semi join, equal:[eq(index_merge.t1.c1, index_merge.t2.c1)]
      ├─IndexReader_30(Build)	10000.00	root		index:IndexFullScan_29
      │ └─IndexFullScan_29	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
      └─IndexMerge_26(Probe)	5542.21	root		type: union
        ├─IndexRangeScan_23(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
        ├─IndexRangeScan_24(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
        └─TableRowIDScan_25(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and EXISTS(select 1 from t2 where t2.c1 = t1.c1) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// EXISTS
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and NOT EXISTS(select 1 from t2 where t2.c1 = t1.c1) order by 1;
id	estRows	task	access object	operator info
Sort_9	4433.77	root		index_merge.t1.c1
└─Projection_11	4433.77	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Selection_12	4433.77	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), Column#10))
    └─HashJoin_22	5542.21	root		anti left outer semi join, equal:[eq(index_merge.t1.c1, index_merge.t2.c1)]
      ├─IndexReader_30(Build)	10000.00	root		index:IndexFullScan_29
      │ └─IndexFullScan_29	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
      └─IndexMerge_26(Probe)	5542.21	root		type: union
        ├─IndexRangeScan_23(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
        ├─IndexRangeScan_24(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
        └─TableRowIDScan_25(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and NOT EXISTS(select 1 from t2 where t2.c1 = t1.c1) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// Non-Correlated
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select count(1) from t2) order by 1;
id	estRows	task	access object	operator info
Sort_38	3325.55	root		index_merge.t1.c1
└─IndexMerge_45	1843.09	root		type: union
  ├─IndexRangeScan_41(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_42(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_44(Probe)	1843.09	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, 5)))
    └─TableRowIDScan_43	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select count(1) from t2) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// ANY
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > ANY(select count(1) from t2) order by 1;
id	estRows	task	access object	operator info
Sort_11	5098.44	root		index_merge.t1.c1
└─HashJoin_15	5098.44	root		CARTESIAN inner join, other cond:or(lt(index_merge.t1.c1, 10), and(and(lt(index_merge.t1.c2, 10), or(gt(index_merge.t1.c3, Column#10), if(ne(Column#11, 0), NULL, 0))), and(ne(Column#12, 0), if(isnull(index_merge.t1.c3), NULL, 1))))
  ├─StreamAgg_23(Build)	1.00	root		funcs:min(Column#9)->Column#10, funcs:sum(0)->Column#11, funcs:count(1)->Column#12
  │ └─StreamAgg_43	1.00	root		funcs:count(Column#25)->Column#9
  │   └─IndexReader_44	1.00	root		index:StreamAgg_27
  │     └─StreamAgg_27	1.00	cop[tikv]		funcs:count(1)->Column#25
  │       └─IndexFullScan_41	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
  └─IndexMerge_21(Probe)	2825.66	root		type: union
    ├─IndexRangeScan_17(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_18(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─Selection_20(Probe)	2825.66	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), if(isnull(index_merge.t1.c3), NULL, 1)))
      └─TableRowIDScan_19	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > ANY(select count(1) from t2) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// SOME
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > SOME(select count(1) from t2) order by 1;
id	estRows	task	access object	operator info
Sort_11	5098.44	root		index_merge.t1.c1
└─HashJoin_15	5098.44	root		CARTESIAN inner join, other cond:or(lt(index_merge.t1.c1, 10), and(and(lt(index_merge.t1.c2, 10), or(gt(index_merge.t1.c3, Column#10), if(ne(Column#11, 0), NULL, 0))), and(ne(Column#12, 0), if(isnull(index_merge.t1.c3), NULL, 1))))
  ├─StreamAgg_23(Build)	1.00	root		funcs:min(Column#9)->Column#10, funcs:sum(0)->Column#11, funcs:count(1)->Column#12
  │ └─StreamAgg_43	1.00	root		funcs:count(Column#25)->Column#9
  │   └─IndexReader_44	1.00	root		index:StreamAgg_27
  │     └─StreamAgg_27	1.00	cop[tikv]		funcs:count(1)->Column#25
  │       └─IndexFullScan_41	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
  └─IndexMerge_21(Probe)	2825.66	root		type: union
    ├─IndexRangeScan_17(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_18(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─Selection_20(Probe)	2825.66	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), if(isnull(index_merge.t1.c3), NULL, 1)))
      └─TableRowIDScan_19	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > SOME(select count(1) from t2) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// ALL
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > ALL(select count(1) from t2) order by 1;
id	estRows	task	access object	operator info
Sort_11	5542.21	root		index_merge.t1.c1
└─HashJoin_15	5542.21	root		CARTESIAN inner join, other cond:or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), or(and(gt(index_merge.t1.c3, Column#10), if(ne(Column#11, 0), NULL, 1)), or(eq(Column#12, 0), if(isnull(index_merge.t1.c3), NULL, 0)))))
  ├─StreamAgg_22(Build)	1.00	root		funcs:max(Column#9)->Column#10, funcs:sum(0)->Column#11, funcs:count(1)->Column#12
  │ └─StreamAgg_42	1.00	root		funcs:count(Column#25)->Column#9
  │   └─IndexReader_43	1.00	root		index:StreamAgg_26
  │     └─StreamAgg_26	1.00	cop[tikv]		funcs:count(1)->Column#25
  │       └─IndexFullScan_40	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
  └─IndexMerge_20(Probe)	5542.21	root		type: union
    ├─IndexRangeScan_17(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_18(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_19(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 > ALL(select count(1) from t2) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
// SELECT FIELD
explain select /*+ use_index_merge(t1) */ c1, (select sum(c2) from t2) from t1 where c1 < 10 or c2 < 10 and c3 > ALL(select count(1) from t2) order by 1;
id	estRows	task	access object	operator info
Sort_39	5542.21	root		index_merge.t1.c1
└─Projection_41	5542.21	root		index_merge.t1.c1, 15->Column#25
  └─HashJoin_43	5542.21	root		CARTESIAN inner join, other cond:or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), or(and(gt(index_merge.t1.c3, Column#14), if(ne(Column#15, 0), NULL, 1)), or(eq(Column#16, 0), if(isnull(index_merge.t1.c3), NULL, 0)))))
    ├─StreamAgg_50(Build)	1.00	root		funcs:max(Column#13)->Column#14, funcs:sum(0)->Column#15, funcs:count(1)->Column#16
    │ └─StreamAgg_70	1.00	root		funcs:count(Column#38)->Column#13
    │   └─IndexReader_71	1.00	root		index:StreamAgg_54
    │     └─StreamAgg_54	1.00	cop[tikv]		funcs:count(1)->Column#38
    │       └─IndexFullScan_68	10000.00	cop[tikv]	table:t2, index:c1(c1)	keep order:false, stats:pseudo
    └─IndexMerge_48(Probe)	5542.21	root		type: union
      ├─IndexRangeScan_45(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
      ├─IndexRangeScan_46(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
      └─TableRowIDScan_47(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ c1, (select sum(c2) from t2) from t1 where c1 < 10 or c2 < 10 and c3 > ALL(select count(1) from t2) order by 1;
c1	(select sum(c2) from t2)
1	15
2	15
3	15
4	15
5	15
// MULTIPLE LEVEL
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 IN (select c1 from t2 where c2 in (select c3 from t2)) order by 1;
id	estRows	task	access object	operator info
Sort_14	4433.77	root		index_merge.t1.c1
└─Projection_16	4433.77	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Selection_17	4433.77	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), Column#13))
    └─HashJoin_18	5542.21	root		CARTESIAN left outer semi join, other cond:eq(index_merge.t1.c3, index_merge.t2.c1)
      ├─HashJoin_37(Build)	9990.00	root		inner join, equal:[eq(index_merge.t2.c2, index_merge.t2.c3)]
      │ ├─HashAgg_41(Build)	7992.00	root		group by:index_merge.t2.c3, funcs:firstrow(index_merge.t2.c3)->index_merge.t2.c3
      │ │ └─TableReader_48	9990.00	root		data:Selection_47
      │ │   └─Selection_47	9990.00	cop[tikv]		not(isnull(index_merge.t2.c3))
      │ │     └─TableFullScan_46	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
      │ └─TableReader_51(Probe)	9990.00	root		data:Selection_50
      │   └─Selection_50	9990.00	cop[tikv]		not(isnull(index_merge.t2.c2))
      │     └─TableFullScan_49	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
      └─IndexMerge_22(Probe)	5542.21	root		type: union
        ├─IndexRangeScan_19(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
        ├─IndexRangeScan_20(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
        └─TableRowIDScan_21(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 IN (select c1 from t2 where c2 in (select c3 from t2)) order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
///// Generated Column
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int as (c1 + c2), key(c1), key(c2));
insert into t1(c1, c2) values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	4060.74	root		index_merge.t1.c1
└─Selection_12	2250.55	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	2
2	2	4
3	3	6
4	4	8
5	5	10
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1;
id	estRows	task	access object	operator info
Sort_5	5098.44	root		index_merge.t1.c1
└─Selection_12	2825.66	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), eq(index_merge.t1.c3, plus(index_merge.t1.c1, index_merge.t1.c2))))
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = c1 + c2 order by 1;
c1	c2	c3
1	1	2
2	2	4
3	3	6
4	4	8
5	5	10
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1;
id	estRows	task	access object	operator info
Sort_5	5098.44	root		index_merge.t1.c1
└─Selection_12	2825.66	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), istrue_with_null(cast(substring(cast(index_merge.t1.c3, var_string(20)), index_merge.t1.c2), double BINARY))))
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and substring(c3, c2) order by 1;
c1	c2	c3
1	1	2
2	2	4
3	3	6
4	4	8
5	5	10
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1;
id	estRows	task	access object	operator info
Sort_5	4800.37	root		index_merge.t1.c1
└─Selection_12	2660.47	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), index_merge.t1.c3))
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 order by 1;
c1	c2	c3
1	1	2
2	2	4
3	3	6
4	4	8
5	5	10
///// SQL Binding
create global binding for
select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1
using
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	4060.74	root		index_merge.t1.c1
└─Selection_12	2250.55	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	2
2	2	4
3	3	6
4	4	8
5	5	10
///// CREATE TABLE/VIEW
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
drop view if exists v2;
create view v2 as select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10;
show create view v2;
View	Create View	character_set_client	collation_connection
v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v2` (`c1`, `c2`, `c3`) AS SELECT /*+ USE_INDEX_MERGE(`t1` )*/ `index_merge`.`t1`.`c1` AS `c1`,`index_merge`.`t1`.`c2` AS `c2`,`index_merge`.`t1`.`c3` AS `c3` FROM `index_merge`.`t1` WHERE `c1`<10 OR `c2`<10 AND `c3`<10	utf8mb4	utf8mb4_general_ci
select * from v2 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
///// DROP/ALTER INDEX
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	4060.74	root		index_merge.t1.c1
└─IndexMerge_12	2250.55	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	2250.55	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
drop index c1 on t1;
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	4060.74	root		index_merge.t1.c1
└─TableReader_10	4060.74	root		data:Selection_9
  └─Selection_9	4060.74	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
    └─TableFullScan_8	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
alter table t1 add index c1(c1);
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	4060.74	root		index_merge.t1.c1
└─IndexMerge_12	2250.55	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	2250.55	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
///// DELETE
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
explain delete from t1 where c1 in (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10) order by 1;
id	estRows	task	access object	operator info
Delete_9	N/A	root		N/A
└─Sort_14	4056.68	root		index_merge.t1.c1
  └─HashJoin_31	4056.68	root		inner join, equal:[eq(index_merge.t1.c1, index_merge.t1.c1)]
    ├─HashAgg_33(Build)	3245.34	root		group by:index_merge.t1.c1, funcs:firstrow(index_merge.t1.c1)->index_merge.t1.c1
    │ └─IndexMerge_39	2248.30	root		type: union
    │   ├─IndexRangeScan_35(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    │   ├─IndexRangeScan_36(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    │   └─Selection_38(Probe)	2248.30	cop[tikv]		not(isnull(index_merge.t1.c1)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
    │     └─TableRowIDScan_37	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
    └─TableReader_47(Probe)	9990.00	root		data:Selection_46
      └─Selection_46	9990.00	cop[tikv]		not(isnull(index_merge.t1.c1))
        └─TableFullScan_45	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
delete from t1 where c1 in (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10) order by 1;
select * from t1;
c1	c2	c3
///// UPDATE
explain update t1 set c1 = 100, c2 = 100, c3 = 100 where c1 in (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10);
id	estRows	task	access object	operator info
Update_9	N/A	root		N/A
└─HashJoin_28	4056.68	root		inner join, equal:[eq(index_merge.t1.c1, index_merge.t1.c1)]
  ├─HashAgg_30(Build)	3245.34	root		group by:index_merge.t1.c1, funcs:firstrow(index_merge.t1.c1)->index_merge.t1.c1
  │ └─IndexMerge_36	2248.30	root		type: union
  │   ├─IndexRangeScan_32(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  │   ├─IndexRangeScan_33(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  │   └─Selection_35(Probe)	2248.30	cop[tikv]		not(isnull(index_merge.t1.c1)), or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
  │     └─TableRowIDScan_34	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
  └─TableReader_44(Probe)	9990.00	root		data:Selection_43
    └─Selection_43	9990.00	cop[tikv]		not(isnull(index_merge.t1.c1))
      └─TableFullScan_42	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
update t1 set c1 = 100, c2 = 100, c3 = 100 where c1 in (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10);
select * from t1;
c1	c2	c3
///// FOR UPDATE
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1 for update;
id	estRows	task	access object	operator info
Sort_6	4060.74	root		index_merge.t1.c1
└─Projection_8	4060.74	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─SelectLock_9	4060.74	root		for update 0
    └─IndexMerge_14	2250.55	root		type: union
      ├─IndexRangeScan_10(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
      ├─IndexRangeScan_11(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
      └─Selection_13(Probe)	2250.55	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
        └─TableRowIDScan_12	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1 for update;
c1	c2	c3
///// TEMPORARY Table. Not support for now.
drop table if exists t1;
create temporary table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Projection_13	4060.74	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
└─UnionScan_14	4060.74	root		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
  └─IndexLookUp_18	4060.74	root		
    ├─IndexFullScan_15(Build)	10000.00	cop[tikv]	table:t1, index:c1(c1)	keep order:true, stats:pseudo
    └─Selection_17(Probe)	4060.74	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
      └─TableRowIDScan_16	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
///// MEMORY Table
explain select count(c1) from (select /*+ use_index_merge(t_alias), stream_agg() */ count(1) c1 from information_schema.statements_summary where sum_latency >= 0 or max_latency >= 0 order by 1) dt;
id	estRows	task	access object	operator info
StreamAgg_9	1.00	root		funcs:count(Column#115)->Column#116
└─StreamAgg_11	1.00	root		funcs:count(1)->Column#115
  └─MemTableScan_15	10000.00	root	table:STATEMENTS_SUMMARY	
show warnings;
Level	Code	Message
Warning	1815	use_index_merge(index_merge.t_alias) is inapplicable, check whether the table(index_merge.t_alias) exists
select count(c1) from (select /*+ use_index_merge(t_alias), stream_agg() */ count(1) c1 from information_schema.statements_summary where sum_latency >= 0 or max_latency >= 0 order by 1) dt;
count(c1)
1
///// Limit
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10 order by 1 limit 1 offset 2;
id	estRows	task	access object	operator info
TopN_9	1.00	root		index_merge.t1.c1, offset:2, count:1
└─IndexMerge_18	3.00	root		type: union
  ├─IndexRangeScan_13(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_14(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─TopN_17(Probe)	3.00	cop[tikv]		index_merge.t1.c1, offset:0, count:3
    └─Selection_16	1841.86	cop[tikv]		lt(index_merge.t1.c3, 10)
      └─TableRowIDScan_15	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10 order by 1 limit 1 offset 2;
c1	c2	c3
3	3	3
///// GROUP BY
explain select /*+ use_index_merge(t1) */ sum(c1) from t1 where (c1 < 10 or c2 < 10) and c3 < 10 group by c1 order by 1;
id	estRows	task	access object	operator info
Sort_6	1473.49	root		Column#5
└─HashAgg_10	1473.49	root		group by:Column#13, funcs:sum(Column#12)->Column#5
  └─Projection_23	1841.86	root		cast(index_merge.t1.c1, decimal(10,0) BINARY)->Column#12, index_merge.t1.c1->Column#13
    └─IndexMerge_16	1841.86	root		type: union
      ├─IndexRangeScan_12(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
      ├─IndexRangeScan_13(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
      └─Selection_15(Probe)	1841.86	cop[tikv]		lt(index_merge.t1.c3, 10)
        └─TableRowIDScan_14	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ sum(c1) from t1 where (c1 < 10 or c2 < 10) and c3 < 10 group by c1 order by 1;
sum(c1)
1
2
3
4
5
///// Apply
drop table if exists t2;
create table t2(c1 int, c2 int, c3 int, key(c1), key(c2));
insert into t2 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select avg(t2.c1) from t2 where t1.c1 = t2.c1 group by t2.c1) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_12	1841.86	root		index_merge.t1.c1
└─Projection_14	1841.86	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Apply_16	1841.86	root		inner join, equal:[eq(Column#10, Column#9)]
    ├─Projection_17(Build)	1841.86	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3, cast(index_merge.t1.c1, decimal(10,0) BINARY)->Column#10
    │ └─IndexMerge_22	1841.86	root		type: union
    │   ├─IndexRangeScan_18(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    │   ├─IndexRangeScan_19(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,-1), keep order:false, stats:pseudo
    │   └─Selection_21(Probe)	1841.86	cop[tikv]		lt(index_merge.t1.c3, 10)
    │     └─TableRowIDScan_20	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
    └─MaxOneRow_23(Probe)	1841.86	root		
      └─StreamAgg_35	3683.72	root		group by:index_merge.t2.c1, funcs:avg(Column#17, Column#18)->Column#9
        └─IndexReader_36	3683.72	root		index:StreamAgg_27
          └─StreamAgg_27	3683.72	cop[tikv]		group by:index_merge.t2.c1, funcs:count(index_merge.t2.c1)->Column#17, funcs:sum(index_merge.t2.c1)->Column#18
            └─IndexRangeScan_34	4604.65	cop[tikv]	table:t2, index:c1(c1)	range: decided by [eq(index_merge.t1.c1, index_merge.t2.c1)], keep order:true, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select avg(t2.c1) from t2 where t1.c1 = t2.c1 group by t2.c1) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select /*+ use_index_merge(t2) */ avg(t2.c1) from t2 where t1.c1 = t2.c1 and t2.c1 < 10 or t2.c2 < 10 group by t2.c1 order by c1 limit 1 offset 2) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_16	1841.86	root		index_merge.t1.c1
└─Projection_18	1841.86	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3
  └─Apply_20	1841.86	root		inner join, equal:[eq(Column#11, Column#9)]
    ├─Projection_21(Build)	1841.86	root		index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3, cast(index_merge.t1.c1, decimal(10,0) BINARY)->Column#11
    │ └─IndexMerge_26	1841.86	root		type: union
    │   ├─IndexRangeScan_22(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    │   ├─IndexRangeScan_23(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,-1), keep order:false, stats:pseudo
    │   └─Selection_25(Probe)	1841.86	cop[tikv]		lt(index_merge.t1.c3, 10)
    │     └─TableRowIDScan_24	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
    └─TopN_29(Probe)	1841.86	root		index_merge.t2.c1, offset:2, count:1
      └─HashAgg_35	4900166.23	root		group by:Column#23, funcs:avg(Column#22)->Column#9, funcs:firstrow(Column#23)->index_merge.t2.c1
        └─Projection_53	6125207.79	root		cast(index_merge.t2.c1, decimal(10,0) BINARY)->Column#22, index_merge.t2.c1->Column#23
          └─IndexMerge_41	6125207.79	root		type: union
            ├─Selection_38(Build)	6121.12	cop[tikv]		eq(index_merge.t1.c1, index_merge.t2.c1)
            │ └─IndexRangeScan_37	6121120.92	cop[tikv]	table:t2, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
            ├─IndexRangeScan_39(Build)	6121120.92	cop[tikv]	table:t2, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
            └─TableRowIDScan_40(Probe)	6125207.79	cop[tikv]	table:t2	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select /*+ use_index_merge(t2) */ avg(t2.c1) from t2 where t1.c1 = t2.c1 and t2.c1 < 10 or t2.c2 < 10 group by t2.c1 order by c1 limit 1 offset 2) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1;
c1	c2	c3
3	3	3
///// Nested filters
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, c4 int, c5 int, key(c1), key(c2), key(c3), key(c4));
insert into t1 values(1, 1, 1, 1, 1), (2, 2, 2, 2, 2), (3, 3, 3, 3, 3), (4, 4, 4, 4, 4), (5, 5, 5, 5, 5);
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c3 < 10 or c4 < 10) order by 1;
id	estRows	task	access object	operator info
Sort_5	3071.61	root		index_merge.t1.c1
└─IndexMerge_12	3071.61	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	3071.61	cop[tikv]		or(lt(index_merge.t1.c3, 10), lt(index_merge.t1.c4, 10))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c3 < 10 or c4 < 10) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) order by 1;
id	estRows	task	access object	operator info
Sort_5	2086.93	root		index_merge.t1.c1
└─IndexMerge_12	1156.62	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c3(c3)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	1156.62	cop[tikv]		or(and(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c2, 10)), and(lt(index_merge.t1.c3, 10), lt(index_merge.t1.c4, 10)))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) and c5 < 10 order by 1;
id	estRows	task	access object	operator info
Sort_5	1430.96	root		index_merge.t1.c1
└─IndexMerge_12	793.07	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c3(c3)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	793.07	cop[tikv]		or(and(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c2, 10)), and(lt(index_merge.t1.c3, 10), and(lt(index_merge.t1.c4, 10), lt(index_merge.t1.c5, 10))))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) and c4 < 10 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where ((c1 < 10 and c4 < 10) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1;
id	estRows	task	access object	operator info
Sort_5	2250.55	root		index_merge.t1.c1
└─IndexMerge_12	1247.30	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	1247.30	cop[tikv]		or(and(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c4, 10)), lt(index_merge.t1.c2, 10)), or(lt(index_merge.t1.c3, 10), lt(index_merge.t1.c5, 10))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where ((c1 < 10 and c4 < 10) or c2 < 10) and (c3 < 10 or c4 < 10) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (((c1 < 10 or c3 < 10) and (c1 < 10 or c4 < 10)) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1;
id	estRows	task	access object	operator info
Sort_5	2978.47	root		index_merge.t1.c1
└─TableReader_10	2978.47	root		data:Selection_9
  └─Selection_9	2978.47	cop[tikv]		or(and(or(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c3, 10)), or(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c4, 10))), lt(index_merge.t1.c2, 10)), or(lt(index_merge.t1.c3, 10), lt(index_merge.t1.c5, 10))
    └─TableFullScan_8	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
show warnings;
Level	Code	Message
Warning	1105	IndexMerge is inapplicable
select /*+ use_index_merge(t1) */ * from t1 where (((c1 < 10 or c3 < 10) and (c1 < 10 or c4 < 10)) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (((c1 < 10 or c3 < 10) and c1 < 10) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1;
id	estRows	task	access object	operator info
Sort_5	2523.42	root		index_merge.t1.c1
└─IndexMerge_12	1398.53	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	1398.53	cop[tikv]		or(and(or(lt(index_merge.t1.c1, 10), lt(index_merge.t1.c3, 10)), lt(index_merge.t1.c1, 10)), lt(index_merge.t1.c2, 10)), or(lt(index_merge.t1.c3, 10), lt(index_merge.t1.c5, 10))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (((c1 < 10 or c3 < 10) and c1 < 10) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
///// All kinds of expressions
// common functions
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and coalesce(c1, c2, c4) = 1 order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		eq(coalesce(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and coalesce(c1, c2, c4) = 1 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─Selection_12	4433.77	root		eq(greatest(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c4), 1)
  └─IndexMerge_11	5542.21	root		type: union
    ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and greatest(c1, c2, c4) = 1 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
// math functions
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and abs(c1) = 1 order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		eq(abs(index_merge.t1.c1), 1)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and abs(c1) = 1 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and pi() order by 1;
id	estRows	task	access object	operator info
Sort_5	5542.21	root		index_merge.t1.c1
└─IndexMerge_11	5542.21	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─TableRowIDScan_10(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and pi() order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ceil(c1) order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		ceil(index_merge.t1.c1)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ceil(c1) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and truncate(c1, 1) = 1 order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─Selection_8	4433.77	root		eq(truncate(index_merge.t1.c1, 1), 1)
  └─IndexMerge_12	5542.21	root		type: union
    ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
    ├─IndexRangeScan_10(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
    └─TableRowIDScan_11(Probe)	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and truncate(c1, 1) = 1 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and sqrt(-1) order by 1;
id	estRows	task	access object	operator info
TableDual_11	0.00	root		rows:0
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and sqrt(-1) order by 1;
c1	c2	c3	c4	c5
// string functions
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and substring(c3, 1, 1) = '1' order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		eq(substring(cast(index_merge.t1.c3, var_string(20)), 1, 1), "1")
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and substring(c3, 1, 1) = '1' order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
// control functions
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ifnull(c1, c2) order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		ifnull(index_merge.t1.c1, index_merge.t1.c2)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ifnull(c1, c2) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and if(c1, c2, c3) order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		if(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and if(c1, c2, c3) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c1 between 1 and 2) order by 1;
id	estRows	task	access object	operator info
Sort_5	138.56	root		index_merge.t1.c1
└─IndexMerge_12	138.56	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	138.56	cop[tikv]		ge(index_merge.t1.c1, 1), le(index_merge.t1.c1, 2)
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c1 between 1 and 2) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
// mixed usage
set @a = 1;
explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and length(substring(sqrt(c3), @a, 1)) = char_length(if(c1, c2, c3)) order by 1;
id	estRows	task	access object	operator info
Sort_5	4433.77	root		index_merge.t1.c1
└─IndexMerge_12	4433.77	root		type: union
  ├─IndexRangeScan_8(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_9(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_11(Probe)	4433.77	cop[tikv]		eq(length(substring(cast(sqrt(cast(index_merge.t1.c3, double BINARY)), var_string(370)), 1, 1)), char_length(cast(if(index_merge.t1.c1, index_merge.t1.c2, index_merge.t1.c3), var_string(20))))
    └─TableRowIDScan_10	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and length(substring(sqrt(c3), @a, 1)) = char_length(if(c1, c2, c3)) order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
///// CTE
drop table if exists t1;
create table t1(c1 int, c2 int, c3 int, c4 int, c5 int, key(c1), key(c2), key(c3), key(c4));
insert into t1 values(1, 1, 1, 1, 1), (2, 2, 2, 2, 2), (3, 3, 3, 3, 3), (4, 4, 4, 4, 4), (5, 5, 5, 5, 5);
explain with cte1 as (select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10) select * from cte1 order by 1;
id	estRows	task	access object	operator info
Sort_10	4060.74	root		index_merge.t1.c1
└─IndexMerge_17	2250.55	root		type: union
  ├─IndexRangeScan_13(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
  ├─IndexRangeScan_14(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
  └─Selection_16(Probe)	2250.55	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
    └─TableRowIDScan_15	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
with cte1 as (select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10) select * from cte1 order by 1;
c1	c2	c3	c4	c5
1	1	1	1	1
2	2	2	2	2
3	3	3	3	3
4	4	4	4	4
5	5	5	5	5
explain with recursive cte1 as (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10 UNION ALL select c1 + 100 from cte1 where c1 < 10) select * from cte1 order by 1;
id	estRows	task	access object	operator info
Sort_24	7309.33	root		index_merge.t1.c1
└─CTEFullScan_27	7309.33	root	CTE:cte1	data:CTE_0
CTE_0	7309.33	root		Recursive CTE
├─Projection_14(Seed Part)	4060.74	root		index_merge.t1.c1
│ └─IndexMerge_20	2250.55	root		type: union
│   ├─IndexRangeScan_16(Build)	3323.33	cop[tikv]	table:t1, index:c1(c1)	range:[-inf,10), keep order:false, stats:pseudo
│   ├─IndexRangeScan_17(Build)	3323.33	cop[tikv]	table:t1, index:c2(c2)	range:[-inf,10), keep order:false, stats:pseudo
│   └─Selection_19(Probe)	2250.55	cop[tikv]		or(lt(index_merge.t1.c1, 10), and(lt(index_merge.t1.c2, 10), lt(index_merge.t1.c3, 10)))
│     └─TableRowIDScan_18	5542.21	cop[tikv]	table:t1	keep order:false, stats:pseudo
└─Projection_21(Recursive Part)	3248.59	root		cast(plus(index_merge.t1.c1, 100), int)->index_merge.t1.c1
  └─Selection_22	3248.59	root		lt(index_merge.t1.c1, 10)
    └─CTETable_23	4060.74	root		Scan on CTE_0
with recursive cte1 as (select /*+ use_index_merge(t1) */ c1 from t1 where c1 < 10 or c2 < 10 and c3 < 10 UNION ALL select c1 + 100 from cte1 where c1 < 10) select * from cte1 order by 1;
c1
1
2
3
4
5
101
102
103
104
105
explain with recursive cte1 as (select 1 c1, 1 c2, 1 c3 UNION ALL select /*+ use_index_merge(t_alias) */ c1 + 1, c2 + 1, c3 + 1 from cte1 t_alias where c1 < 10 or c2 < 10 and c3 < 10) select * from cte1 order by 1;
id	estRows	task	access object	operator info
Sort_17	1.80	root		Column#16
└─CTEFullScan_20	1.80	root	CTE:cte1	data:CTE_0
CTE_0	1.80	root		Recursive CTE
├─Projection_12(Seed Part)	1.00	root		1->Column#4, 1->Column#5, 1->Column#6
│ └─TableDual_13	1.00	root		rows:1
└─Projection_14(Recursive Part)	0.80	root		cast(plus(Column#7, 1), bigint BINARY)->Column#13, cast(plus(Column#8, 1), bigint BINARY)->Column#14, cast(plus(Column#9, 1), bigint BINARY)->Column#15
  └─Selection_15	0.80	root		or(lt(Column#7, 10), and(lt(Column#8, 10), lt(Column#9, 10)))
    └─CTETable_16	1.00	root		Scan on CTE_0
show warnings;
Level	Code	Message
Warning	1815	use_index_merge(index_merge.t_alias) is inapplicable, check whether the table(index_merge.t_alias) exists
Warning	1815	use_index_merge(index_merge.t_alias) is inapplicable, check whether the table(index_merge.t_alias) exists
with recursive cte1 as (select 1 c1, 1 c2, 1 c3 UNION ALL select /*+ use_index_merge(t_alias) */ c1 + 1, c2 + 1, c3 + 1 from cte1 t_alias where c1 < 10 or c2 < 10 and c3 < 10) select * from cte1 order by 1;
c1	c2	c3
1	1	1
2	2	2
3	3	3
4	4	4
5	5	5
6	6	6
7	7	7
8	8	8
9	9	9
10	10	10
