Analyzer ORDER BY read in order query plan add test

This commit is contained in:
Maksim Kita 2023-11-09 18:27:59 +03:00
parent c391527c86
commit 23f0811267
4 changed files with 567 additions and 2 deletions

View File

@ -2,7 +2,6 @@
00593_union_all_assert_columns_removed 00593_union_all_assert_columns_removed
00717_merge_and_distributed 00717_merge_and_distributed
00725_memory_tracking 00725_memory_tracking
00940_order_by_read_in_order_query_plan
01062_pm_all_join_with_block_continuation 01062_pm_all_join_with_block_continuation
01064_incremental_streaming_from_2_src_with_feedback 01064_incremental_streaming_from_2_src_with_feedback
01083_expressions_in_engine_arguments 01083_expressions_in_engine_arguments

View File

@ -1,4 +1,4 @@
SET optimize_read_in_order = 1, query_plan_read_in_order=1; SET optimize_read_in_order = 1, query_plan_read_in_order = 1, allow_experimental_analyzer = 0;
drop table if exists tab; drop table if exists tab;
drop table if exists tab2; drop table if exists tab2;

View File

@ -0,0 +1,410 @@
-- { echoOn }
-- Exact match, single key
select * from tab order by (a + b) * c;
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from tab order by (a + b) * c) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC
select * from tab order by (a + b) * c desc;
4 4 4 4
4 4 4 4
3 3 3 3
3 3 3 3
2 2 2 2
2 2 2 2
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC
-- Exact match, full key
select * from tab order by (a + b) * c, sin(a / b);
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, sin(a / b)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
select * from tab order by (a + b) * c desc, sin(a / b) desc;
4 4 4 4
4 4 4 4
3 3 3 3
3 3 3 3
2 2 2 2
2 2 2 2
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, sin(a / b) desc) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC, sin(divide(a_0, b_1)) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, sin(divide(a_0, b_1)) DESC
-- Exact match, mixed direction
select * from tab order by (a + b) * c desc, sin(a / b);
4 4 4 4
4 4 4 4
3 3 3 3
3 3 3 3
2 2 2 2
2 2 2 2
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, sin(a / b)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, sin(divide(a_0, b_1)) ASC
select * from tab order by (a + b) * c, sin(a / b) desc;
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, sin(a / b) desc) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) DESC
-- Wrong order, full sort
select * from tab order by sin(a / b), (a + b) * c;
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from tab order by sin(a / b), (a + b) * c) where explain ilike '%sort description%';
Sort description: sin(divide(a_0, b_1)) ASC, multiply(plus(a_0, b_1), c_2) ASC
-- Fixed point
select * from tab where (a + b) * c = 8 order by sin(a / b);
2 2 2 2
2 2 2 2
select * from (explain plan actions = 1 select * from tab where (a + b) * c = 8 order by sin(a / b)) where explain ilike '%sort description%';
Prefix sort description: sin(divide(a_0, b_1)) ASC
Result sort description: sin(divide(a_0, b_1)) ASC
select * from tab where d + 1 = 2 order by (d + 1) * 4, (a + b) * c;
1 1 1 1
1 1 1 1
select * from (explain plan actions = 1 select * from tab where d + 1 = 2 order by (d + 1) * 4, (a + b) * c) where explain ilike '%sort description%';
Prefix sort description: multiply(plus(d_3, 1_UInt8), 4_UInt8) ASC, multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(d_3, 1_UInt8), 4_UInt8) ASC, multiply(plus(a_0, b_1), c_2) ASC
select * from tab where d + 1 = 3 and (a + b) = 4 and c = 2 order by (d + 1) * 4, sin(a / b);
2 2 2 2
2 2 2 2
select * from (explain plan actions = 1 select * from tab where d + 1 = 3 and (a + b) = 4 and c = 2 order by (d + 1) * 4, sin(a / b)) where explain ilike '%sort description%';
Prefix sort description: multiply(plus(d_3, 1_UInt8), 4_UInt8) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(d_3, 1_UInt8), 4_UInt8) ASC, sin(divide(a_0, b_1)) ASC
-- Wrong order with fixed point
select * from tab where (a + b) * c = 8 order by sin(b / a);
2 2 2 2
2 2 2 2
select * from (explain plan actions = 1 select * from tab where (a + b) * c = 8 order by sin(b / a)) where explain ilike '%sort description%';
Sort description: sin(divide(b_1, a_0)) ASC
-- Monotonicity
select * from tab order by intDiv((a + b) * c, 2);
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from tab order by intDiv((a + b) * c, 2)) where explain like '%sort description%';
Prefix sort description: intDiv(multiply(plus(a_0, b_1), c_2), 2_UInt8) ASC
Result sort description: intDiv(multiply(plus(a_0, b_1), c_2), 2_UInt8) ASC
select * from tab order by intDiv((a + b) * c, 2), sin(a / b);
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from tab order by intDiv((a + b) * c, 2), sin(a / b)) where explain like '%sort description%';
Prefix sort description: intDiv(multiply(plus(a_0, b_1), c_2), 2_UInt8) ASC
Result sort description: intDiv(multiply(plus(a_0, b_1), c_2), 2_UInt8) ASC, sin(divide(a_0, b_1)) ASC
-- select * from tab order by (a + b) * c, intDiv(sin(a / b), 2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(sin(a / b), 2)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) ASC
-- select * from tab order by (a + b) * c desc , intDiv(sin(a / b), 2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc , intDiv(sin(a / b), 2)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) ASC
-- select * from tab order by (a + b) * c, intDiv(sin(a / b), 2) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(sin(a / b), 2) desc) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) DESC
-- select * from tab order by (a + b) * c desc, intDiv(sin(a / b), 2) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(sin(a / b), 2) desc) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(sin(divide(a_0, b_1)), 2_UInt8) DESC
-- select * from tab order by (a + b) * c desc, intDiv(sin(a / b), -2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(sin(a / b), -2)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(sin(divide(a_0, b_1)), -2_Int8) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(sin(divide(a_0, b_1)), -2_Int8) ASC
-- select * from tab order by (a + b) * c desc, intDiv(intDiv(sin(a / b), -2), -3);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(intDiv(sin(a / b), -2), -3)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) DESC
Result sort description: multiply(plus(a_0, b_1), c_2) DESC, intDiv(intDiv(sin(divide(a_0, b_1)), -2_Int8), -3_Int8) ASC
-- select * from tab order by (a + b) * c, intDiv(intDiv(sin(a / b), -2), -3);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(intDiv(sin(a / b), -2), -3)) where explain like '%sort description%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, intDiv(intDiv(sin(divide(a_0, b_1)), -2_Int8), -3_Int8) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, intDiv(intDiv(sin(divide(a_0, b_1)), -2_Int8), -3_Int8) ASC
-- Aliases
select * from (select *, a + b as x from tab) order by x * c;
0 0 0 0 0
0 0 0 0 0
1 1 1 1 2
1 1 1 1 2
2 2 2 2 4
2 2 2 2 4
3 3 3 3 6
3 3 3 3 6
4 4 4 4 8
4 4 4 4 8
select * from (explain plan actions = 1 select * from (select *, a + b as x from tab) order by x * c) where explain like '%sort description%';
Prefix sort description: multiply(x_4, c_2) ASC
Result sort description: multiply(x_4, c_2) ASC
select * from (select *, a + b as x, a / b as y from tab) order by x * c, sin(y);
0 0 0 0 0 nan
0 0 0 0 0 nan
1 1 1 1 2 1
1 1 1 1 2 1
2 2 2 2 4 1
2 2 2 2 4 1
3 3 3 3 6 1
3 3 3 3 6 1
4 4 4 4 8 1
4 4 4 4 8 1
select * from (explain plan actions = 1 select * from (select *, a + b as x, a / b as y from tab) order by x * c, sin(y)) where explain like '%sort description%';
Prefix sort description: multiply(x_4, c_2) ASC, sin(y_5) ASC
Result sort description: multiply(x_4, c_2) ASC, sin(y_5) ASC
select * from (select *, a / b as y from (select *, a + b as x from tab)) order by x * c, sin(y);
0 0 0 0 0 nan
0 0 0 0 0 nan
1 1 1 1 2 1
1 1 1 1 2 1
2 2 2 2 4 1
2 2 2 2 4 1
3 3 3 3 6 1
3 3 3 3 6 1
4 4 4 4 8 1
4 4 4 4 8 1
select * from (explain plan actions = 1 select * from (select *, a / b as y from (select *, a + b as x from tab)) order by x * c, sin(y)) where explain like '%sort description%';
Prefix sort description: multiply(x_4, c_2) ASC, sin(y_5) ASC
Result sort description: multiply(x_4, c_2) ASC, sin(y_5) ASC
-- { echoOn }
select * from tab2 order by toTimeZone(toTimezone(x, 'UTC'), 'CET'), intDiv(intDiv(y, -2), -3);
2020-02-02 00:00:00 0 0
2020-02-02 00:00:00 0 0
2020-02-03 00:00:00 1 1
2020-02-03 00:00:00 1 1
2020-02-04 00:00:00 2 2
2020-02-04 00:00:00 2 2
2020-02-05 00:00:00 3 3
2020-02-05 00:00:00 3 3
select * from (explain plan actions = 1 select * from tab2 order by toTimeZone(toTimezone(x, 'UTC'), 'CET'), intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
Prefix sort description: toTimezone(toTimezone(x_0, \'UTC\'_String), \'CET\'_String) ASC, intDiv(intDiv(y_1, -2_Int8), -3_Int8) ASC
Result sort description: toTimezone(toTimezone(x_0, \'UTC\'_String), \'CET\'_String) ASC, intDiv(intDiv(y_1, -2_Int8), -3_Int8) ASC
select * from tab2 order by toStartOfDay(x), intDiv(intDiv(y, -2), -3);
2020-02-02 00:00:00 0 0
2020-02-02 00:00:00 0 0
2020-02-03 00:00:00 1 1
2020-02-03 00:00:00 1 1
2020-02-04 00:00:00 2 2
2020-02-04 00:00:00 2 2
2020-02-05 00:00:00 3 3
2020-02-05 00:00:00 3 3
select * from (explain plan actions = 1 select * from tab2 order by toStartOfDay(x), intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
Prefix sort description: toStartOfDay(x_0) ASC
Result sort description: toStartOfDay(x_0) ASC, intDiv(intDiv(y_1, -2_Int8), -3_Int8) ASC
-- select * from tab2 where toTimezone(x, 'CET') = '2020-02-03 01:00:00' order by intDiv(intDiv(y, -2), -3);
select * from (explain plan actions = 1 select * from tab2 where toTimezone(x, 'CET') = '2020-02-03 01:00:00' order by intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
Prefix sort description: intDiv(intDiv(y_1, -2_Int8), -3_Int8) ASC
Result sort description: intDiv(intDiv(y_1, -2_Int8), -3_Int8) ASC
-- { echoOn }
-- Union (not fully supported)
select * from (select * from tab union all select * from tab3) order by (a + b) * c, sin(a / b);
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab3) order by (a + b) * c, sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
ReadType: InOrder
ReadType: InOrder
select * from (select * from tab where (a + b) * c = 8 union all select * from tab3 where (a + b) * c = 18) order by sin(a / b);
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
select * from (explain plan actions = 1 select * from (select * from tab where (a + b) * c = 8 union all select * from tab3 where (a + b) * c = 18) order by sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
Prefix sort description: sin(divide(a_0, b_1)) ASC
Result sort description: sin(divide(a_0, b_1)) ASC
ReadType: InOrder
ReadType: InOrder
select * from (select * from tab where (a + b) * c = 8 union all select * from tab4) order by sin(a / b);
2 2 2 2
2 2 2 2
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from (select * from tab where (a + b) * c = 8 union all select * from tab4) order by sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
Prefix sort description: sin(divide(a_0, b_1)) ASC
Result sort description: sin(divide(a_0, b_1)) ASC
ReadType: InOrder
ReadType: InOrder
select * from (select * from tab union all select * from tab5) order by (a + b) * c;
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c) where explain like '%sort description%' or explain like '%ReadType%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC
ReadType: InOrder
ReadType: InOrder
select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b);
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
ReadType: InOrder
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
ReadType: InOrder
-- Union with limit
select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b) limit 3;
0 0 0 0
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b) limit 3) where explain ilike '%sort description%' or explain like '%ReadType%' or explain like '%Limit%';
Limit (preliminary LIMIT (without OFFSET))
Limit 3
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Limit 3
ReadType: InOrder
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
ReadType: InOrder
-- In this example, we read-in-order from tab up to ((a + b) * c, sin(a / b)) and from tab5 up to ((a + b) * c).
-- In case of tab5, there would be two finish sorting transforms: ((a + b) * c) -> ((a + b) * c, sin(a / b)) -> ((a + b) * c, sin(a / b), d).
-- It's important that ((a + b) * c) -> ((a + b) * c does not have LIMIT. We can add LIMIT WITH TIES later, when sorting alog support it.
-- In case of tab4, we do full sorting by ((a + b) * c, sin(a / b), d) with LIMIT. We can replace it to sorting by ((a + b) * c, sin(a / b)) and LIMIT WITH TIES, when sorting alog support it.
select * from (select * from tab union all select * from tab5 union all select * from tab4) order by (a + b) * c, sin(a / b), d limit 3;
0 0 0 0
0 0 0 0
0 0 0 0
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5 union all select * from tab4) order by (a + b) * c, sin(a / b), d limit 3) where explain ilike '%sort description%' or explain like '%ReadType%' or explain like '%Limit%';
Limit (preliminary LIMIT (without OFFSET))
Limit 3
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC, d_3 ASC
Limit 3
ReadType: InOrder
Prefix sort description: multiply(plus(a_0, b_1), c_2) ASC
Result sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC
ReadType: InOrder
Sort description: multiply(plus(a_0, b_1), c_2) ASC, sin(divide(a_0, b_1)) ASC, d_3 ASC
Limit 3
ReadType: Default
drop table if exists tab;
drop table if exists tab2;
drop table if exists tab3;
drop table if exists tab4;
drop table if exists tab5;

