planner/cascades: add transformation rule PushTopNDownOuterJoin (#14249)
This commit is contained in:
committed by
pingcap-github-bot
parent
cdf1430260
commit
dbb6fdf51d
@ -39,6 +39,13 @@
|
||||
"select a, b, c from t t1 where t1.a in (select t2.a as a from t t2 where t2.b > t1.b order by t1.b limit 1)",
|
||||
"select a, b, c from t t1 where t1.a in (select a from (select t2.a as a, t1.b as b from t t2 where t2.b > t1.b) x order by b limit 1)",
|
||||
"select a, b from (select @i as a, @i := @i+1 as b from t) t order by a desc limit 1",
|
||||
"select * from t t1 left join t t2 on t1.b = t2.b order by t1.b limit 1",
|
||||
"select * from t t1 left join t t2 on t1.b = t2.b order by t1.a, t1.c limit 1",
|
||||
"select * from t t1 left join t t2 on t1.b = t2.b order by t2.a, t2.c limit 1",
|
||||
"select * from t t1 left join t t2 on t1.b = t2.b order by t1.a, t2.c limit 1",
|
||||
"select * from t t1 right join t t2 on t1.b = t2.b order by t1.a, t1.c limit 1",
|
||||
"select * from t t1 right join t t2 on t1.b = t2.b order by t2.a, t2.c limit 1",
|
||||
"select * from t t1 right join t t2 on t1.b = t2.b order by t1.a, t2.c limit 1",
|
||||
"(select a from t) union all (select b from t) order by a limit 2;",
|
||||
"(select a from t) union all (select b from t) limit 2;",
|
||||
"(select a from t) union all (select b from t) limit 2 offset 5;",
|
||||
|
||||
@ -506,6 +506,151 @@
|
||||
" IndexScan_8 table:t, index:c, d, e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b order by t1.b limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.b:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_13 input:[Group#5], test.t.b:asc, offset:0, count:1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#6], table:t1",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_14 input:[Group#7], test.t.b:asc, offset:0, count:1",
|
||||
"Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#8], table:t2",
|
||||
"Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b order by t1.a, t1.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_13 input:[Group#5], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#6], table:t1",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_14 input:[Group#7], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#8], table:t2",
|
||||
"Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b order by t2.a, t2.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#5], table:t1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#6], table:t2",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 left join t t2 on t1.b = t2.b order by t1.a, t2.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], left outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#5], table:t1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#6], table:t2",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 right join t t2 on t1.b = t2.b order by t1.a, t1.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#5], table:t1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#6], table:t2",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 right join t t2 on t1.b = t2.b order by t2.a, t2.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#5], table:t1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_13 input:[Group#6], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#7], table:t2",
|
||||
"Group#7 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_14 input:[Group#8], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#8 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "select * from t t1 right join t t2 on t1.b = t2.b order by t1.a, t2.c limit 1",
|
||||
"Result": [
|
||||
"Group#0 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Projection_4 input:[Group#1], test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date, test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.c_str, test.t.d_str, test.t.e_str, test.t.f, test.t.g, test.t.h, test.t.i_date",
|
||||
"Group#1 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TopN_12 input:[Group#2], test.t.a:asc, test.t.c:asc, offset:0, count:1",
|
||||
"Group#2 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date,test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" Join_3 input:[Group#3,Group#4], right outer join, equal:[eq(test.t.b, test.t.b)]",
|
||||
"Group#3 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_8 input:[Group#5], table:t1",
|
||||
"Group#5 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_7 table:t1, pk col:test.t.a",
|
||||
"Group#4 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TiKVSingleGather_10 input:[Group#6], table:t2",
|
||||
"Group#6 Schema:[test.t.a,test.t.b,test.t.c,test.t.d,test.t.e,test.t.c_str,test.t.d_str,test.t.e_str,test.t.f,test.t.g,test.t.h,test.t.i_date]",
|
||||
" TableScan_9 table:t2, pk col:test.t.a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SQL": "(select a from t) union all (select b from t) order by a limit 2;",
|
||||
"Result": [
|
||||
|
||||
@ -76,6 +76,7 @@ var defaultTransformationMap = map[memo.Operand][]Transformation{
|
||||
},
|
||||
memo.OperandTopN: {
|
||||
NewRulePushTopNDownProjection(),
|
||||
NewRulePushTopNDownOuterJoin(),
|
||||
NewRulePushTopNDownUnionAll(),
|
||||
NewRulePushTopNDownTiKVSingleGather(),
|
||||
},
|
||||
@ -1035,6 +1036,89 @@ func (r *MergeAdjacentProjection) OnTransform(old *memo.ExprIter) (newExprs []*m
|
||||
return []*memo.GroupExpr{newProjExpr}, true, false, nil
|
||||
}
|
||||
|
||||
// PushTopNDownOuterJoin pushes topN to outer join.
|
||||
type PushTopNDownOuterJoin struct {
|
||||
baseRule
|
||||
}
|
||||
|
||||
// NewRulePushTopNDownOuterJoin creates a new Transformation PushTopNDownOuterJoin.
|
||||
// The pattern of this rule is: `TopN -> Join`.
|
||||
func NewRulePushTopNDownOuterJoin() Transformation {
|
||||
rule := &PushTopNDownOuterJoin{}
|
||||
rule.pattern = memo.BuildPattern(
|
||||
memo.OperandTopN,
|
||||
memo.EngineTiDBOnly,
|
||||
memo.NewPattern(memo.OperandJoin, memo.EngineTiDBOnly),
|
||||
)
|
||||
return rule
|
||||
}
|
||||
|
||||
// Match implements Transformation interface.
|
||||
// Use appliedRuleSet in GroupExpr to avoid re-apply rules.
|
||||
func (r *PushTopNDownOuterJoin) Match(expr *memo.ExprIter) bool {
|
||||
if expr.GetExpr().HasAppliedRule(r) {
|
||||
return false
|
||||
}
|
||||
join := expr.Children[0].GetExpr().ExprNode.(*plannercore.LogicalJoin)
|
||||
switch join.JoinType {
|
||||
case plannercore.LeftOuterJoin, plannercore.LeftOuterSemiJoin, plannercore.AntiLeftOuterSemiJoin, plannercore.RightOuterJoin:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func pushTopNDownOuterJoinToChild(topN *plannercore.LogicalTopN, outerGroup *memo.Group) *memo.Group {
|
||||
for _, by := range topN.ByItems {
|
||||
cols := expression.ExtractColumns(by.Expr)
|
||||
for _, col := range cols {
|
||||
if !outerGroup.Prop.Schema.Contains(col) {
|
||||
return outerGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newTopN := plannercore.LogicalTopN{
|
||||
Count: topN.Count + topN.Offset,
|
||||
ByItems: make([]*plannercore.ByItems, len(topN.ByItems)),
|
||||
}.Init(topN.SCtx(), topN.SelectBlockOffset())
|
||||
|
||||
for i := range topN.ByItems {
|
||||
newTopN.ByItems[i] = topN.ByItems[i].Clone()
|
||||
}
|
||||
newTopNGroup := memo.NewGroupExpr(newTopN)
|
||||
newTopNGroup.SetChildren(outerGroup)
|
||||
newChild := memo.NewGroupWithSchema(newTopNGroup, outerGroup.Prop.Schema)
|
||||
return newChild
|
||||
}
|
||||
|
||||
// OnTransform implements Transformation interface.
|
||||
// This rule will transform `TopN->OuterJoin->(OuterChild, InnerChild)` to `TopN->OuterJoin->(TopN->OuterChild, InnerChild)`
|
||||
func (r *PushTopNDownOuterJoin) OnTransform(old *memo.ExprIter) (newExprs []*memo.GroupExpr, eraseOld bool, eraseAll bool, err error) {
|
||||
topN := old.GetExpr().ExprNode.(*plannercore.LogicalTopN)
|
||||
joinExpr := old.Children[0].GetExpr()
|
||||
join := joinExpr.ExprNode.(*plannercore.LogicalJoin)
|
||||
joinSchema := old.Children[0].Group.Prop.Schema
|
||||
leftGroup := joinExpr.Children[0]
|
||||
rightGroup := joinExpr.Children[1]
|
||||
|
||||
switch join.JoinType {
|
||||
case plannercore.LeftOuterJoin, plannercore.LeftOuterSemiJoin, plannercore.AntiLeftOuterSemiJoin:
|
||||
leftGroup = pushTopNDownOuterJoinToChild(topN, leftGroup)
|
||||
case plannercore.RightOuterJoin:
|
||||
rightGroup = pushTopNDownOuterJoinToChild(topN, rightGroup)
|
||||
default:
|
||||
return nil, false, false, nil
|
||||
}
|
||||
|
||||
newJoinExpr := memo.NewGroupExpr(join)
|
||||
newJoinExpr.SetChildren(leftGroup, rightGroup)
|
||||
newTopNExpr := memo.NewGroupExpr(topN)
|
||||
newTopNExpr.SetChildren(memo.NewGroupWithSchema(newJoinExpr, joinSchema))
|
||||
newTopNExpr.AddAppliedRule(r)
|
||||
return []*memo.GroupExpr{newTopNExpr}, true, false, nil
|
||||
}
|
||||
|
||||
// PushTopNDownProjection pushes TopN to Projection.
|
||||
type PushTopNDownProjection struct {
|
||||
baseRule
|
||||
|
||||
@ -158,6 +158,7 @@ func (s *testTransformationRuleSuite) TestTopNRules(c *C) {
|
||||
},
|
||||
memo.OperandTopN: {
|
||||
NewRulePushTopNDownProjection(),
|
||||
NewRulePushTopNDownOuterJoin(),
|
||||
NewRulePushTopNDownUnionAll(),
|
||||
NewRulePushTopNDownTiKVSingleGather(),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user