diff --git a/query_classifier/qc_sqlite/builtin_functions.c b/query_classifier/qc_sqlite/builtin_functions.c index ad912c63f..af42e1f65 100644 --- a/query_classifier/qc_sqlite/builtin_functions.c +++ b/query_classifier/qc_sqlite/builtin_functions.c @@ -424,6 +424,11 @@ static const char* BUILTIN_10_2_3_FUNCTIONS[] = // "cume_dist", "dense_rank", + "first_value", + "lag", + "last_value", + "lead", + "nth_value", "ntile", "percent_rank", "rank", diff --git a/query_classifier/test/CMakeLists.txt b/query_classifier/test/CMakeLists.txt index d7df9ba38..4d72b4abe 100644 --- a/query_classifier/test/CMakeLists.txt +++ b/query_classifier/test/CMakeLists.txt @@ -53,7 +53,24 @@ if (BUILD_QC_MYSQLEMBEDDED) add_test(TestQC_cte_nonrecursive compare -v 2 ${CMAKE_CURRENT_SOURCE_DIR}/cte_nonrecursive.test) add_test(TestQC_cte_recursive compare -v 2 ${CMAKE_CURRENT_SOURCE_DIR}/cte_recursive.test) - add_test(TestQC_win compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win.test) + add_test(TestQC_win compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win.test) + add_test(TestQC_win_avg compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_avg.test) + add_test(TestQC_win_big-mdev-10092 compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_big-mdev-10092.test) + add_test(TestQC_win_big-mdev-11697 compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_big-mdev-11697.test) + add_test(TestQC_win_big compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_big.test) + add_test(TestQC_win_bit compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_bit.test) + add_test(TestQC_win_empty_over compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_empty_over.test) + add_test(TestQC_win_first_last_value compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_first_last_value.test) + add_test(TestQC_win_i_s compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_i_s.test) + add_test(TestQC_win_lead_lag compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_lead_lag.test) + add_test(TestQC_win_min_max compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_min_max.test) + add_test(TestQC_win_nth_value compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_nth_value.test) + add_test(TestQC_win_ntile compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_ntile.test) + add_test(TestQC_win_orderby compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_orderby.test) + add_test(TestQC_win_percent_cume compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_percent_cume.test) + add_test(TestQC_win_rank compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_rank.test) + add_test(TestQC_win_std compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_std.test) + add_test(TestQC_win_sum compare -v2 ${CMAKE_CURRENT_SOURCE_DIR}/win_sum.test) endif() if(NOT (MYSQL_EMBEDDED_VERSION VERSION_LESS 10.3)) diff --git a/query_classifier/test/qc_sqlite_unsupported.test b/query_classifier/test/qc_sqlite_unsupported.test index 4901dc1d4..5ca58a7ac 100644 --- a/query_classifier/test/qc_sqlite_unsupported.test +++ b/query_classifier/test/qc_sqlite_unsupported.test @@ -126,3 +126,11 @@ with recursive src(counter) as union select counter+1 from src where counter<10 ) select * from src; + +#MXS qc_sqlite +#MXS Statement was classified only based on keywords (Sqlite3 error: SQL logic +#MXS error or missing database, near "(": syntax error): "create view win_view +#MXS as (select a, min(a) over () from t1 where a = 1);" +create view win_view +as (select a, min(a) over () from t1 where a = 1); +select * from win_view; diff --git a/query_classifier/test/win_avg.test b/query_classifier/test/win_avg.test new file mode 100644 index 000000000..23a3652d9 --- /dev/null +++ b/query_classifier/test/win_avg.test @@ -0,0 +1,47 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c real +); + + +insert into t1 values +(101 , 0, 10, 1.1), +(102 , 0, 10, 2.1), +(103 , 1, 10, 3.1), +(104 , 1, 10, 4.1), +(108 , 2, 10, 5.1), +(105 , 2, 20, 6.1), +(106 , 2, 20, 7.1), +(107 , 2, 20, 8.15), +(109 , 4, 20, 9.15), +(110 , 4, 20, 10.15), +(111 , 5, NULL, 11.15), +(112 , 5, 1, 12.25), +(113 , 5, NULL, 13.35), +(114 , 5, NULL, 14.50), +(115 , 5, NULL, 15.65), +(116 , 6, 1, NULL), +(117 , 6, 1, 10), +(118 , 6, 1, 1.1), +(119 , 6, 1, NULL), +(120 , 6, 1, NULL), +(121 , 6, 1, NULL), +(122 , 6, 1, 2.2), +(123 , 6, 1, 20.1), +(124 , 6, 1, -10.4), +(125 , 6, 1, NULL), +(126 , 6, 1, NULL), +(127 , 6, 1, NULL); + + +--sorted_result +select pk, a, b, avg(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) +from t1; + +--sorted_result +select pk, a, c, avg(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) +from t1; + +drop table t1; diff --git a/query_classifier/test/win_big-mdev-10092.test b/query_classifier/test/win_big-mdev-10092.test new file mode 100644 index 000000000..090d43b0b --- /dev/null +++ b/query_classifier/test/win_big-mdev-10092.test @@ -0,0 +1,103 @@ +--echo # +--echo # MDEV-10092: Server crashes in in ha_heap::rnd_pos / Table_read_cursor::get_next +--echo # + +CREATE TABLE `orders` ( + `o_orderkey` int(11) NOT NULL, + `o_custkey` double DEFAULT NULL, + `o_orderstatus` char(1) DEFAULT NULL, + `o_totalprice` double DEFAULT NULL, + `o_orderDATE` date DEFAULT NULL, + `o_orderpriority` char(15) DEFAULT NULL, + `o_clerk` char(15) DEFAULT NULL, + `o_shippriority` int(11) DEFAULT NULL, + `o_comment` varchar(79) DEFAULT NULL, + KEY `i_o_orderdate` (`o_orderDATE`), + KEY `i_o_custkey` (`o_custkey`) +) DEFAULT CHARSET=latin1; + +delimiter //; + +create procedure add_data() +begin +INSERT INTO `orders` VALUES (593793,3220,'O',181553.02,'1996-10-12','5-LOW','Clerk#000000921',0,'carefully unusual instructions are final pl'); +INSERT INTO `orders` VALUES (593794,4681,'F',32306.35,'1994-03-15','2-HIGH','Clerk#000000776',0,'slyly ironic depths are blithely. final excuses across the unusual instruction'); +INSERT INTO `orders` VALUES (593795,7213,'O',206579.47,'1998-03-04','2-HIGH','Clerk#000000746',0,'ruthlessly regular theodolites atop the blith'); +INSERT INTO `orders` VALUES (593796,10486,'F',181299.81,'1993-01-13','3-MEDIUM','Clerk#000000787',0,'special theodolites detect slyly. p'); +INSERT INTO `orders` VALUES (593797,3316,'O',208149.32,'1996-12-22','1-URGENT','Clerk#000000355',0,'carefully silent theodolites use blithely acco'); +INSERT INTO `orders` VALUES (593798,1613,'F',254625.5,'1995-01-26','2-HIGH','Clerk#000000504',0,'fluffily even requests ar'); +INSERT INTO `orders` VALUES (593799,4418,'F',45122.99,'1993-07-12','1-URGENT','Clerk#000000838',0,'blithely ironic ideas boost furiously above the ironic foxes. special pac'); +INSERT INTO `orders` VALUES (593824,12013,'F',216314.23,'1992-02-28','1-URGENT','Clerk#000000074',0,'quickly furious requests play above the fur'); +INSERT INTO `orders` VALUES (593825,8101,'O',123101.26,'1997-01-23','5-LOW','Clerk#000000649',0,'regular deposits haggle after the carefully i'); +INSERT INTO `orders` VALUES (593826,6958,'O',280097.59,'1995-12-14','2-HIGH','Clerk#000000080',0,'slyly even ideas about the slyly pending escapades cajole above th'); +INSERT INTO `orders` VALUES (593827,14116,'O',103011.78,'1995-12-16','3-MEDIUM','Clerk#000000567',0,'blithely bold decoys are furiously. fluffy deposits serve flu'); +INSERT INTO `orders` VALUES (593828,6839,'F',106697.51,'1993-12-11','4-NOT SPECIFIED','Clerk#000000065',0,'carefully final theodolites wake quickly final theodolites! unus'); +INSERT INTO `orders` VALUES (593829,14605,'O',44147.73,'1997-02-18','3-MEDIUM','Clerk#000000474',0,'ironic requests use carefully against the iro'); +INSERT INTO `orders` VALUES (593830,12976,'F',167393.6,'1994-06-21','1-URGENT','Clerk#000000424',0,'dolphins haggle careful'); +INSERT INTO `orders` VALUES (593831,14107,'O',208417.51,'1997-11-18','4-NOT SPECIFIED','Clerk#000000336',0,'furiously express pinto beans after the blithely pending requests need to '); +INSERT INTO `orders` VALUES (593856,5623,'O',143236.09,'1998-03-24','5-LOW','Clerk#000000382',0,'carefully ironic accounts impress slyly according to the ironic'); +INSERT INTO `orders` VALUES (593857,1828,'O',217673.82,'1996-01-12','1-URGENT','Clerk#000000060',0,'special, special pinto beans haggle blithely. blithel'); +INSERT INTO `orders` VALUES (593858,14755,'O',8032.07,'1997-07-20','4-NOT SPECIFIED','Clerk#000000110',0,'regular excuses use ironic pinto '); +INSERT INTO `orders` VALUES (593859,8780,'F',356852.14,'1992-10-09','2-HIGH','Clerk#000000510',0,'furiously regular accounts eat across the carefully '); +INSERT INTO `orders` VALUES (593860,13318,'O',18413.14,'1998-01-10','2-HIGH','Clerk#000000673',0,'pending pains cajole furiously alo'); +INSERT INTO `orders` VALUES (593861,1175,'O',28859.21,'1996-09-10','4-NOT SPECIFIED','Clerk#000000680',0,'carefully silent instructi'); +INSERT INTO `orders` VALUES (593862,7787,'F',202891.72,'1992-02-27','5-LOW','Clerk#000000988',0,'slyly express requests sleep. express dependencies wake bli'); +INSERT INTO `orders` VALUES (593863,1897,'O',33062.05,'1998-06-29','1-URGENT','Clerk#000000117',0,'accounts integrate carefully across the fluffily even warhorses'); +INSERT INTO `orders` VALUES (593888,5656,'O',20952.26,'1997-02-04','3-MEDIUM','Clerk#000000735',0,'requests could have to cajole about the special, final '); +INSERT INTO `orders` VALUES (593889,2692,'F',282718.42,'1992-08-02','4-NOT SPECIFIED','Clerk#000000669',0,'regular deposits haggle fluff'); +INSERT INTO `orders` VALUES (593890,3685,'O',34012.74,'1996-06-17','5-LOW','Clerk#000000993',0,'furiously even requests'); +INSERT INTO `orders` VALUES (593891,10333,'F',182791.4,'1993-01-23','4-NOT SPECIFIED','Clerk#000000098',0,'slyly final platelets doubt'); +INSERT INTO `orders` VALUES (593892,5687,'F',224381.48,'1994-09-18','2-HIGH','Clerk#000000294',0,'blithely bold epitaphs sleep after the carefully express in'); +INSERT INTO `orders` VALUES (593893,5437,'F',124300.91,'1993-08-04','4-NOT SPECIFIED','Clerk#000000302',0,'daring instructions alongside of the si'); +INSERT INTO `orders` VALUES (593894,1732,'F',150438.64,'1993-11-07','3-MEDIUM','Clerk#000000046',0,'quickly special accounts integrate by the even, dogged platelets? slowly '); +INSERT INTO `orders` VALUES (593895,12230,'O',47380.97,'1997-03-23','2-HIGH','Clerk#000000168',0,'fluffily permanent instructions alongside of the furiously even pack'); +INSERT INTO `orders` VALUES (593920,13871,'F',2919.68,'1992-01-29','5-LOW','Clerk#000000597',0,'quickly regular foxes across the furiously bold accounts wake car'); +INSERT INTO `orders` VALUES (593921,6664,'F',139065.79,'1992-04-21','5-LOW','Clerk#000000017',0,'fluffily final deposits are carefully. quickly special pinto beans bel'); +INSERT INTO `orders` VALUES (593922,2504,'O',179041.45,'1997-04-05','2-HIGH','Clerk#000000902',0,'final pinto beans are furiously. '); +INSERT INTO `orders` VALUES (593923,4978,'O',258843,'1998-02-27','1-URGENT','Clerk#000000654',0,'carefully final asymptotes according to the regular dependencie'); +INSERT INTO `orders` VALUES (593924,7550,'O',232280.81,'1995-10-28','3-MEDIUM','Clerk#000000063',0,'fluffily ironic packages haggle carefully pending platelets. q'); +INSERT INTO `orders` VALUES (593925,12226,'O',319755.48,'1995-09-01','3-MEDIUM','Clerk#000000308',0,'quickly pending packages throughout the quickly unusual requests'); +INSERT INTO `orders` VALUES (593926,2819,'F',204662.4,'1994-11-07','4-NOT SPECIFIED','Clerk#000000298',0,'blithely special grouches cajole ironic instructions. slyly pendin'); +INSERT INTO `orders` VALUES (593927,593,'F',188162.64,'1995-03-04','1-URGENT','Clerk#000000263',0,'express, unusual deposits boost furiously after the unusual dolphi'); +INSERT INTO `orders` VALUES (593952,9362,'P',318688.16,'1995-03-05','4-NOT SPECIFIED','Clerk#000000468',0,'ruthless requests must have to are carefully? special pa'); +INSERT INTO `orders` VALUES (593953,11410,'O',166717.28,'1998-07-29','5-LOW','Clerk#000000509',0,'even, regular instructions snooze. slyly ironic packages nag fluffily.'); +INSERT INTO `orders` VALUES (593954,8875,'O',132909.37,'1996-08-29','3-MEDIUM','Clerk#000000825',0,'special decoys integrate carefully. care'); +INSERT INTO `orders` VALUES (593955,12494,'O',73329.07,'1995-08-05','1-URGENT','Clerk#000000561',0,'quickly special request'); +INSERT INTO `orders` VALUES (593956,1390,'O',187837.11,'1995-10-17','5-LOW','Clerk#000000797',0,'silent, pending foxes'); +INSERT INTO `orders` VALUES (593957,10106,'F',196969.46,'1993-04-03','2-HIGH','Clerk#000000566',0,'blithely ruthless excuses boost slyly about the requests. careful'); +INSERT INTO `orders` VALUES (593958,14770,'F',103528.82,'1993-12-27','3-MEDIUM','Clerk#000000598',0,'carefully special deposits eat above the q'); +INSERT INTO `orders` VALUES (593959,14566,'O',156600.32,'1996-11-16','2-HIGH','Clerk#000000030',0,'accounts are quickly bold packages. carefully ironic depos'); +INSERT INTO `orders` VALUES (593984,4924,'O',47149.15,'1995-05-06','3-MEDIUM','Clerk#000000120',0,'regular asymptotes haggle slyly abo'); +INSERT INTO `orders` VALUES (593985,5185,'O',152533.91,'1997-08-04','3-MEDIUM','Clerk#000000575',0,'blithely special dolphins are even requests. carefully eve'); +INSERT INTO `orders` VALUES (593986,14257,'O',109734.28,'1998-06-05','3-MEDIUM','Clerk#000000930',0,'carefully final instructions against the slyly'); +INSERT INTO `orders` VALUES (593987,5818,'F',64541.52,'1994-04-13','3-MEDIUM','Clerk#000000259',0,'slyly pending deposits are furiously. regular requests h'); +INSERT INTO `orders` VALUES (593988,1178,'F',249608.42,'1994-10-01','2-HIGH','Clerk#000000266',0,'fluffily regular foxes toward the furiously bold accounts sleep furiously'); +INSERT INTO `orders` VALUES (593989,5173,'P',61508.55,'1995-03-02','2-HIGH','Clerk#000000374',0,'slyly express deposits wake between '); +INSERT INTO `orders` VALUES (593990,8395,'O',129696.17,'1997-12-30','4-NOT SPECIFIED','Clerk#000000570',0,'carefully final requests haggle furiously fluffily final accou'); +INSERT INTO `orders` VALUES (593991,1894,'O',145691.27,'1998-04-09','5-LOW','Clerk#000000294',0,'slyly final notornis haggle carefull'); +INSERT INTO `orders` VALUES (594016,14935,'F',144592.29,'1992-10-20','3-MEDIUM','Clerk#000000602',0,'furiously express ideas cajole quickl'); +INSERT INTO `orders` VALUES (594017,892,'F',147267.55,'1994-12-10','1-URGENT','Clerk#000000419',0,'close, pending packages affix blithely. slyly regular reque'); +end; +// + +delimiter ;// +call add_data(); +call add_data(); +set sort_buffer_size = 1024; + +flush status; +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey ) from orders; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +flush status; +select o_custkey, Avg(o_custkey) OVER ( ORDER BY o_custkey RANGE CURRENT ROW ) from orders; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +drop table orders; +drop procedure add_data; diff --git a/query_classifier/test/win_big-mdev-11697.test b/query_classifier/test/win_big-mdev-11697.test new file mode 100644 index 000000000..7103b8522 --- /dev/null +++ b/query_classifier/test/win_big-mdev-11697.test @@ -0,0 +1,50 @@ +create table test_table (id int, random_data varchar(36), static_int int, static_varchar varchar(10)); + +insert into test_table(id, random_data, static_int, static_varchar) +select id, random_data, 42, 'Hello' + from ( + with recursive data_generator(id, random_data) as ( + select 1 as id, uuid() as random_data + union all + select id + 1, uuid() from data_generator where id < 1000 + ) + select * from data_generator + ) as a; + +commit; + +analyze table test_table; + +explain select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; + +select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; + +drop table if exists test_table; + +create table test_table (id int, random_data varchar(36), static_int int, static_varchar varchar(10)); + +insert into test_table(id, random_data, static_int, static_varchar) +select id, random_data, 42, 'Hello' + from ( + with recursive data_generator(id, random_data) as ( + select 1 as id, uuid() as random_data + union all + select id + 1, uuid() from data_generator where id < 100000 + ) + select * from data_generator + ) as a; + +commit; + +analyze table test_table; + +explain select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; + +flush status; +select * from (select id, lead(id) over(order by id) next_id from test_table order by id) a limit 10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +drop table test_table; diff --git a/query_classifier/test/win_big.test b/query_classifier/test/win_big.test new file mode 100644 index 000000000..09c8d640b --- /dev/null +++ b/query_classifier/test/win_big.test @@ -0,0 +1,123 @@ +# +# Tests for window functions over big datasets. +# "Big" here is "big enough so that filesort result doesn't fit in a +# memory buffer". +# +# + +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1(a int); +insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C; + +create table t10 (a int, b int, c int); +insert into t10 +select + A.a + 1000*B.a, + A.a + 1000*B.a, + A.a + 1000*B.a +from t1 A, t0 B +order by A.a+1000*B.a; + +--echo ################################################################# +--echo ## Try a basic example +flush status; +create table t21 as +select + sum(b) over (order by a rows between 2 preceding and 2 following) as SUM_B +from + t10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +set sort_buffer_size=1024; +flush status; +create table t22 as +select + sum(b) over (order by a rows between 2 preceding and 2 following) as SUM_B +from + t10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +let $diff_tables= t21, t22; +source include/diff_tables.inc; +drop table t21, t22; + +--echo ################################################################# +--echo # Try many cursors +set sort_buffer_size=default; +flush status; +create table t21 as +select + sum(b) over (order by a rows between 2 preceding and 2 following) as SUM_B1, + sum(b) over (order by a rows between 5 preceding and 5 following) as SUM_B2, + sum(b) over (order by a rows between 20 preceding and 20 following) as SUM_B3 +from + t10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +set sort_buffer_size=1024; +flush status; +create table t22 as +select + sum(b) over (order by a rows between 2 preceding and 2 following) as SUM_B1, + sum(b) over (order by a rows between 5 preceding and 5 following) as SUM_B2, + sum(b) over (order by a rows between 20 preceding and 20 following) as SUM_B3 +from + t10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +let $diff_tables= t21, t22; +source include/diff_tables.inc; +drop table t21, t22; + +--echo ################################################################# +--echo # Try having cursors pointing at different IO_CACHE pages +--echo # in the IO_CACHE +set sort_buffer_size=default; +flush status; +create table t21 as +select + a, + sum(b) over (order by a range between 5000 preceding and 5000 following) as SUM_B1 +from + t10; + +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +set sort_buffer_size=1024; +flush status; +create table t22 as +select + a, + sum(b) over (order by a range between 5000 preceding and 5000 following) as SUM_B1 +from + t10; +select variable_name, + case when variable_value > 0 then 'WITH PASSES' else 'NO PASSES' end +from information_schema.session_status +where variable_name like 'Sort_merge_passes'; + +let $diff_tables= t21, t22; +source include/diff_tables.inc; +drop table t21, t22; +--echo ################################################################# + +drop table t10; +drop table t0,t1; + diff --git a/query_classifier/test/win_bit.test b/query_classifier/test/win_bit.test new file mode 100644 index 000000000..f077d0d67 --- /dev/null +++ b/query_classifier/test/win_bit.test @@ -0,0 +1,89 @@ +create table t1 ( + pk int primary key, + a int, + b int +); + +create table t2 ( + pk int primary key, + a int, + b int +); + + + +insert into t1 values +( 1 , 0, 1), +( 2 , 0, 2), +( 3 , 1, 4), +( 4 , 1, 8), +( 5 , 2, 32), +( 6 , 2, 64), +( 7 , 2, 128), +( 8 , 2, 16); + +insert into t2 values +( 1 , 0, 2), +( 2 , 0, 2), +( 3 , 1, 4), +( 4 , 1, 4), +( 5 , 2, 16), +( 6 , 2, 64), +( 7 , 2, 128), +( 8 , 2, 16); + + + +--echo # Test bit functions on only one partition. +select pk, a, b, + bit_or(b) over (order by pk) as bit_or, + bit_and(b) over (order by pk) as bit_and, + bit_xor(b) over (order by pk) as bit_xor +from t1; + +select pk, a, b, + bit_or(b) over (order by pk) as bit_or, + bit_and(b) over (order by pk) as bit_and, + bit_xor(b) over (order by pk) as bit_xor +from t2; + +--echo # Test multiple partitions with bit functions. +select pk, a, b, + bit_or(b) over (partition by a order by pk) as bit_or, + bit_and(b) over (partition by a order by pk) as bit_and, + bit_xor(b) over (partition by a order by pk) as bit_xor +from t1; + +select pk, a, b, + bit_or(b) over (partition by a order by pk) as bit_or, + bit_and(b) over (partition by a order by pk) as bit_and, + bit_xor(b) over (partition by a order by pk) as bit_xor +from t2; + +--echo # Test remove function for bit functions using a sliding window. +select pk, a, b, + bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as bit_or, + bit_and(b) over (partition by a order by pk) as bit_and, + bit_xor(b) over (partition by a order by pk) as bit_xor +from t1; + +select pk, a, b, + bit_or(b) over (partition by a order by pk) as bit_or, + bit_and(b) over (partition by a order by pk) as bit_and, + bit_xor(b) over (partition by a order by pk) as bit_xor +from t2; + + + + + + + +#select pk, a, b, bit_or(b) over (order by a) as count from t1 order by a, pk; +#select pk, a, b, bit_and(b) over (order by a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as count from t1 order by a, pk; +#select pk, a, b, bit_xor(b) over (order by a, pk ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as count from t2 order by pk; +#select pk, a, b, bit_or(b) over (order by a, pk ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as count from t2 order by pk; +#select pk, a, b, bit_and(b) over (order by a, pk ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as count from t3 order by pk; + +drop table t1; +drop table t2; diff --git a/query_classifier/test/win_empty_over.test b/query_classifier/test/win_empty_over.test new file mode 100644 index 000000000..5f374d262 --- /dev/null +++ b/query_classifier/test/win_empty_over.test @@ -0,0 +1,71 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c char(10), + d decimal(10, 3), + e real +); + +insert into t1 values +( 1, 0, 1, 'one', 0.1, 0.001), +( 2, 0, 2, 'two', 0.2, 0.002), +( 3, 0, 3, 'three', 0.3, 0.003), +( 4, 1, 2, 'three', 0.4, 0.004), +( 5, 1, 1, 'two', 0.5, 0.005), +( 6, 1, 1, 'one', 0.6, 0.006), +( 7, 2, NULL, 'n_one', 0.5, 0.007), +( 8, 2, 1, 'n_two', NULL, 0.008), +( 9, 2, 2, NULL, 0.7, 0.009), +(10, 2, 0, 'n_four', 0.8, 0.010), +(11, 2, 10, NULL, 0.9, NULL); + +select pk, row_number() over () from t1; +explain FORMAT=JSON select pk, row_number() over () from t1; +explain FORMAT=JSON select row_number() over (), pk from t1; + +select row_number() over () from (select 4) as t; + +--sorted_result +select min(a) over (), max(a) over (), a, row_number() over () +from t1 +where a = 0; + +--sorted_result +select a, min(a) over (), max(a) over (), row_number() over () +from t1 +where a = 0; + +--sorted_result +select min(a) over () + 1, max(a) over (), row_number() over () +from t1 +where a = 0; + +--sorted_result +select min(a) over () + a, max(a) over (), row_number() over () +from t1 +where a = 1; + +--sorted_result +select a + min(a) over (), max(a) over (), row_number() over () +from t1 +where a = 1; + +select a + min(a) over () from t1 where a = 1; + +#MXS qc_sqlite +#MXS Statement was classified only based on keywords (Sqlite3 error: SQL logic +#MXS error or missing database, near "(": syntax error): "create view win_view +#MXS as (select a, min(a) over () from t1 where a = 1);" +# +#MXS create view win_view +#MXS as (select a, min(a) over () from t1 where a = 1); +#MXS select * from win_view; +drop view win_view; + +#MXS create view win_view +#MXS as (select a, max(a + 1) over () from t1 where a = 1); +#MXS select * from win_view; +drop view win_view; + +drop table t1; diff --git a/query_classifier/test/win_first_last_value.test b/query_classifier/test/win_first_last_value.test new file mode 100644 index 000000000..0a90a98a5 --- /dev/null +++ b/query_classifier/test/win_first_last_value.test @@ -0,0 +1,87 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c char(10), + d decimal(10, 3), + e real +); + +insert into t1 values +( 1, 0, 1, 'one', 0.1, 0.001), +( 2, 0, 2, 'two', 0.2, 0.002), +( 3, 0, 3, 'three', 0.3, 0.003), +( 4, 1, 2, 'three', 0.4, 0.004), +( 5, 1, 1, 'two', 0.5, 0.005), +( 6, 1, 1, 'one', 0.6, 0.006), +( 7, 2, NULL, 'n_one', 0.5, 0.007), +( 8, 2, 1, 'n_two', NULL, 0.008), +( 9, 2, 2, NULL, 0.7, 0.009), +(10, 2, 0, 'n_four', 0.8, 0.010), +(11, 2, 10, NULL, 0.9, NULL); + +select pk, first_value(pk) over (order by pk), + last_value(pk) over (order by pk), + first_value(pk) over (order by pk desc), + last_value(pk) over (order by pk desc) +from t1 +order by pk desc; + +select pk, + first_value(pk) over (order by pk + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + last_value(pk) over (order by pk + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + first_value(pk) over (order by pk desc + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + last_value(pk) over (order by pk desc + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +from t1 +order by pk; + +select pk, + first_value(pk) over (order by pk desc), + last_value(pk) over (order by pk desc) +from t1; + +select pk, a, b, c, d, e, + first_value(b) over (partition by a order by pk) as fst_b, + last_value(b) over (partition by a order by pk) as lst_b, + first_value(c) over (partition by a order by pk) as fst_c, + last_value(c) over (partition by a order by pk) as lst_c, + first_value(d) over (partition by a order by pk) as fst_d, + last_value(d) over (partition by a order by pk) as lst_d, + first_value(e) over (partition by a order by pk) as fst_e, + last_value(e) over (partition by a order by pk) as lst_e +from t1; + +drop table t1; + +--echo # +--echo # MDEV-11746: Wrong result upon using FIRST_VALUE with a window frame +--echo # +create table t1 (i int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); + +select i, + first_value(i) OVER (order by i rows between CURRENT ROW and 1 FOLLOWING) as fst_1f, + last_value(i) OVER (order by i rows between CURRENT ROW and 1 FOLLOWING) as last_1f, + first_value(i) OVER (order by i rows between 1 PRECEDING AND 1 FOLLOWING) as fst_1p1f, + last_value(i) OVER (order by i rows between 1 PRECEDING AND 1 FOLLOWING) as fst_1p1f, + first_value(i) OVER (order by i rows between 2 PRECEDING AND 1 PRECEDING) as fst_2p1p, + last_value(i) OVER (order by i rows between 2 PRECEDING AND 1 PRECEDING) as fst_2p1p, + first_value(i) OVER (order by i rows between 1 FOLLOWING AND 2 FOLLOWING) as fst_1f2f, + last_value(i) OVER (order by i rows between 1 FOLLOWING AND 2 FOLLOWING) as fst_1f2f +from t1; + +drop table t1; + +--echo # +--echo # MDEV-12861 FIRST_VALUE() does not preserve the exact data type +--echo # + +CREATE TABLE t1 (a INT, b INT, c FLOAT); +INSERT INTO t1 VALUES (1,1,1),(1,2,2),(2,1,1),(2,2,2); +CREATE TABLE t2 AS SELECT a, FIRST_VALUE(b) OVER(), FIRST_VALUE(c) OVER() FROM t1 GROUP BY a; +SHOW CREATE TABLE t2; +DROP TABLE t2,t1; diff --git a/query_classifier/test/win_i_s.test b/query_classifier/test/win_i_s.test new file mode 100644 index 000000000..d9b0f1902 --- /dev/null +++ b/query_classifier/test/win_i_s.test @@ -0,0 +1,18 @@ +show status like '%window%'; + +create table t1 (a int, b int); +insert into t1 values (1, 10), (2, 20), (3, 30); + +select a, b, rank() over (order by a) from t1; +show status like '%window%'; + +select a, b, rank() over (order by a), sum(a) over (order by a) from t1; +show status like '%window%'; + +--sorted_result +select t_a.r1, t_b.r2 +from (select a, b, rank() over (order by a) as r1 from t1) t_a, + (select a, b, row_number() over (order by a) as r2 from t1) t_b; +show status like '%window%'; + +drop table t1; diff --git a/query_classifier/test/win_lead_lag.test b/query_classifier/test/win_lead_lag.test new file mode 100644 index 000000000..2824f8378 --- /dev/null +++ b/query_classifier/test/win_lead_lag.test @@ -0,0 +1,110 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c char(10), + d decimal(10, 3), + e real +); + +insert into t1 values +( 1, 0, 1, 'one', 0.1, 0.001), +( 2, 0, 2, 'two', 0.2, 0.002), +( 3, 0, 3, 'three', 0.3, 0.003), +( 4, 1, 2, 'three', 0.4, 0.004), +( 5, 1, 1, 'two', 0.5, 0.005), +( 6, 1, 1, 'one', 0.6, 0.006), +( 7, 2, NULL, 'n_one', 0.5, 0.007), +( 8, 2, 1, 'n_two', NULL, 0.008), +( 9, 2, 2, NULL, 0.7, 0.009), +(10, 2, 0, 'n_four', 0.8, 0.010), +(11, 2, 10, NULL, 0.9, NULL); + +select pk, + lead(pk) over (order by pk), + lead(pk, 1) over (order by pk), + lead(pk, 2) over (order by pk), + lead(pk, 0) over (order by pk), + lead(pk, -1) over (order by pk), + lead(pk, -2) over (order by pk) +from t1 +order by pk asc; + +select pk, + lag(pk) over (order by pk), + lag(pk, 1) over (order by pk), + lag(pk, 2) over (order by pk), + lag(pk, 0) over (order by pk), + lag(pk, -1) over (order by pk), + lag(pk, -2) over (order by pk) +from t1 +order by pk asc; + +select pk, pk - 2, + lag(pk, pk - 2) over (order by pk), + lead(pk, pk - 2) over (order by pk) +from t1 +order by pk asc; + +select pk, pk - 2, + lag(pk, pk + 2) over (order by pk), + lead(pk, pk + 2) over (order by pk) +from t1 +order by pk asc; + +select pk, a, + lead(pk) over (partition by a order by pk), + lead(pk, 1) over (partition by a order by pk), + lead(pk, 2) over (partition by a order by pk), + lead(pk, 0) over (partition by a order by pk), + lead(pk, -1) over (partition by a order by pk), + lead(pk, -2) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, + lag(pk) over (partition by a order by pk), + lag(pk, 1) over (partition by a order by pk), + lag(pk, 2) over (partition by a order by pk), + lag(pk, 0) over (partition by a order by pk), + lag(pk, -1) over (partition by a order by pk), + lag(pk, -2) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, pk - 2, + lag(pk, pk - 2) over (partition by a order by pk), + lead(pk, pk - 2) over (partition by a order by pk), + lag(pk, a - 2) over (partition by a order by pk), + lead(pk, a - 2) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, pk - 2, + lag(pk, pk + 2) over (partition by a order by pk), + lead(pk, pk + 2) over (partition by a order by pk), + lag(pk, a + 2) over (partition by a order by pk), + lead(pk, a + 2) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, b, c, d, e, + lag(a) over (partition by a order by pk), + lag(b) over (partition by a order by pk), + lag(c) over (partition by a order by pk), + lag(d) over (partition by a order by pk), + lag(e) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, b, a+b, + lag(a + b) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, a, b, a+b, + lag(a + b) over (partition by a order by pk) + pk +from t1 +order by pk asc; + +drop table t1; diff --git a/query_classifier/test/win_min_max.test b/query_classifier/test/win_min_max.test new file mode 100644 index 000000000..8efde87ff --- /dev/null +++ b/query_classifier/test/win_min_max.test @@ -0,0 +1,370 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c real +); + + +insert into t1 values +(101 , 0, 10, 1.1), +(102 , 0, 10, 2.1), +(103 , 1, 10, 3.1), +(104 , 1, 10, 4.1), +(108 , 2, 10, 5.1), +(105 , 2, 20, 6.1), +(106 , 2, 20, 7.1), +(107 , 2, 20, 8.15), +(109 , 4, 20, 9.15), +(110 , 4, 20, 10.15), +(111 , 5, NULL, 11.15), +(112 , 5, 1, 12.25), +(113 , 5, NULL, 13.35), +(114 , 5, NULL, 14.50), +(115 , 5, NULL, 15.65), +(116 , 6, 1, NULL), +(117 , 6, 1, 10), +(118 , 6, 1, 1.1), +(119 , 6, 1, NULL), +(120 , 6, 1, NULL), +(121 , 6, 1, NULL), +(122 , 6, 1, 2.2), +(123 , 6, 1, 20.1), +(124 , 6, 1, -10.4), +(125 , 6, 1, NULL), +(126 , 6, 1, NULL), +(127 , 6, 1, NULL); + + +--sorted_result +select pk, a, b, min(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as min, + max(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as max +from t1; + +--sorted_result +select pk, a, c, min(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as min, + max(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as max +from t1; + +create table t2 ( + pk int primary key, + a int, + b int, + c char(10) +); + +insert into t2 values +( 1, 0, 1, 'one'), +( 2, 0, 2, 'two'), +( 3, 0, 3, 'three'), +( 4, 1, 20, 'four'), +( 5, 1, 10, 'five'), +( 6, 1, 40, 'six'), +( 7, 1, 30, 'seven'), +( 8, 4,300, 'eight'), +( 9, 4,100, 'nine'), +(10, 4,200, 'ten'), +(11, 4,200, 'eleven'); + +--echo # First try some invalid argument queries. +select pk, a, b, c, + min(c) over (order by pk), + max(c) over (order by pk), + min(c) over (partition by a order by pk), + max(c) over (partition by a order by pk) +from t2; + + + +--echo # Empty frame + +select pk, a, b, c, + min(b) over (order by pk rows between 2 following and 1 following) as min1, + max(b) over (order by pk rows between 2 following and 1 following) as max1, + min(b) over (partition by a order by pk rows between 2 following and 1 following) as min2, + max(b) over (partition by a order by pk rows between 2 following and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 2 following and 1 following) as min1, + max(b) over (order by pk range between 2 following and 1 following) as max1, + min(b) over (partition by a order by pk range between 2 following and 1 following) as min2, + max(b) over (partition by a order by pk range between 2 following and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 preceding and 2 preceding) as min1, + max(b) over (order by pk rows between 1 preceding and 2 preceding) as max1, + min(b) over (partition by a order by pk rows between 1 preceding and 2 preceding) as min2, + max(b) over (partition by a order by pk rows between 1 preceding and 2 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 preceding and 2 preceding) as min1, + max(b) over (order by pk range between 1 preceding and 2 preceding) as max1, + min(b) over (partition by a order by pk range between 1 preceding and 2 preceding) as min2, + max(b) over (partition by a order by pk range between 1 preceding and 2 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 following and 0 following) as min1, + max(b) over (order by pk rows between 1 following and 0 following) as max1, + min(b) over (partition by a order by pk rows between 1 following and 0 following) as min2, + max(b) over (partition by a order by pk rows between 1 following and 0 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 following and 0 following) as min1, + max(b) over (order by pk range between 1 following and 0 following) as max1, + min(b) over (partition by a order by pk range between 1 following and 0 following) as min2, + max(b) over (partition by a order by pk range between 1 following and 0 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 following and 0 preceding) as min1, + max(b) over (order by pk rows between 1 following and 0 preceding) as max1, + min(b) over (partition by a order by pk rows between 1 following and 0 preceding) as min2, + max(b) over (partition by a order by pk rows between 1 following and 0 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 following and 0 preceding) as min1, + max(b) over (order by pk range between 1 following and 0 preceding) as max1, + min(b) over (partition by a order by pk range between 1 following and 0 preceding) as min2, + max(b) over (partition by a order by pk range between 1 following and 0 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 0 following and 1 preceding) as min1, + max(b) over (order by pk rows between 0 following and 1 preceding) as max1, + min(b) over (partition by a order by pk rows between 0 following and 1 preceding) as min2, + max(b) over (partition by a order by pk rows between 0 following and 1 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 0 following and 1 preceding) as min1, + max(b) over (order by pk range between 0 following and 1 preceding) as max1, + min(b) over (partition by a order by pk range between 0 following and 1 preceding) as min2, + max(b) over (partition by a order by pk range between 0 following and 1 preceding) as max2 +from t2; + +--echo # 1 row frame. +select pk, a, b, c, + min(b) over (order by pk rows between current row and current row) as min1, + max(b) over (order by pk rows between current row and current row) as max1, + min(b) over (partition by a order by pk rows between current row and current row) as min2, + max(b) over (partition by a order by pk rows between current row and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 0 preceding and current row) as min1, + max(b) over (order by pk rows between 0 preceding and current row) as max1, + min(b) over (partition by a order by pk rows between 0 preceding and current row) as min2, + max(b) over (partition by a order by pk rows between 0 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 0 preceding and 0 preceding) as min1, + max(b) over (order by pk rows between 0 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk rows between 0 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk rows between 0 preceding and 0 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 preceding and 1 preceding) as min1, + max(b) over (order by pk rows between 1 preceding and 1 preceding) as max1, + min(b) over (partition by a order by pk rows between 1 preceding and 1 preceding) as min2, + max(b) over (partition by a order by pk rows between 1 preceding and 1 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 following and 1 following) as min1, + max(b) over (order by pk rows between 1 following and 1 following) as max1, + min(b) over (partition by a order by pk rows between 1 following and 1 following) as min2, + max(b) over (partition by a order by pk rows between 1 following and 1 following) as max2 +from t2; + +--echo # Try a larger offset. +select pk, a, b, c, + min(b) over (order by pk rows between 3 following and 3 following) as min1, + max(b) over (order by pk rows between 3 following and 3 following) as max1, + min(b) over (partition by a order by pk rows between 3 following and 3 following) as min2, + max(b) over (partition by a order by pk rows between 3 following and 3 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 3 preceding and 3 preceding) as min1, + max(b) over (order by pk rows between 3 preceding and 3 preceding) as max1, + min(b) over (partition by a order by pk rows between 3 preceding and 3 preceding) as min2, + max(b) over (partition by a order by pk rows between 3 preceding and 3 preceding) as max2 +from t2; + +--echo # 2 row frame. +select pk, a, b, c, + min(b) over (order by pk rows between current row and 1 following) as min1, + max(b) over (order by pk rows between current row and 1 following) as max1, + min(b) over (partition by a order by pk rows between current row and 1 following) as min2, + max(b) over (partition by a order by pk rows between current row and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 0 preceding and 1 following) as min1, + max(b) over (order by pk rows between 0 preceding and 1 following) as max1, + min(b) over (partition by a order by pk rows between 0 preceding and 1 following) as min2, + max(b) over (partition by a order by pk rows between 0 preceding and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 preceding and current row) as min1, + max(b) over (order by pk rows between 1 preceding and current row) as max1, + min(b) over (partition by a order by pk rows between 1 preceding and current row) as min2, + max(b) over (partition by a order by pk rows between 1 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 1 preceding and 0 preceding) as min1, + max(b) over (order by pk rows between 1 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk rows between 1 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk rows between 1 preceding and 0 preceding) as max2 +from t2; + +--echo # Try a larger frame/offset. +select pk, a, b, c, + min(b) over (order by pk rows between current row and 3 following) as min1, + max(b) over (order by pk rows between current row and 3 following) as max1, + min(b) over (partition by a order by pk rows between current row and 3 following) as min2, + max(b) over (partition by a order by pk rows between current row and 3 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 2 preceding and 1 following) as min1, + max(b) over (order by pk rows between 2 preceding and 1 following) as max1, + min(b) over (partition by a order by pk rows between 2 preceding and 1 following) as min2, + max(b) over (partition by a order by pk rows between 2 preceding and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 3 preceding and current row) as min1, + max(b) over (order by pk rows between 3 preceding and current row) as max1, + min(b) over (partition by a order by pk rows between 3 preceding and current row) as min2, + max(b) over (partition by a order by pk rows between 3 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk rows between 3 preceding and 0 preceding) as min1, + max(b) over (order by pk rows between 3 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk rows between 3 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk rows between 3 preceding and 0 preceding) as max2 +from t2; + +--echo # Check range frame bounds +select pk, a, b, c, + min(b) over (order by pk range between current row and current row) as min1, + max(b) over (order by pk range between current row and current row) as max1, + min(b) over (partition by a order by pk range between current row and current row) as min2, + max(b) over (partition by a order by pk range between current row and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 0 preceding and current row) as min1, + max(b) over (order by pk range between 0 preceding and current row) as max1, + min(b) over (partition by a order by pk range between 0 preceding and current row) as min2, + max(b) over (partition by a order by pk range between 0 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 0 preceding and 0 preceding) as min1, + max(b) over (order by pk range between 0 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk range between 0 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk range between 0 preceding and 0 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 preceding and 1 preceding) as min1, + max(b) over (order by pk range between 1 preceding and 1 preceding) as max1, + min(b) over (partition by a order by pk range between 1 preceding and 1 preceding) as min2, + max(b) over (partition by a order by pk range between 1 preceding and 1 preceding) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 following and 1 following) as min1, + max(b) over (order by pk range between 1 following and 1 following) as max1, + min(b) over (partition by a order by pk range between 1 following and 1 following) as min2, + max(b) over (partition by a order by pk range between 1 following and 1 following) as max2 +from t2; + +--echo # Try a larger offset. +select pk, a, b, c, + min(b) over (order by pk range between 3 following and 3 following) as min1, + max(b) over (order by pk range between 3 following and 3 following) as max1, + min(b) over (partition by a order by pk range between 3 following and 3 following) as min2, + max(b) over (partition by a order by pk range between 3 following and 3 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 3 preceding and 3 preceding) as min1, + max(b) over (order by pk range between 3 preceding and 3 preceding) as max1, + min(b) over (partition by a order by pk range between 3 preceding and 3 preceding) as min2, + max(b) over (partition by a order by pk range between 3 preceding and 3 preceding) as max2 +from t2; + +--echo # 2 row frame. +select pk, a, b, c, + min(b) over (order by pk range between current row and 1 following) as min1, + max(b) over (order by pk range between current row and 1 following) as max1, + min(b) over (partition by a order by pk range between current row and 1 following) as min2, + max(b) over (partition by a order by pk range between current row and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 0 preceding and 1 following) as min1, + max(b) over (order by pk range between 0 preceding and 1 following) as max1, + min(b) over (partition by a order by pk range between 0 preceding and 1 following) as min2, + max(b) over (partition by a order by pk range between 0 preceding and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 preceding and current row) as min1, + max(b) over (order by pk range between 1 preceding and current row) as max1, + min(b) over (partition by a order by pk range between 1 preceding and current row) as min2, + max(b) over (partition by a order by pk range between 1 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 1 preceding and 0 preceding) as min1, + max(b) over (order by pk range between 1 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk range between 1 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk range between 1 preceding and 0 preceding) as max2 +from t2; + +--echo # Try a larger frame/offset. +select pk, a, b, c, + min(b) over (order by pk range between current row and 3 following) as min1, + max(b) over (order by pk range between current row and 3 following) as max1, + min(b) over (partition by a order by pk range between current row and 3 following) as min2, + max(b) over (partition by a order by pk range between current row and 3 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 2 preceding and 1 following) as min1, + max(b) over (order by pk range between 2 preceding and 1 following) as max1, + min(b) over (partition by a order by pk range between 2 preceding and 1 following) as min2, + max(b) over (partition by a order by pk range between 2 preceding and 1 following) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 3 preceding and current row) as min1, + max(b) over (order by pk range between 3 preceding and current row) as max1, + min(b) over (partition by a order by pk range between 3 preceding and current row) as min2, + max(b) over (partition by a order by pk range between 3 preceding and current row) as max2 +from t2; + +select pk, a, b, c, + min(b) over (order by pk range between 3 preceding and 0 preceding) as min1, + max(b) over (order by pk range between 3 preceding and 0 preceding) as max1, + min(b) over (partition by a order by pk range between 3 preceding and 0 preceding) as min2, + max(b) over (partition by a order by pk range between 3 preceding and 0 preceding) as max2 +from t2; + +drop table t2; +drop table t1; diff --git a/query_classifier/test/win_nth_value.test b/query_classifier/test/win_nth_value.test new file mode 100644 index 000000000..b9764d1e9 --- /dev/null +++ b/query_classifier/test/win_nth_value.test @@ -0,0 +1,67 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c char(10), + d decimal(10, 3), + e real +); + +insert into t1 values +( 1, 0, 1, 'one', 0.1, 0.001), +( 2, 0, 2, 'two', 0.2, 0.002), +( 3, 0, 3, 'three', 0.3, 0.003), +( 4, 1, 2, 'three', 0.4, 0.004), +( 5, 1, 1, 'two', 0.5, 0.005), +( 6, 1, 1, 'one', 0.6, 0.006), +( 7, 2, NULL, 'n_one', 0.5, 0.007), +( 8, 2, 1, 'n_two', NULL, 0.008), +( 9, 2, 2, NULL, 0.7, 0.009), +(10, 2, 0, 'n_four', 0.8, 0.010), +(11, 2, 10, NULL, 0.9, NULL); + +select pk, + nth_value(pk, 1) over (order by pk), + nth_value(pk, 2) over (order by pk), + nth_value(pk, 0) over (order by pk), + nth_value(pk, -1) over (order by pk), + nth_value(pk, -2) over (order by pk) +from t1 +order by pk asc; + +select pk, + nth_value(pk, pk) over (order by pk), + nth_value(pk / 0.1, pk) over (order by pk) +from t1 +order by pk asc; + +select pk, + a, + nth_value(pk, pk) over (partition by a order by pk), + nth_value(pk, a + 1) over (partition by a order by pk) +from t1 +order by pk asc; + +select pk, + a, + nth_value(pk, 1) over (partition by a order by pk ROWS between 1 preceding and 1 following) +from t1; + +select pk, + a, + nth_value(a, 1) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 2) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 3) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 4) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 5) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 6) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 7) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 8) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 9) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 10) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 11) over (order by a RANGE BETWEEN 1 preceding and 1 following), + nth_value(a, 12) over (order by a RANGE BETWEEN 1 preceding and 1 following) +from t1 +order by pk asc; + +drop table t1; diff --git a/query_classifier/test/win_ntile.test b/query_classifier/test/win_ntile.test new file mode 100644 index 000000000..6f12e1f40 --- /dev/null +++ b/query_classifier/test/win_ntile.test @@ -0,0 +1,171 @@ +create table t1 ( + pk int primary key, + a int, + b int +); + + +insert into t1 values +(11 , 0, 10), +(12 , 0, 10), +(13 , 1, 10), +(14 , 1, 10), +(18 , 2, 10), +(15 , 2, 20), +(16 , 2, 20), +(17 , 2, 20), +(19 , 4, 20), +(20 , 4, 20); + +# TODO Try invalid queries too. + +--error ER_INVALID_NTILE_ARGUMENT +select pk, a, b, ntile(-1) over (order by a) +from t1; + +--error ER_INVALID_NTILE_ARGUMENT +select pk, a, b, + ntile(0) over (order by a) +from t1; + +--sorted_result +select pk, a, b, + ntile(1) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(2) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(3) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(4) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(5) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(6) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(7) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(8) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(9) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(10) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(11) over (order by pk) +from t1; + +--sorted_result +select pk, a, b, + ntile(20) over (order by pk) +from t1; + + +select pk, a, b, + ntile(1) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(2) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(3) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(4) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(5) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(6) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(7) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(8) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(9) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(10) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(11) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(20) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile(1 + 3) over (partition by b order by pk) +from t1; + +select pk, a, b, + ntile((select 4)) over (partition by b order by pk) +from t1; + +select t1.a from t1 where pk = 11; +--error ER_INVALID_NTILE_ARGUMENT +select pk, a, b, + ntile((select a from t1 where pk=11)) over (partition by b order by pk) +from t1; + +select t1.a from t1 where pk = 13; +select pk, a, b, + ntile((select a from t1 where pk=13)) over (partition by b order by pk) +from t1; + +explain +select pk, a, b, + ntile((select a from t1 where pk=13)) over (partition by b order by pk) +from t1; + +select a from t1; +--error ER_SUBQUERY_NO_1_ROW +select pk, a, b, + ntile((select a from t1)) over (partition by b order by pk) +from t1; + + +drop table t1; diff --git a/query_classifier/test/win_orderby.test b/query_classifier/test/win_orderby.test new file mode 100644 index 000000000..0d42c6064 --- /dev/null +++ b/query_classifier/test/win_orderby.test @@ -0,0 +1,32 @@ +# +# Tests for window functions and ORDER BY +# + +--disable_warnings +drop table if exists t0,t1; +--enable_warnings + +create table t0(a int primary key); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1( + pk int, + a int, + key(pk) +); + +insert into t1 +select + A.a + B.a* 10 + C.a * 100, + 1 +from t0 A, t0 B, t0 C; + +select + pk, + count(a) over (order by pk rows between 2 preceding and 2 following) +from t1 +where pk between 1 and 30 +order by pk desc +limit 4; + +drop table t0,t1; diff --git a/query_classifier/test/win_percent_cume.test b/query_classifier/test/win_percent_cume.test new file mode 100644 index 000000000..b851185cb --- /dev/null +++ b/query_classifier/test/win_percent_cume.test @@ -0,0 +1,36 @@ +create table t1 ( + pk int primary key, + a int, + b int +); + + +insert into t1 values +( 1 , 0, 10), +( 2 , 0, 10), +( 3 , 1, 10), +( 4 , 1, 10), +( 8 , 2, 10), +( 5 , 2, 20), +( 6 , 2, 20), +( 7 , 2, 20), +( 9 , 4, 20), +(10 , 4, 20); + +select pk, a, b, + percent_rank() over (order by a), + cume_dist() over (order by a) +from t1; + +select pk, a, b, + percent_rank() over (order by pk), + cume_dist() over (order by pk) +from t1 order by pk; + +select pk, a, b, + percent_rank() over (partition by a order by a), + cume_dist() over (partition by a order by a) +from t1; + +drop table t1; + diff --git a/query_classifier/test/win_rank.test b/query_classifier/test/win_rank.test new file mode 100644 index 000000000..eda1f4582 --- /dev/null +++ b/query_classifier/test/win_rank.test @@ -0,0 +1,58 @@ +--echo # +--echo # Try DENSE_RANK() function +--echo # + +create table t1 ( + pk int primary key, + a int, + b int +); + +insert into t1 values +( 1 , 0, 10), +( 2 , 0, 10), +( 3 , 1, 10), +( 4 , 1, 10), +( 8 , 2, 10), +( 5 , 2, 20), +( 6 , 2, 20), +( 7 , 2, 20), +( 9 , 4, 20), +(10 , 4, 20); + +select pk, a, b, rank() over (order by a) as rank, + dense_rank() over (order by a) as dense_rank +from t1; +select pk, a, b, rank() over (partition by b order by a) as rank, + dense_rank() over (partition by b order by a) as dense_rank +from t1; + +drop table t1; + +--echo # +--echo # Test with null values in the table. +--echo # + +create table t2 (s1 int, s2 char(5)); +insert into t2 values (1,'a'); +insert into t2 values (null,null); +insert into t2 values (1,null); +insert into t2 values (null,'a'); +insert into t2 values (null,'c'); +insert into t2 values (2,'b'); +insert into t2 values (-1,''); + +select *, rank() over (order by s1) as rank, + dense_rank() over (order by s1) as dense_rank +from t2; +select *, rank() over (partition by s2 order by s1) as rank, + dense_rank() over (partition by s2 order by s1) as dense_rank +from t2; +select *, rank() over (order by s2) as rank, + dense_rank() over (order by s2) as dense_rank +from t2; +select *, rank() over (partition by s1 order by s2) as rank, + dense_rank() over (partition by s1 order by s2) as dense_rank +from t2; + +drop table t2; diff --git a/query_classifier/test/win_std.test b/query_classifier/test/win_std.test new file mode 100644 index 000000000..5ed999431 --- /dev/null +++ b/query_classifier/test/win_std.test @@ -0,0 +1,136 @@ +create table t1 ( + pk int primary key, + a int, + b int +); + +create table t2 ( + pk int primary key, + a int, + b int, + c char(10) +); + +insert into t2 values +( 1, 0, 1, 'one'), +( 2, 0, 2, 'two'), +( 3, 0, 3, 'three'), +( 4, 1, 1, 'one'), +( 5, 1, 1, 'two'), +( 6, 1, 2, 'three'); + +--disable_warnings +--echo # First try some invalid queries. +select std(c) over (order by a) +from t2; +--enable_warnings + +--echo # Empty frame. +select std(b) over (order by a rows between 2 following and 1 following) +from t2; + +select std(b) over (order by a range between 2 following and 1 following) +from t2; + +select std(b) over (order by a rows between 1 preceding and 2 preceding) +from t2; + +select std(b) over (order by a range between 1 preceding and 2 preceding) +from t2; + +select std(b) over (order by a rows between 1 following and 0 following) +from t2; + +select std(b) over (order by a range between 1 following and 0 following) +from t2; + +select std(b) over (order by a rows between 1 following and 0 preceding) +from t2; + +select std(b) over (order by a range between 1 following and 0 preceding) +from t2; + +select std(b) over (order by a rows between 0 following and 1 preceding) +from t2; + +select std(b) over (order by a range between 0 following and 1 preceding) +from t2; + +--echo # 1 row frame. +select std(b) over (order by a rows between current row and current row) +from t2; + +select std(b) over (order by a rows between 0 preceding and current row) +from t2; + +select std(b) over (order by a rows between 0 preceding and 0 preceding) +from t2; + +select std(b) over (order by a rows between 0 preceding and 0 following) +from t2; + +select std(b) over (order by a rows between 0 following and 0 preceding) +from t2; + +--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS +select std(b) over (order by a rows between 0 following and current row) +from t2; + +select std(b) over (order by a rows between current row and 0 following) +from t2; + +--echo # Only peers frame. +select a, b, std(b) over (order by a range between 0 preceding and 0 preceding) +from t2; + +select a, b, std(b) over (order by a range between 0 preceding and current row) +from t2; + +--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS +select a, b, std(b) over (order by a range between current row and 0 preceding) +from t2; + +select a, b, std(b) over (order by a range between current row and 0 following) +from t2; + +select a, b, std(b) over (order by a range between 0 following and 0 following) +from t2; + +--echo # 2 rows frame. + +--sorted_result +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and current row) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a, b, pk rows between 1 preceding and 0 preceding) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a, b, pk rows between current row and 1 following) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a, b, pk rows between 0 following and 1 following) +from t2; + +--echo # 2 peers frame. + +--sorted_result +select pk, a, b, std(b) over (order by a range between 1 preceding and current row) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a range between 1 preceding and 0 preceding) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a range between current row and 1 following) +from t2; + +--sorted_result +select pk, a, b, std(b) over (order by a range between 0 following and 1 following) +from t2; + +drop table t1; +drop table t2; diff --git a/query_classifier/test/win_sum.test b/query_classifier/test/win_sum.test new file mode 100644 index 000000000..aa4965bfd --- /dev/null +++ b/query_classifier/test/win_sum.test @@ -0,0 +1,47 @@ +create table t1 ( + pk int primary key, + a int, + b int, + c real +); + + +insert into t1 values +(101 , 0, 10, 1.1), +(102 , 0, 10, 2.1), +(103 , 1, 10, 3.1), +(104 , 1, 10, 4.1), +(108 , 2, 10, 5.1), +(105 , 2, 20, 6.1), +(106 , 2, 20, 7.1), +(107 , 2, 20, 8.15), +(109 , 4, 20, 9.15), +(110 , 4, 20, 10.15), +(111 , 5, NULL, 11.15), +(112 , 5, 1, 12.25), +(113 , 5, NULL, 13.35), +(114 , 5, NULL, 14.50), +(115 , 5, NULL, 15.65), +(116 , 6, 1, NULL), +(117 , 6, 1, 10), +(118 , 6, 1, 1.1), +(119 , 6, 1, NULL), +(120 , 6, 1, NULL), +(121 , 6, 1, NULL), +(122 , 6, 1, 2.2), +(123 , 6, 1, 20.1), +(124 , 6, 1, -10.4), +(125 , 6, 1, NULL), +(126 , 6, 1, NULL), +(127 , 6, 1, NULL); + + +--sorted_result +select pk, a, b, sum(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) +from t1; + +--sorted_result +select pk, a, c, sum(c) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) +from t1; + +drop table t1;