View File

@ -0,0 +1,156 @@
SET optimize_read_in_order = 1, query_plan_read_in_order = 1, allow_experimental_analyzer = 1;
drop table if exists tab;
drop table if exists tab2;
drop table if exists tab3;
drop table if exists tab4;
drop table if exists tab5;
create table tab (a UInt32, b UInt32, c UInt32, d UInt32) engine = MergeTree order by ((a + b) * c, sin(a / b));
insert into tab select number, number, number, number from numbers(5);
insert into tab select number, number, number, number from numbers(5);
-- { echoOn }
-- Exact match, single key
select * from tab order by (a + b) * c;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c) where explain like '%sort description%';
select * from tab order by (a + b) * c desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc) where explain like '%sort description%';
-- Exact match, full key
select * from tab order by (a + b) * c, sin(a / b);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, sin(a / b)) where explain like '%sort description%';
select * from tab order by (a + b) * c desc, sin(a / b) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, sin(a / b) desc) where explain like '%sort description%';
-- Exact match, mixed direction
select * from tab order by (a + b) * c desc, sin(a / b);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, sin(a / b)) where explain like '%sort description%';
select * from tab order by (a + b) * c, sin(a / b) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, sin(a / b) desc) where explain like '%sort description%';
-- Wrong order, full sort
select * from tab order by sin(a / b), (a + b) * c;
select * from (explain plan actions = 1 select * from tab order by sin(a / b), (a + b) * c) where explain ilike '%sort description%';
-- Fixed point
select * from tab where (a + b) * c = 8 order by sin(a / b);
select * from (explain plan actions = 1 select * from tab where (a + b) * c = 8 order by sin(a / b)) where explain ilike '%sort description%';
select * from tab where d + 1 = 2 order by (d + 1) * 4, (a + b) * c;
select * from (explain plan actions = 1 select * from tab where d + 1 = 2 order by (d + 1) * 4, (a + b) * c) where explain ilike '%sort description%';
select * from tab where d + 1 = 3 and (a + b) = 4 and c = 2 order by (d + 1) * 4, sin(a / b);
select * from (explain plan actions = 1 select * from tab where d + 1 = 3 and (a + b) = 4 and c = 2 order by (d + 1) * 4, sin(a / b)) where explain ilike '%sort description%';
-- Wrong order with fixed point
select * from tab where (a + b) * c = 8 order by sin(b / a);
select * from (explain plan actions = 1 select * from tab where (a + b) * c = 8 order by sin(b / a)) where explain ilike '%sort description%';
-- Monotonicity
select * from tab order by intDiv((a + b) * c, 2);
select * from (explain plan actions = 1 select * from tab order by intDiv((a + b) * c, 2)) where explain like '%sort description%';
select * from tab order by intDiv((a + b) * c, 2), sin(a / b);
select * from (explain plan actions = 1 select * from tab order by intDiv((a + b) * c, 2), sin(a / b)) where explain like '%sort description%';
-- select * from tab order by (a + b) * c, intDiv(sin(a / b), 2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(sin(a / b), 2)) where explain like '%sort description%';
-- select * from tab order by (a + b) * c desc , intDiv(sin(a / b), 2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc , intDiv(sin(a / b), 2)) where explain like '%sort description%';
-- select * from tab order by (a + b) * c, intDiv(sin(a / b), 2) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(sin(a / b), 2) desc) where explain like '%sort description%';
-- select * from tab order by (a + b) * c desc, intDiv(sin(a / b), 2) desc;
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(sin(a / b), 2) desc) where explain like '%sort description%';
-- select * from tab order by (a + b) * c desc, intDiv(sin(a / b), -2);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(sin(a / b), -2)) where explain like '%sort description%';
-- select * from tab order by (a + b) * c desc, intDiv(intDiv(sin(a / b), -2), -3);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c desc, intDiv(intDiv(sin(a / b), -2), -3)) where explain like '%sort description%';
-- select * from tab order by (a + b) * c, intDiv(intDiv(sin(a / b), -2), -3);
select * from (explain plan actions = 1 select * from tab order by (a + b) * c, intDiv(intDiv(sin(a / b), -2), -3)) where explain like '%sort description%';
-- Aliases
select * from (select *, a + b as x from tab) order by x * c;
select * from (explain plan actions = 1 select * from (select *, a + b as x from tab) order by x * c) where explain like '%sort description%';
select * from (select *, a + b as x, a / b as y from tab) order by x * c, sin(y);
select * from (explain plan actions = 1 select * from (select *, a + b as x, a / b as y from tab) order by x * c, sin(y)) where explain like '%sort description%';
select * from (select *, a / b as y from (select *, a + b as x from tab)) order by x * c, sin(y);
select * from (explain plan actions = 1 select * from (select *, a / b as y from (select *, a + b as x from tab)) order by x * c, sin(y)) where explain like '%sort description%';
-- { echoOff }
create table tab2 (x DateTime, y UInt32, z UInt32) engine = MergeTree order by (x, y);
insert into tab2 select toDate('2020-02-02') + number, number, number from numbers(4);
insert into tab2 select toDate('2020-02-02') + number, number, number from numbers(4);
-- { echoOn }
select * from tab2 order by toTimeZone(toTimezone(x, 'UTC'), 'CET'), intDiv(intDiv(y, -2), -3);
select * from (explain plan actions = 1 select * from tab2 order by toTimeZone(toTimezone(x, 'UTC'), 'CET'), intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
select * from tab2 order by toStartOfDay(x), intDiv(intDiv(y, -2), -3);
select * from (explain plan actions = 1 select * from tab2 order by toStartOfDay(x), intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
-- select * from tab2 where toTimezone(x, 'CET') = '2020-02-03 01:00:00' order by intDiv(intDiv(y, -2), -3);
select * from (explain plan actions = 1 select * from tab2 where toTimezone(x, 'CET') = '2020-02-03 01:00:00' order by intDiv(intDiv(y, -2), -3)) where explain like '%sort description%';
-- { echoOff }
create table tab3 (a UInt32, b UInt32, c UInt32, d UInt32) engine = MergeTree order by ((a + b) * c, sin(a / b));
insert into tab3 select number, number, number, number from numbers(5);
insert into tab3 select number, number, number, number from numbers(5);
create table tab4 (a UInt32, b UInt32, c UInt32, d UInt32) engine = MergeTree order by sin(a / b);
insert into tab4 select number, number, number, number from numbers(5);
insert into tab4 select number, number, number, number from numbers(5);
create table tab5 (a UInt32, b UInt32, c UInt32, d UInt32) engine = MergeTree order by (a + b) * c;
insert into tab5 select number, number, number, number from numbers(5);
insert into tab5 select number, number, number, number from numbers(5);
-- { echoOn }
-- Union (not fully supported)
select * from (select * from tab union all select * from tab3) order by (a + b) * c, sin(a / b);
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab3) order by (a + b) * c, sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
select * from (select * from tab where (a + b) * c = 8 union all select * from tab3 where (a + b) * c = 18) order by sin(a / b);
select * from (explain plan actions = 1 select * from (select * from tab where (a + b) * c = 8 union all select * from tab3 where (a + b) * c = 18) order by sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
select * from (select * from tab where (a + b) * c = 8 union all select * from tab4) order by sin(a / b);
select * from (explain plan actions = 1 select * from (select * from tab where (a + b) * c = 8 union all select * from tab4) order by sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
select * from (select * from tab union all select * from tab5) order by (a + b) * c;
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c) where explain like '%sort description%' or explain like '%ReadType%';
select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b);
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b)) where explain like '%sort description%' or explain like '%ReadType%';
-- Union with limit
select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b) limit 3;
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5) order by (a + b) * c, sin(a / b) limit 3) where explain ilike '%sort description%' or explain like '%ReadType%' or explain like '%Limit%';
-- In this example, we read-in-order from tab up to ((a + b) * c, sin(a / b)) and from tab5 up to ((a + b) * c).
-- In case of tab5, there would be two finish sorting transforms: ((a + b) * c) -> ((a + b) * c, sin(a / b)) -> ((a + b) * c, sin(a / b), d).
-- It's important that ((a + b) * c) -> ((a + b) * c does not have LIMIT. We can add LIMIT WITH TIES later, when sorting alog support it.
-- In case of tab4, we do full sorting by ((a + b) * c, sin(a / b), d) with LIMIT. We can replace it to sorting by ((a + b) * c, sin(a / b)) and LIMIT WITH TIES, when sorting alog support it.
select * from (select * from tab union all select * from tab5 union all select * from tab4) order by (a + b) * c, sin(a / b), d limit 3;
select * from (explain plan actions = 1 select * from (select * from tab union all select * from tab5 union all select * from tab4) order by (a + b) * c, sin(a / b), d limit 3) where explain ilike '%sort description%' or explain like '%ReadType%' or explain like '%Limit%';
drop table if exists tab;
drop table if exists tab2;
drop table if exists tab3;
drop table if exists tab4;
drop table if exists tab5;