summaryrefslogtreecommitdiff
path: root/mysql-test/t
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/t')
-rw-r--r--mysql-test/t/connect2.test3
-rw-r--r--mysql-test/t/cte_nonrecursive.test14
-rw-r--r--mysql-test/t/cte_recursive.test241
-rw-r--r--mysql-test/t/ctype_eucjpms.test16
-rw-r--r--mysql-test/t/ctype_gbk_export_import.test161
-rw-r--r--mysql-test/t/ctype_ujis.test17
-rw-r--r--mysql-test/t/ctype_utf8.test16
-rw-r--r--mysql-test/t/ctype_utf8mb4.test17
-rw-r--r--mysql-test/t/delayed.test41
-rw-r--r--mysql-test/t/func_analyse.test28
-rw-r--r--mysql-test/t/group_by.test35
-rw-r--r--mysql-test/t/limit_rows_examined.test4
-rw-r--r--mysql-test/t/myisam.test2
-rw-r--r--mysql-test/t/order_by_optimizer.test34
-rw-r--r--mysql-test/t/parser.test4
-rw-r--r--mysql-test/t/subselect.test2
-rw-r--r--mysql-test/t/win.test1203
-rw-r--r--mysql-test/t/win_avg.test47
-rw-r--r--mysql-test/t/win_bit.test89
-rw-r--r--mysql-test/t/win_ntile.test171
-rw-r--r--mysql-test/t/win_orderby.test32
-rw-r--r--mysql-test/t/win_percent_cume.test36
-rw-r--r--mysql-test/t/win_rank.test58
-rw-r--r--mysql-test/t/win_sum.test47
24 files changed, 2308 insertions, 10 deletions
diff --git a/mysql-test/t/connect2.test b/mysql-test/t/connect2.test
index b4614a65a91..9d2a438aa0a 100644
--- a/mysql-test/t/connect2.test
+++ b/mysql-test/t/connect2.test
@@ -7,7 +7,7 @@
call mtr.add_suppression("Allocation failed");
SET @old_debug= @@session.debug;
set @old_thread_cache_size=@@global.thread_cache_size;
-
+set @@global.thread_cache_size=0;
# Test connections to the
connect(con1,localhost,root,,test,,);
@@ -32,7 +32,6 @@ select 1;
disconnect con1;
# Test connections to the extra port.
-
connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,);
select 1;
disconnect con1;
diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test
index 5a6e07e0c0c..e3164f53887 100644
--- a/mysql-test/t/cte_nonrecursive.test
+++ b/mysql-test/t/cte_nonrecursive.test
@@ -434,3 +434,17 @@ with t(f1,f1) as (select * from t1 where b >= 'c')
select t1.b from t2,t1 where t1.a = t2.c;
drop table t1,t2;
+
+--echo #
+--echo # Bug mdev-9937: View used in the specification of with table
+--echo # refers to the base table with the same name
+--echo #
+
+create table t1 (a int);
+insert into t1 values (20), (30), (10);
+create view v1 as select * from t1 where a > 10;
+
+with t1 as (select * from v1) select * from t1;
+
+drop view v1;
+drop table t1;
diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test
new file mode 100644
index 00000000000..34eee6d3bf2
--- /dev/null
+++ b/mysql-test/t/cte_recursive.test
@@ -0,0 +1,241 @@
+create table t1 (a int, b varchar(32));
+insert into t1 values
+(4,'aaaa' ), (7,'bb'), (1,'ccc'), (4,'dd');
+insert into t1 values
+(3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg');
+
+--ERROR 1984
+with recursive
+a1(a,b) as
+(select * from t1 where t1.a>3
+union
+select * from b1 where b1.a >3
+union
+select * from c1 where c1.a>3),
+b1(a,b) as
+(select * from a1 where a1.b > 'ccc'
+union
+select * from c1 where c1.b > 'ddd'),
+c1(a,b) as
+(select * from a1 where a1.a<6 and a1.b< 'zz'
+union
+select * from b1 where b1.b > 'auu')
+select * from c1;
+
+drop table t1;
+
+create table folks(id int, name char(32), dob date, father int, mother int);
+
+insert into folks values
+(100, 'Vasya', '2000-01-01', 20, 30),
+(20, 'Dad', '1970-02-02', 10, 9),
+(30, 'Mom', '1975-03-03', 8, 7),
+(10, 'Grandpa Bill', '1940-04-05', null, null),
+(9, 'Grandma Ann', '1941-10-15', null, null),
+(25, 'Uncle Jim', '1968-11-18', 8, 7),
+(98, 'Sister Amy', '2001-06-20', 20, 30),
+(8, 'Grandma Sally', '1943-08-23', 5, 6),
+(6, 'Grandgrandma Martha', '1923-05-17', null, null),
+(67, 'Cousin Eddie', '1992-02-28', 25, 27),
+(27, 'Auntie Melinda', '1971-03-29', null, null);
+
+
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Vasya' and dob = '2000-01-01'
+ union
+ select p.id, p.name, p.dob, p.father, p.mother
+ from folks as p, ancestors AS a
+ where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+
+with recursive
+ancestors
+as
+(
+ select p.*
+ from folks as p, ancestors AS a
+ where p.id = a.father or p.id = a.mother
+ union
+ select *
+ from folks
+ where name = 'Vasya' and dob = '2000-01-01'
+)
+select * from ancestors;
+
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Cousin Eddie'
+ union
+ select p.*
+ from folks as p, ancestors as a
+ where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Vasya' or name='Sister Amy'
+ union
+ select p.*
+ from folks as p, ancestors as a
+ where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+
+with recursive
+prev_gen
+as
+(
+ select folks.*
+ from folks, prev_gen
+ where folks.id=prev_gen.father or folks.id=prev_gen.mother
+ union
+ select *
+ from folks
+ where name='Vasya'
+),
+ancestors
+as
+(
+ select *
+ from folks
+ where name='Vasya'
+ union
+ select *
+ from ancestors
+ union
+ select *
+ from prev_gen
+)
+select ancestors.name, ancestors.dob from ancestors;
+
+
+with recursive
+descendants
+as
+(
+ select *
+ from folks
+ where name = 'Grandpa Bill'
+ union
+ select folks.*
+ from folks, descendants as d
+ where d.id=folks.father or d.id=folks.mother
+)
+select * from descendants;
+
+with recursive
+descendants
+as
+(
+ select *
+ from folks
+ where name = 'Grandma Sally'
+ union
+ select folks.*
+ from folks, descendants as d
+ where d.id=folks.father or d.id=folks.mother
+)
+select * from descendants;
+
+
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Vasya' and dob = '2000-01-01'
+ union
+ select p.*
+ from folks as p, ancestors AS a
+ where p.id = a.father OR p.id = a.mother
+)
+select *
+ from ancestors t1, ancestors t2
+ where exists (select * from ancestors a
+ where a.father=t1.id AND a.mother=t2.id);
+
+with
+ancestor_couples(husband, h_dob, wife, w_dob)
+as
+(
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Vasya'
+ union
+ select p.*
+ from folks as p, ancestors AS a
+ where p.id = a.father OR p.id = a.mother
+)
+select t1.name, t1.dob, t2.name, t2.dob
+ from ancestors t1, ancestors t2
+ where exists (select * from ancestors a
+ where a.father=t1.id AND a.mother=t2.id)
+)
+select * from ancestor_couples;
+
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Vasya' and dob = '2000-01-01'
+ union
+ select p.*
+ from folks as p, ancestors AS a
+ where p.id = a.father
+ union
+ select p.*
+ from folks as p, ancestors AS a
+ where p.id = a.mother
+)
+select * from ancestors;
+
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+ w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+ select h.*, w.*
+ from folks h, folks w, coupled_ancestors a
+ where a.father = h.id AND a.mother = w.id
+ union
+ select h.*, w.*
+ from folks v, folks h, folks w
+ where v.name = 'Vasya' and
+ (v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+ select h_id, h_name, h_dob, h_father, h_mother
+ from ancestor_couples
+ union
+ select w_id, w_name, w_dob, w_father, w_mother
+ from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+ from ancestor_couples;
+
+drop table folks;
+
diff --git a/mysql-test/t/ctype_eucjpms.test b/mysql-test/t/ctype_eucjpms.test
index d533e38b2a2..b5bd92d1d07 100644
--- a/mysql-test/t/ctype_eucjpms.test
+++ b/mysql-test/t/ctype_eucjpms.test
@@ -566,3 +566,19 @@ DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-9842 LOAD DATA INFILE does not work well with a TEXT column when using sjis
+--echo #
+CREATE TABLE t1 (a TEXT CHARACTER SET eucjpms);
+LOAD DATA INFILE '../../std_data/loaddata/mdev9823.ujis.txt' INTO TABLE t1 CHARACTER SET eucjpms IGNORE 4 LINES;
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/t/ctype_gbk_export_import.test b/mysql-test/t/ctype_gbk_export_import.test
new file mode 100644
index 00000000000..02d18fe60d4
--- /dev/null
+++ b/mysql-test/t/ctype_gbk_export_import.test
@@ -0,0 +1,161 @@
+--source include/not_windows.inc
+--source include/have_case_sensitive_file_system.inc
+--source include/have_gbk.inc
+
+#
+# Check if we're running on a POSIX-locale machine
+#
+
+--disable_query_log
+--exec locale -a > $MYSQLTEST_VARDIR/tmp/locale_a_gbk.output 2>/dev/null || true
+SET @file=REPLACE(LOAD_FILE('../../tmp/locale_a_gbk.output'), '-', '');
+# Note, file content must be case sensitive. See mysql_locale_posix.test
+--remove_file $MYSQLTEST_VARDIR/tmp/locale_a_gbk.output
+if (`SELECT (IFNULL(@file,'') NOT LIKE '%\nzh_CN.gbk\n%')`)
+{
+ Skip Need POSIX locale zh_CN.gbk;
+}
+--enable_query_log
+
+
+--disable_warnings
+DROP DATABASE IF EXISTS gbk;
+--enable_warnings
+
+CREATE DATABASE gbk DEFAULT CHARACTER SET gbk;
+USE gbk;
+
+CREATE TABLE t1 (
+ id INT NOT NULL,
+ a1 TEXT NOT NULL,
+ a2 TEXT CHARACTER SET utf8 NOT NULL,
+ b1 BLOB NOT NULL,
+ eol TEXT NOT NULL);
+
+DELIMITER |;
+CREATE PROCEDURE populate()
+BEGIN
+ TRUNCATE TABLE t1;
+ INSERT INTO t1 SET id=1, a1=0xEE5C, a2=_gbk 0xEE5C, b1=0xEE5C, eol='$';
+ INSERT INTO t1 SET id=2, a1=0xEE5C5C, a2=_gbk 0xEE5C5C, b1=0xEE5C5C, eol='$';
+END|
+
+CREATE FUNCTION cmt(id INT, field_name TEXT, field_value BLOB)
+ RETURNS TEXT CHARACTER SET utf8
+BEGIN
+ DECLARE comment TEXT CHARACTER SET utf8;
+ DECLARE expected_value_01 BLOB;
+ DECLARE expected_value_02 BLOB;
+ SET comment= CASE field_name WHEN 'a1' THEN 'TEXT-GBK' WHEN 'a2' THEN 'TEXT-UTF8' WHEN 'b1' THEN 'BLOB' ELSE '' END;
+ SET expected_value_01= CASE field_name WHEN 'a1' THEN 0xEE5C WHEN 'a2' THEN 0xE9A0AB WHEN 'b1' THEN 0xEE5C ELSE '' END;
+ SET expected_value_02= CASE field_name WHEN 'a1' THEN 0xEE5C5C WHEN 'a2' THEN 0xE9A0AB5C WHEN 'b1' THEN 0xEE5C5C ELSE '' END;
+ RETURN IF(CASE id
+ WHEN 1 THEN expected_value_01
+ WHEN 2 THEN expected_value_02
+ ELSE ''
+ END <> field_value,
+ CONCAT('BAD-', comment), '');
+END|
+
+CREATE FUNCTION display_file(file BLOB) RETURNS TEXT CHARACTER SET utf8
+BEGIN
+ SET file=REPLACE(file, 0x09, '----');
+ SET file=REPLACE(file, 0x0A, '++++');
+ RETURN REPLACE(REPLACE(HEX(file), '2D2D2D2D','-'), '2B2B2B2B','|');
+END|
+
+DELIMITER ;|
+
+CREATE VIEW v1 AS
+SELECT
+ id,
+ CONCAT(RPAD(HEX(a1),50,' '), cmt(id, 'a1', a1)) AS a1,
+ CONCAT(RPAD(HEX(a2),50,' '), cmt(id, 'a2', a2)) AS a2,
+ CONCAT(RPAD(HEX(b1),50,' '), cmt(id, 'b1', b1)) AS b1,
+ CONCAT(RPAD(HEX(eol),50,' '), IF(eol<>'$','BAD-EOL','')) AS eol,
+ '---' AS `---`
+FROM t1;
+SHOW CREATE TABLE t1;
+
+--echo #
+--echo # Dump using SELECT INTO OUTFILE
+--echo #
+
+--perl
+my $dir= $ENV{'MYSQL_TMP_DIR'};
+open (my $FILE, '>', "$dir/tmpgbk.inc") or die "open(): $!";
+for $LOCALE ("zh_CN.gbk") {
+for $DUMP_OPTIONS ("--default-character-set=auto", "--default-character-set=gbk","--default-character-set=utf8") {
+for $DUMP_CHARSET_CLAUSE ("", "CHARACTER SET gbk", "CHARACTER SET utf8", "CHARACTER SET binary") {
+for $RESTORE_OPTIONS ("--default-character-set=auto", "--default-character-set=gbk","--default-character-set=utf8") {
+for $RESTORE_CHARSET_CLAUSE ("", "CHARACTER SET gbk", "CHARACTER SET utf8", "CHARACTER SET binary") {
+print $FILE <<END
+--echo Start of {$LOCALE}{$DUMP_OPTIONS $DUMP_CHARSET_CLAUSE}{$RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE}
+--echo Locale: $LOCALE
+--echo OUTFILE: $DUMP_OPTIONS $DUMP_CHARSET_CLAUSE
+--echo INFILE: $RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE
+--disable_query_log
+CALL populate();
+--exec LC_ALL=$LOCALE \$MYSQL $DUMP_OPTIONS gbk -e "SELECT * INTO OUTFILE '\$MYSQLTEST_VARDIR/tmp/t1' $DUMP_CHARSET_CLAUSE FROM t1"
+--vertical_results
+TRUNCATE TABLE t1;
+--eval SELECT display_file(LOAD_FILE('\$MYSQLTEST_VARDIR/tmp/t1')) AS file;
+--exec LC_ALL=$LOCALE \$MYSQL $RESTORE_OPTIONS gbk -e "LOAD DATA INFILE '\$MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t1 $RESTORE_CHARSET_CLAUSE"
+SELECT * FROM v1;
+--echo End of {$LOCALE}{$DUMP_OPTIONS $DUMP_CHARSET_CLAUSE}{$RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE}
+--echo
+--echo
+--horizontal_results
+--enable_query_log
+--remove_file \$MYSQLTEST_VARDIR/tmp/t1
+END
+}}}}}
+close $FILE
+EOF
+--source $MYSQL_TMP_DIR/tmpgbk.inc
+--remove_file $MYSQL_TMP_DIR/tmpgbk.inc
+
+
+--echo #
+--echo # Dump using mysqldump -Tdir
+--echo #
+
+--exec mkdir $MYSQLTEST_VARDIR/tmp/tmpgbk
+--perl
+my $dir= $ENV{'MYSQL_TMP_DIR'};
+open (my $FILE, '>', "$dir/tmpgbk.inc") or die "open(): $!";
+for $LOCALE ("zh_CN.gbk") {
+for $DUMP_OPTIONS ("--default-character-set=binary","--default-character-set=gbk","--default-character-set=utf8") {
+for $RESTORE_OPTIONS ("--default-character-set=auto","--default-character-set=binary","--default-character-set=gbk","--default-character-set=utf8") {
+for $RESTORE_CHARSET_CLAUSE ("", "CHARACTER SET gbk", "CHARACTER SET utf8", "CHARACTER SET binary") {
+print $FILE <<END
+--echo Start of {$LOCALE}{$DUMP_OPTIONS}{$RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE}
+--echo Locale: $LOCALE
+--echo mysqldump: $DUMP_OPTIONS
+--echo INFILE: $RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE
+--disable_query_log
+CALL populate();
+--exec LC_ALL=$LOCALE \$MYSQL_DUMP $DUMP_OPTIONS -T\$MYSQLTEST_VARDIR/tmp/tmpgbk gbk t1
+--vertical_results
+TRUNCATE TABLE t1;
+--eval SELECT display_file(LOAD_FILE('\$MYSQLTEST_VARDIR/tmp/tmpgbk/t1.txt')) AS file;
+--exec LC_ALL=$LOCALE \$MYSQL $RESTORE_OPTIONS gbk -e "LOAD DATA INFILE '\$MYSQLTEST_VARDIR/tmp/tmpgbk/t1.txt' INTO TABLE t1 $RESTORE_CHARSET_CLAUSE"
+SELECT * FROM v1;
+--echo End of {$LOCALE}{$DUMP_OPTIONS}{$RESTORE_OPTIONS $RESTORE_CHARSET_CLAUSE}
+--echo
+--echo
+--horizontal_results
+--enable_query_log
+--remove_file \$MYSQLTEST_VARDIR/tmp/tmpgbk/t1.txt
+--remove_file \$MYSQLTEST_VARDIR/tmp/tmpgbk/t1.sql
+END
+}}}}
+close $FILE
+EOF
+--source $MYSQL_TMP_DIR/tmpgbk.inc
+--remove_file $MYSQL_TMP_DIR/tmpgbk.inc
+--rmdir $MYSQLTEST_VARDIR/tmp/tmpgbk
+
+
+DROP DATABASE gbk;
+USE test;
diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test
index 3f444580b13..db85585efd9 100644
--- a/mysql-test/t/ctype_ujis.test
+++ b/mysql-test/t/ctype_ujis.test
@@ -1396,3 +1396,20 @@ SELECT HEX(a) FROM t1 ORDER BY a;DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #
+
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-9842 LOAD DATA INFILE does not work well with a TEXT column when using sjis
+--echo #
+CREATE TABLE t1 (a TEXT CHARACTER SET ujis);
+LOAD DATA INFILE '../../std_data/loaddata/mdev9823.ujis.txt' INTO TABLE t1 CHARACTER SET ujis IGNORE 4 LINES;
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index f3a9e63b57d..61bc1c58ecb 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1967,5 +1967,21 @@ SELECT c1 FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-9842 LOAD DATA INFILE does not work well with a TEXT column when using sjis
+--echo #
+CREATE TABLE t1 (a TEXT CHARACTER SET utf8);
+LOAD DATA INFILE '../../std_data/loaddata/mdev9823.utf8mb4.txt' INTO TABLE t1 CHARACTER SET utf8 IGNORE 4 LINES;
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-9874 LOAD XML INFILE does not handle well broken multi-byte characters
+--echo #
+CREATE TABLE t1 (a TEXT CHARACTER SET utf8);
+LOAD XML INFILE '../../std_data/loaddata/mdev9874.xml' INTO TABLE t1 CHARACTER SET utf8 ROWS IDENTIFIED BY '<row>';
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index 2fe9b5e6544..74e39a80e5b 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/ctype_utf8mb4.test
@@ -1919,3 +1919,20 @@ DROP FUNCTION f1;
--echo #
--echo # End of 10.1 tests
--echo #
+
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-9842 LOAD DATA INFILE does not work well with a TEXT column when using sjis
+--echo #
+CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4);
+LOAD DATA INFILE '../../std_data/loaddata/mdev9823.utf8mb4.txt' INTO TABLE t1 CHARACTER SET utf8mb4 IGNORE 4 LINES;
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index 85f28de128b..dea16c84a51 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -1,5 +1,12 @@
# delayed works differently in embedded server
--source include/not_embedded.inc
+# Don't test this under valgrind, memory leaks will occur
+--source include/not_valgrind.inc
+# Avoid CrashReporter popup on Mac
+--source include/not_crashrep.inc
+# Binary must be compiled with debug for crash to occur
+--source include/have_debug_sync.inc
+
#
# test of DELAYED insert and timestamps
# (Can't be tested with purify :( )
@@ -601,3 +608,37 @@ disconnect con1;
--source include/wait_until_disconnected.inc
connection default;
drop tables tm, t1, t2;
+
+--echo #
+--echo # MDEV-9621 INSERT DELAYED fails on insert for tables with many columns
+--echo #
+
+CREATE TABLE t1 (
+ a int,b int,c int,d int,e int,f int,g int,h int,i int,j int,k int,l int,m int,n int,o int,p int,q int,r int,s int,t int,u int,v int,x int,y int,z int
+) ENGINE=MyISAM;
+
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+INSERT DELAYED INTO t1 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z)
+values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+drop table t1;
+
+--echo #
+--echo # INSERT DELAYED hangs if table was crashed
+--echo #
+
+create table t1 (a int, b int) engine=myisam;
+insert into t1 values (1,1);
+
+# Will come back with t1 crashed.
+--source include/crash_mysqld.inc
+
+call mtr.add_suppression(" marked as crashed and should be repaired");
+call mtr.add_suppression("Checking table");
+
+--replace_result '\\' '/'
+insert delayed into t1 values (2,2);
+insert delayed into t1 values (3,3);
+flush tables t1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/func_analyse.test b/mysql-test/t/func_analyse.test
index c77967a0cc9..6c30c0ca630 100644
--- a/mysql-test/t/func_analyse.test
+++ b/mysql-test/t/func_analyse.test
@@ -11,7 +11,7 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6
select count(*) from t1 procedure analyse();
select * from t1 procedure analyse();
select * from t1 procedure analyse(2);
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
create table t2 select * from t1 procedure analyse();
drop table t1;
@@ -127,7 +127,7 @@ CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
--echo # should not crash
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
DROP TABLE t1;
@@ -157,3 +157,27 @@ SELECT * FROM t2 LIMIT 1 PROCEDURE ANALYSE();
DROP TABLE t1, t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # Start of 10.2 tests
+--echo #
+(SELECT 1 FROM DUAL PROCEDURE ANALYSE());
+((SELECT 1 FROM DUAL PROCEDURE ANALYSE()));
+
+# TODO:
+--error ER_WRONG_USAGE
+SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
+
+--echo #
+--echo # MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification
+--echo #
+
+--error ER_PARSE_ERROR
+SELECT * FROM (SELECT * FROM t1 PROCEDURE ANALYSE());
+--ERROR ER_PARSE_ERROR
+SELECT * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE());
+
+--error ER_PARSE_ERROR
+SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2;
+--error ER_PARSE_ERROR
+SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index fe9308cd20a..f0007186ab2 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -996,8 +996,33 @@ EXPLAIN SELECT a FROM t1 WHERE a < 2 ORDER BY a;
EXPLAIN SELECT a FROM t1 WHERE a < 2 GROUP BY a;
EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY,i2);
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR JOIN (PRIMARY,i2);
+
+--echo #
+--echo # For this explain, the query plan is weird: if we are using
+--echo # the primary key for reasons other than doing grouping, can't
+--echo # GROUP BY code take advantage of this? Well, currently it doesnt:
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR GROUP BY (PRIMARY,i2) GROUP BY a;
+--echo # Here's a proof it is really doing sorting:
+flush status;
+--disable_result_log
+SELECT a FROM t1 IGNORE INDEX FOR GROUP BY (PRIMARY,i2) GROUP BY a;
+--enable_result_log
+show status like 'Sort_%';
+--echo # Proof ends.
+--echo #
+
+--echo # For this explain, the query plan is weird: if we are using
+--echo # the primary key for reasons other than doing sorting, can't
+--echo # ORDER BY code take advantage of this? Well, currently it doesnt:
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY,i2) ORDER BY a;
+--echo # Here's a proof it is really doing sorting:
+flush status;
+--disable_result_log
+SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY,i2) ORDER BY a;
+--enable_result_log
+show status like 'Sort_%';
+--echo # Proof ends.
+--echo #
SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY,i2) ORDER BY a;
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY)
IGNORE INDEX FOR GROUP BY (i2) GROUP BY a;
@@ -1793,3 +1818,13 @@ from t1
group by t1.b;
drop table t0,t1,t2;
+
+--echo #
+--echo # MDEV-9602 crash in st_key::actual_rec_per_key when group by constant
+--echo #
+
+create table t1 (a date not null,unique (a)) engine=innodb;
+select distinct a from t1 group by 'a';
+insert into t1 values("2001-02-02"),("2001-02-03");
+select distinct a from t1 group by 'a';
+drop table t1;
diff --git a/mysql-test/t/limit_rows_examined.test b/mysql-test/t/limit_rows_examined.test
index 45ee483c7aa..382530234be 100644
--- a/mysql-test/t/limit_rows_examined.test
+++ b/mysql-test/t/limit_rows_examined.test
@@ -305,7 +305,6 @@ select c1, sum(c2) from t3 group by c1;
explain
select c1, sum(c2) from t3 group by c1 LIMIT ROWS EXAMINED 0;
select c1, sum(c2) from t3 group by c1 LIMIT ROWS EXAMINED 0;
---error 1028
select c1, sum(c2) from t3 group by c1 LIMIT ROWS EXAMINED 1;
select c1, sum(c2) from t3 group by c1 LIMIT ROWS EXAMINED 20;
select c1, sum(c2) from t3 group by c1 LIMIT ROWS EXAMINED 21;
@@ -321,7 +320,6 @@ insert into t3i values
explain
select c1, sum(c2) from t3i group by c1 LIMIT ROWS EXAMINED 0;
select c1, sum(c2) from t3i group by c1 LIMIT ROWS EXAMINED 0;
---error 1028
select c1, sum(c2) from t3i group by c1 LIMIT ROWS EXAMINED 1;
select c1, sum(c2) from t3i group by c1 LIMIT ROWS EXAMINED 20;
select c1, sum(c2) from t3i group by c1 LIMIT ROWS EXAMINED 21;
@@ -432,7 +430,7 @@ drop table t1,t2,t1i,t2i;
SET @@optimizer_switch='in_to_exists=on,outer_join_with_cache=on';
CREATE TABLE t1 ( a VARCHAR(3) ) ENGINE=MyISAM;
-INSERT INTO t1 VALUES ('USA');
+INSERT INTO t1 VALUES ('USA'),('CAN');
CREATE TABLE t2 ( b INT );
INSERT INTO t2 VALUES (3899),(3914),(3888);
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 9ac49a9063d..a454fa25ac4 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -552,6 +552,8 @@ insert t2 select * from t1;
checksum table t1, t2, t3 quick;
checksum table t1, t2, t3;
checksum table t1, t2, t3 extended;
+alter table t1 add d int default 30, add e bigint default 300000, add f decimal(30) default 442;
+checksum table t1;
#show table status;
drop table t1,t2;
diff --git a/mysql-test/t/order_by_optimizer.test b/mysql-test/t/order_by_optimizer.test
new file mode 100644
index 00000000000..a4c134afec9
--- /dev/null
+++ b/mysql-test/t/order_by_optimizer.test
@@ -0,0 +1,34 @@
+--disable_warnings
+drop table if exists t0,t1,t2,t3;
+
+--enable_warnings
+--echo #
+--echo # MDEV-7885: EXPLAIN shows wrong info for ORDER BY query
+--echo #
+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 t2 (key1 int, col1 int, key(key1));
+insert into t2 select a,a from t0;
+insert into t2 select 15,15 from t1;
+alter table t2 add key2 int, add key(key2);
+--echo # This must show "Using filesort":
+explain
+select * from t2 ignore index for order by (key1) where col1<0 order by key1 limit 10;
+
+drop table t0, t1, t2;
+
+--echo #
+--echo # MDEV-8857: [Upstream too] EXPLAIN incorrectly shows Distinct for tables using join buffer
+--echo #
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (a int, filler char(200), key(a));
+insert into t1 select A.a + B.a* 10, 'AAAAAAAAAAAAAAAAAAAA' from t0 A, t0 B where B.a in (0,1);
+explain select distinct A.a from t0 A, t1 B where A.a+B.a> 0;
+
+drop table t0, t1;
+
diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test
index 0a19b03a4eb..86cc3c47c37 100644
--- a/mysql-test/t/parser.test
+++ b/mysql-test/t/parser.test
@@ -806,7 +806,7 @@ SELECT 1 FROM
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE) a;
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
SELECT 1 FROM
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE) a;
@@ -815,7 +815,7 @@ SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE);
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE);
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 7a7c01e78bd..5313a4b8a39 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -51,7 +51,7 @@ SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c O
SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
--- error ER_WRONG_USAGE
+-- error ER_PARSE_ERROR
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error ER_PARSE_ERROR
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test
new file mode 100644
index 00000000000..09ddf41b4f0
--- /dev/null
+++ b/mysql-test/t/win.test
@@ -0,0 +1,1203 @@
+#
+# Window Functions Tests
+#
+
+--disable_warnings
+drop table if exists t1,t2;
+drop view if exists v1;
+--enable_warnings
+
+--echo # ########################################################################
+--echo # # Parser tests
+--echo # ########################################################################
+--echo #
+--echo # Check what happens when one attempts to use window function without OVER clause
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+
+--error ER_PARSE_ERROR
+select row_number() from t1;
+--error ER_PARSE_ERROR
+select rank() from t1;
+
+--echo # Attempt to use window function in the WHERE clause
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select * from t1 where 1=rank() over (order by a);
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select * from t1 where 1>row_number() over (partition by b order by a);
+drop table t1;
+
+--echo # ########################################################################
+--echo # # Functionality tests
+--echo # ########################################################################
+--echo #
+--echo # Check if ROW_NUMBER() works in basic cases
+create table t1(a int, b int, x char(32));
+insert into t1 values (2, 10, 'xx');
+insert into t1 values (2, 10, 'zz');
+insert into t1 values (2, 20, 'yy');
+insert into t1 values (3, 10, 'xxx');
+insert into t1 values (3, 20, 'vvv');
+
+--sorted_result
+select a, row_number() over (partition by a order by b) from t1;
+
+select a, b, x, row_number() over (partition by a order by x) from t1;
+
+drop table t1;
+
+create table t1 (pk int primary key, a int, b int);
+insert into t1 values
+ (1, 10, 22),
+ (2, 11, 21),
+ (3, 12, 20),
+ (4, 13, 19),
+ (5, 14, 18);
+
+select
+ pk, a, b,
+ row_number() over (order by a),
+ row_number() over (order by b)
+from t1;
+
+drop table t1;
+
+--echo #
+--echo # Try RANK() function
+--echo #
+create table t2 (
+ pk int primary key,
+ a int
+);
+
+insert into t2 values
+( 1 , 0),
+( 2 , 0),
+( 3 , 1),
+( 4 , 1),
+( 8 , 2),
+( 5 , 2),
+( 6 , 2),
+( 7 , 2),
+( 9 , 4),
+(10 , 4);
+
+select pk, a, rank() over (order by a) from t2;
+select pk, a, rank() over (order by a desc) from t2;
+
+drop table t2;
+
+--echo #
+--echo # Try Aggregates as window functions. With frames.
+--echo #
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+
+select
+ pk, c,
+ count(*) over (partition by c order by pk
+ rows between 2 preceding and 2 following) as CNT
+from t1;
+
+select
+ pk, c,
+ count(*) over (partition by c order by pk
+ rows between 1 preceding and 2 following) as CNT
+from t1;
+
+select
+ pk, c,
+ count(*) over (partition by c order by pk
+ rows between 2 preceding and current row) as CNT
+from t1;
+
+select
+ pk,c,
+ count(*) over (partition by c order by pk rows
+ between 1 following and 2 following) as CNT
+from t1;
+
+select
+ pk,c,
+ count(*) over (partition by c order by pk rows
+ between 2 preceding and 1 preceding) as CNT
+from t1;
+
+select
+ pk, c,
+ count(*) over (partition by c order by pk
+ rows between current row and 1 following) as CNT
+from t1;
+
+--echo # Check ORDER BY DESC
+select
+ pk, c,
+ count(*) over (partition by c order by pk desc
+ rows between 2 preceding and 2 following) as CNT
+from t1;
+
+drop table t0,t1;
+
+--echo #
+--echo # Resolution of window names
+--echo #
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+
+select
+ pk, c,
+ count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+ rows between 2 preceding and 2 following);
+
+select
+ pk, c,
+ count(*) over (w1 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c order by pk);
+
+select
+ pk, c,
+ count(*) over (w1 order by pk rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c);
+
+select
+ pk, c,
+ count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 order by pk);
+
+select
+ pk, c,
+ count(*) over w3 as CNT
+from t1
+window
+ w1 as (partition by c),
+ w2 as (w1 order by pk),
+ w3 as (w2 rows between 2 preceding and 2 following);
+
+--error ER_WRONG_WINDOW_SPEC_NAME
+select
+ pk, c,
+ count(*) over w as CNT
+from t1
+window w1 as (partition by c order by pk
+ rows between 2 preceding and 2 following);
+
+--error ER_DUP_WINDOW_NAME
+select
+ pk, c,
+ count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w1 as (order by pk);
+
+--error ER_WRONG_WINDOW_SPEC_NAME
+select
+ pk, c,
+ count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w partition by c order by pk);
+
+--error ER_PARTITION_LIST_IN_REFERENCING_WINDOW_SPEC
+select
+ pk, c,
+ count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 partition by c order by pk);
+
+--error ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC
+select
+ pk, c,
+ count(*) over (w2 rows between 2 preceding and 2 following) as CNT
+from t1
+window w1 as (partition by c order by pk), w2 as (w1 order by pk);
+
+--error ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC
+select
+ pk, c,
+ count(*) over w3 as CNT
+from t1
+window
+ w1 as (partition by c),
+ w2 as (w1 order by pk rows between 3 preceding and 2 following),
+ w3 as (w2 rows between 2 preceding and 2 following);
+
+--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS
+select
+ pk, c,
+ count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+ rows between unbounded following and 2 following);
+
+--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS
+select
+ pk, c,
+ count(*) over (w1 rows between 2 preceding and unbounded preceding) as CNT
+from t1
+window w1 as (partition by c order by pk);
+
+--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS
+select
+ pk, c,
+ count(*) over (w1 order by pk rows between current row and 2 preceding) as CNT
+from t1
+window w1 as (partition by c);
+
+--error ER_BAD_COMBINATION_OF_WINDOW_FRAME_BOUND_SPECS
+select
+ pk, c,
+ count(*) over (w2 rows between 2 following and current row) as CNT
+from t1
+window w1 as (partition by c), w2 as (w1 order by pk);
+
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select
+ pk, c
+from t1 where rank() over w1 > 2
+window w1 as (partition by c order by pk);
+
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select
+ c, max(pk) as m
+from t1
+ group by c + rank() over w1
+window w1 as (order by m);
+
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select
+ c, max(pk) as m, rank() over w1 as r
+from t1
+ group by c+r
+window w1 as (order by m);
+
+--error ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION
+select
+ c, max(pk) as m, rank() over w1 as r
+from t1
+ group by c having c+r > 3
+window w1 as (order by m);
+
+--error ER_WINDOW_FUNCTION_IN_WINDOW_SPEC
+select
+ c, max(pk) as m, rank() over w1 as r,
+ rank() over (partition by r+1 order by m)
+from t1
+ group by c
+window w1 as (order by m);
+
+--error ER_WINDOW_FUNCTION_IN_WINDOW_SPEC
+select
+ c, max(pk) as m, rank() over w1 as r,
+ rank() over (partition by m order by r)
+from t1
+ group by c
+window w1 as (order by m);
+
+--error ER_WINDOW_FUNCTION_IN_WINDOW_SPEC
+select
+ c, max(pk) as m, rank() over w1 as r, dense_rank() over w2 as dr
+from t1
+ group by c
+window w1 as (order by m), w2 as (partition by r order by m);
+
+--error ER_NOT_ALLOWED_WINDOW_FRAME
+select
+ pk, c,
+ row_number() over (partition by c order by pk
+ range between unbounded preceding and current row) as r
+from t1;
+
+--error ER_NOT_ALLOWED_WINDOW_FRAME
+select
+ pk, c,
+ rank() over w1 as r
+from t1
+window w1 as (partition by c order by pk
+ rows between 2 preceding and 2 following);
+
+--error ER_NOT_ALLOWED_WINDOW_FRAME
+select
+ pk, c,
+ dense_rank() over (partition by c order by pk
+ rows between 1 preceding and 1 following) as r
+from t1;
+
+--error ER_NO_ORDER_LIST_IN_WINDOW_SPEC
+select
+ pk, c,
+ rank() over w1 as r
+from t1
+window w1 as (partition by c);
+
+--error ER_NO_ORDER_LIST_IN_WINDOW_SPEC
+select
+ pk, c,
+ dense_rank() over (partition by c) as r
+from t1;
+
+drop table t0,t1;
+
+--echo #
+--echo # MDEV-9634: Window function produces incorrect value
+--echo #
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (part_id int, pk int, a int);
+insert into t2 select
+ if(a<5, 0, 1), a, if(a<5, NULL, 1) from t0;
+select * from t2;
+
+select
+ part_id, pk, a,
+ count(a) over (partition by part_id order by pk
+ rows between 1 preceding and 1 following) as CNT
+from t2;
+
+drop table t0, t2;
+
+--echo #
+--echo # RANGE-type bounds
+--echo #
+
+create table t3 (
+ pk int,
+ val int
+);
+
+insert into t3 values
+(0, 1),
+(1, 1),
+(2, 1),
+(3, 2),
+(4, 2),
+(5, 2),
+(6, 2);
+
+select
+ pk,
+ val,
+ count(val) over (order by val
+ range between current row and
+ current row)
+ as CNT
+from t3;
+
+insert into t3 values
+(7, 3),
+(8, 3);
+
+select
+ pk,
+ val,
+ count(val) over (order by val
+ range between current row and
+ current row)
+ as CNT
+from t3;
+
+drop table t3;
+
+--echo # Now, check with PARTITION BY
+create table t4 (
+ part_id int,
+ pk int,
+ val int
+);
+
+insert into t4 values
+(1234, 100, 1),
+(1234, 101, 1),
+(1234, 102, 1),
+(1234, 103, 2),
+(1234, 104, 2),
+(1234, 105, 2),
+(1234, 106, 2),
+(1234, 107, 3),
+(1234, 108, 3),
+
+(5678, 200, 1),
+(5678, 201, 1),
+(5678, 202, 1),
+(5678, 203, 2),
+(5678, 204, 2),
+(5678, 205, 2),
+(5678, 206, 2),
+(5678, 207, 3),
+(5678, 208, 3);
+
+select
+ part_id,
+ pk,
+ val,
+ count(val) over (partition by part_id
+ order by val
+ range between current row and
+ current row)
+ as CNT
+from t4;
+
+--echo #
+--echo # Try RANGE UNBOUNDED PRECEDING | FOLLOWING
+--echo #
+select
+ part_id,
+ pk,
+ val,
+ count(val) over (partition by part_id
+ order by val
+ range between unbounded preceding and
+ current row)
+ as CNT
+from t4;
+
+select
+ part_id,
+ pk,
+ val,
+ count(val) over (partition by part_id
+ order by val
+ range between current row and
+ unbounded following)
+ as CNT
+from t4;
+
+select
+ part_id,
+ pk,
+ val,
+ count(val) over (partition by part_id
+ order by val
+ range between unbounded preceding and
+ unbounded following)
+ as CNT
+from t4;
+
+drop table t4;
+
+--echo #
+--echo # MDEV-9695: Wrong window frame when using RANGE BETWEEN N FOLLOWING AND PRECEDING
+--echo #
+create table t1 (pk int, 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);
+
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as bit_or
+from t1;
+
+--echo # Extra ROWS n PRECEDING tests
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or
+from t1;
+drop table t1;
+
+
+create table t2 (
+ pk int,
+ a int,
+ b int
+);
+
+insert into t2 values
+( 1, 0, 1),
+( 2, 0, 2),
+( 3, 0, 4),
+( 4, 0, 8),
+( 5, 1, 16),
+( 6, 1, 32),
+( 7, 1, 64),
+( 8, 1, 128),
+( 9, 2, 256),
+(10, 2, 512),
+(11, 2, 1024),
+(12, 2, 2048);
+
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or
+from t2;
+
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) as bit_or
+from t2;
+
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) as bit_or
+from t2;
+
+--echo # Check CURRENT ROW
+
+select pk, a, b,
+bit_or(b) over (partition by a order by pk ROWS BETWEEN CURRENT ROW AND CURRENT ROW) as bit_or
+from t2;
+
+drop table t2;
+
+--echo #
+--echo # Try RANGE PRECEDING|FOLLWING n
+--echo #
+create table t1 (
+ part_id int,
+ pk int,
+ a int
+);
+
+insert into t1 values
+(10, 1, 1),
+(10, 2, 2),
+(10, 3, 4),
+(10, 4, 8),
+(10, 5,26),
+(10, 6,27),
+(10, 7,40),
+(10, 8,71),
+(10, 9,72);
+
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 10 FOLLOWING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a DESC
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 10 FOLLOWING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 1 FOLLOWING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 10 PRECEDING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a DESC
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 10 PRECEDING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 1 PRECEDING) as cnt
+from t1;
+
+# Try bottom bound
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN 1 PRECEDING
+ AND CURRENT ROW) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a DESC
+ RANGE BETWEEN 1 PRECEDING
+ AND CURRENT ROW) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN 1 FOLLOWING
+ AND 3 FOLLOWING) as cnt
+from t1;
+
+--echo # Try CURRENT ROW with[out] DESC
+select
+ pk, a,
+ count(a) over (ORDER BY a
+ RANGE BETWEEN CURRENT ROW
+ AND 1 FOLLOWING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (order by a desc
+ range between current row
+ and 1 following) as cnt
+from t1;
+
+
+# Try with partitions
+insert into t1 select 22, pk, a from t1;
+select
+ part_id, pk, a,
+ count(a) over (PARTITION BY part_id
+ ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 10 FOLLOWING) as cnt
+from t1;
+
+select
+ pk, a,
+ count(a) over (PARTITION BY part_id
+ ORDER BY a
+ RANGE BETWEEN UNBOUNDED PRECEDING
+ AND 1 PRECEDING) as cnt
+from t1;
+
+drop table t1;
+
+--echo # Try a RANGE frame over non-integer datatype:
+
+create table t1 (
+ col1 int,
+ a decimal(5,3)
+);
+
+insert into t1 values (1, 0.45);
+insert into t1 values (1, 0.5);
+insert into t1 values (1, 0.55);
+insert into t1 values (1, 1.21);
+insert into t1 values (1, 1.22);
+insert into t1 values (1, 3.33);
+
+select
+ a,
+ count(col1) over (order by a
+ range between 0.1 preceding
+ and 0.1 following)
+from t1;
+
+drop table t1;
+
+--echo #
+--echo # RANGE-type frames and NULL values
+--echo #
+create table t1 (
+ pk int,
+ a int,
+ b int
+);
+
+insert into t1 values (1, NULL,1);
+insert into t1 values (2, NULL,1);
+insert into t1 values (3, NULL,1);
+insert into t1 values (4, 10 ,1);
+insert into t1 values (5, 11 ,1);
+insert into t1 values (6, 12 ,1);
+insert into t1 values (7, 13 ,1);
+insert into t1 values (8, 14 ,1);
+
+
+select
+ pk, a,
+ count(b) over (order by a
+ range between 2 preceding
+ and 2 following) as CNT
+from t1;
+drop table t1;
+
+--echo #
+--echo # Try ranges that have bound1 > bound2. The standard actually allows them
+--echo #
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+
+select
+ pk, c,
+ count(*) over (partition by c
+ order by pk
+ rows between 1 preceding
+ and 2 preceding)
+ as cnt
+from t1;
+
+
+select
+ pk, c,
+ count(*) over (partition by c
+ order by pk
+ range between 1 preceding
+ and 2 preceding)
+ as cnt
+from t1;
+drop table t0, t1;
+
+--echo #
+--echo # Error checking for frame bounds
+--echo #
+
+create table t1 (a int, b int, c varchar(32));
+insert into t1 values (1,1,'foo');
+insert into t1 values (2,2,'bar');
+--error ER_RANGE_FRAME_NEEDS_SIMPLE_ORDERBY
+select
+ count(*) over (order by a,b
+ range between unbounded preceding and current row)
+from t1;
+
+--error ER_WRONG_TYPE_FOR_RANGE_FRAME
+select
+ count(*) over (order by c
+ range between unbounded preceding and current row)
+from t1;
+
+--error ER_WRONG_TYPE_FOR_RANGE_FRAME
+select
+ count(*) over (order by a
+ range between 'abcd' preceding and current row)
+from t1;
+
+--error ER_WRONG_TYPE_FOR_RANGE_FRAME
+select
+ count(*) over (order by a
+ range between current row and 'foo' following)
+from t1;
+
+--echo # Try range frame with invalid bounds
+--error ER_WRONG_TYPE_FOR_ROWS_FRAME
+select
+ count(*) over (order by a
+ rows between 0.5 preceding and current row)
+from t1;
+
+--error ER_WRONG_TYPE_FOR_ROWS_FRAME
+select
+ count(*) over (order by a
+ rows between current row and 3.14 following)
+from t1;
+
+--echo #
+--echo # EXCLUDE clause is parsed but not supported
+--echo #
+
+--error ER_FRAME_EXCLUSION_NOT_SUPPORTED
+select
+ count(*) over (order by a
+ rows between 1 preceding and 1 following
+ exclude current row)
+from t1;
+
+--error ER_FRAME_EXCLUSION_NOT_SUPPORTED
+select
+ count(*) over (order by a
+ range between 1 preceding and 1 following
+ exclude ties)
+from t1;
+
+--error ER_FRAME_EXCLUSION_NOT_SUPPORTED
+select
+ count(*) over (order by a
+ range between 1 preceding and 1 following
+ exclude group)
+from t1;
+
+# EXCLUDE NO OTHERS means 'don't exclude anything'
+select
+ count(*) over (order by a
+ rows between 1 preceding and 1 following
+ exclude no others)
+from t1;
+
+drop table t1;
+
+--echo #
+--echo # Window function in grouping query
+--echo #
+
+create table t1 (
+ username varchar(32),
+ amount int
+);
+
+insert into t1 values
+('user1',1),
+('user1',5),
+('user1',3),
+('user2',10),
+('user2',20),
+('user2',30);
+
+select
+ username,
+ sum(amount) as s,
+ rank() over (order by s desc)
+from t1
+group by username;
+
+drop table t1;
+
+--echo #
+--echo # mdev-9719: Window function in prepared statement
+--echo #
+
+create table t1(a int, b int, x char(32));
+insert into t1 values (2, 10, 'xx');
+insert into t1 values (2, 10, 'zz');
+insert into t1 values (2, 20, 'yy');
+insert into t1 values (3, 10, 'xxx');
+insert into t1 values (3, 20, 'vvv');
+
+prepare stmt from 'select a, row_number() over (partition by a order by b) from t1';
+--sorted_result
+execute stmt;
+
+drop table t1;
+
+--echo #
+--echo # mdev-9754: Window name resolution in prepared statement
+--echo #
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (pk int, c int);
+insert into t1 select a+1,1 from t0;
+update t1 set c=2 where pk not in (1,2,3,4);
+select * from t1;
+
+prepare stmt from
+'select
+ pk, c,
+ count(*) over w1 as CNT
+from t1
+window w1 as (partition by c order by pk
+ rows between 2 preceding and 2 following)';
+execute stmt;
+
+drop table t0,t1;
+
+--echo #
+--echo # EXPLAIN FORMAT=JSON support for window functions
+--echo #
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+explain format=json select rank() over (order by a) from t0;
+
+create table t1 (a int, b int, c int);
+insert into t1 select a,a,a from t0;
+
+explain format=json
+select
+ a,
+ rank() over (order by sum(b))
+from t1
+group by a;
+
+explain format=json
+select
+ a,
+ rank() over (order by sum(b))
+from t1
+group by a
+order by null;
+
+--echo #
+--echo # Check how window function works together with GROUP BY and HAVING
+--echo #
+
+select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7);
+explain format=json
+select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7);
+
+drop table t1;
+drop table t0;
+
+--echo #
+--echo # Building ordering index for window functions
+--echo #
+
+create table t1 (
+ pk int primary key,
+ a int,
+ b int,
+ c int
+);
+
+insert into t1 values
+(101 , 0, 10, 1),
+(102 , 0, 10, 2),
+(103 , 1, 10, 3),
+(104 , 1, 10, 4),
+(108 , 2, 10, 5),
+(105 , 2, 20, 6),
+(106 , 2, 20, 7),
+(107 , 2, 20, 8),
+(109 , 4, 20, 9),
+(110 , 4, 20, 10),
+(111 , 5, NULL, 11),
+(112 , 5, 1, 12),
+(113 , 5, NULL, 13),
+(114 , 5, NULL, 14),
+(115 , 5, NULL, 15),
+(116 , 6, 1, NULL),
+(117 , 6, 1, 10),
+(118 , 6, 1, 1),
+(119 , 6, 1, NULL),
+(120 , 6, 1, NULL),
+(121 , 6, 1, NULL),
+(122 , 6, 1, 2),
+(123 , 6, 1, 20),
+(124 , 6, 1, -10),
+(125 , 6, 1, NULL),
+(126 , 6, 1, NULL),
+(127 , 6, 1, NULL);
+
+--sorted_result
+select sum(b) over (partition by a order by b,pk
+ rows between unbounded preceding and current row) as c1,
+ avg(b) over (w1 rows between 1 preceding and 1 following) as c2,
+ sum(c) over (w2 rows between 1 preceding and 1 following) as c5,
+ avg(b) over (w1 rows between 5 preceding and 5 following) as c3,
+ sum(b) over (w1 rows between 1 preceding and 1 following) as c4
+from t1
+window w1 as (partition by a order by b,pk),
+ w2 as (partition by b order by c,pk);
+
+drop table t1;
+
+
+--echo #
+--echo # MDEV-9848: Window functions: reuse sorting and/or scanning
+--echo #
+
+create table t1 (a int, b int, c int);
+insert into t1 values
+(1,3,1),
+(2,2,1),
+(3,1,1);
+
+--echo # Check using counters
+flush status;
+select
+ rank() over (partition by c order by a),
+ rank() over (partition by c order by b)
+from t1;
+show status like '%sort%';
+
+flush status;
+select
+ rank() over (partition by c order by a),
+ rank() over (partition by c order by a)
+from t1;
+show status like '%sort%';
+
+# Check using EXPLAIN FORMAT=JSON
+explain format=json
+select
+ rank() over (partition by c order by a),
+ rank() over (partition by c order by a)
+from t1;
+
+explain format=json
+select
+ rank() over (order by a),
+ row_number() over (order by a)
+from t1;
+
+explain format=json
+select
+ rank() over (partition by c order by a),
+ count(*) over (partition by c)
+from t1;
+
+explain format=json
+select
+ count(*) over (partition by c),
+ rank() over (partition by c order by a)
+from t1;
+
+drop table t1;
+
+
+--echo #
+--echo # MDEV-9847: Window functions: crash with big_tables=1
+--echo #
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+set @tmp=@@big_tables;
+set big_tables=1;
+select rank() over (order by a) from t1;
+set big_tables=@tmp;
+drop table t1;
+
+--echo #
+--echo # Check if "ORDER BY window_func" works
+--echo #
+
+create table t1 (s1 int, s2 char(5));
+insert into t1 values (1,'a');
+insert into t1 values (null,null);
+insert into t1 values (1,null);
+insert into t1 values (null,'a');
+insert into t1 values (2,'b');
+insert into t1 values (-1,'');
+
+explain format=json
+select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
+select *, row_number() over (order by s1, s2) as X from t1 order by X desc;
+drop table t1;
+
+--echo #
+--echo # Try window functions that are not directly present in the select list
+--echo #
+create table t1 (a int, b int);
+insert into t1 values
+ (1,3),
+ (2,2),
+ (3,1);
+
+select
+ rank() over (order by a) -
+ rank() over (order by b)
+from
+ t1;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-9894: Assertion `0' failed in Window_func_runner::setup
+--echo # return ER_NOT_SUPPORTED_YET for aggregates that are not yet supported
+--echo # as window functions.
+--echo #
+create table t1 (i int);
+insert into t1 values (1),(2);
+--error ER_NOT_SUPPORTED_YET
+SELECT MAX(i) OVER (PARTITION BY (i)) FROM t1;
+drop table t1;
+
+--echo #
+--echo # Check the 0 in ROWS 0 PRECEDING
+--echo #
+
+create table t1 (
+ part_id int,
+ pk int,
+ a int
+);
+
+insert into t1 values (1, 1, 1);
+insert into t1 values (1, 2, 2);
+insert into t1 values (1, 3, 4);
+insert into t1 values (1, 4, 8);
+
+select
+ pk, a,
+ sum(a) over (order by pk rows between 0 preceding and current row)
+from t1;
+
+select
+ pk, a,
+ sum(a) over (order by pk rows between 1 preceding and 0 preceding)
+from t1;
+
+insert into t1 values (200, 1, 1);
+insert into t1 values (200, 2, 2);
+insert into t1 values (200, 3, 4);
+insert into t1 values (200, 4, 8);
+select
+ part_id, pk, a,
+ sum(a) over (partition by part_id order by pk rows between 0 preceding and current row)
+from t1;
+
+select
+ part_id, pk, a,
+ sum(a) over (partition by part_id order by pk rows between 1 preceding and 0 preceding)
+from t1;
+
+drop table t1;
+--echo #
+--echo # MDEV-9780, The "DISTINCT must not bet converted into GROUP BY when
+--echo # window functions are present" part
+--echo #
+
+create table t1 (part_id int, a int);
+insert into t1 values
+(100, 1),
+(100, 2),
+(100, 2),
+(100, 3),
+(2000, 1),
+(2000, 2),
+(2000, 3),
+(2000, 3),
+(2000, 3);
+
+select rank() over (partition by part_id order by a) from t1;
+select distinct rank() over (partition by part_id order by a) from t1;
+explain format=json
+select distinct rank() over (partition by part_id order by a) from t1;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-9893: Window functions with different ORDER BY lists,
+--echo # one of these lists containing an expression
+--echo #
+
+create table t1 (s1 int, s2 char(5));
+insert into t1 values (1,'a');
+insert into t1 values (null,null);
+insert into t1 values (3,null);
+insert into t1 values (4,'a');
+insert into t1 values (2,'b');
+insert into t1 values (-1,'');
+
+select
+ *,
+ ROW_NUMBER() OVER (order by s1),
+ CUME_DIST() OVER (order by -s1)
+from t1;
+
+drop table t1;
+
+
+--echo #
+--echo # MDEV-9925: Wrong result with aggregate function as a window function
+--echo #
+create table t1 (i int);
+insert into t1 values (1),(2);
+select i, sum(i) over (partition by i) from t1;
+drop table t1;
+
+--echo #
+--echo # MDEV-9922: Assertion `!join->only_const_tables() && fsort' failed in int create_sort_index
+--echo #
+create view v1 as select 1 as i;
+select rank() over (order by i) from v1;
+drop view v1;
+
diff --git a/mysql-test/t/win_avg.test b/mysql-test/t/win_avg.test
new file mode 100644
index 00000000000..23a3652d943
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_bit.test b/mysql-test/t/win_bit.test
new file mode 100644
index 00000000000..f077d0d67a0
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_ntile.test b/mysql-test/t/win_ntile.test
new file mode 100644
index 00000000000..6f12e1f4005
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_orderby.test b/mysql-test/t/win_orderby.test
new file mode 100644
index 00000000000..0d42c606486
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_percent_cume.test b/mysql-test/t/win_percent_cume.test
new file mode 100644
index 00000000000..b851185cb32
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_rank.test b/mysql-test/t/win_rank.test
new file mode 100644
index 00000000000..eda1f458205
--- /dev/null
+++ b/mysql-test/t/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/mysql-test/t/win_sum.test b/mysql-test/t/win_sum.test
new file mode 100644
index 00000000000..aa4965bfd5a
--- /dev/null
+++ b/mysql-test/t/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;