summaryrefslogtreecommitdiff
path: root/mysql-test/t
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/t')
-rw-r--r--mysql-test/t/distinct.test4
-rw-r--r--mysql-test/t/drop.test2
-rw-r--r--mysql-test/t/func_group.test1
-rw-r--r--mysql-test/t/func_sapdb.test13
-rw-r--r--mysql-test/t/func_time.test26
-rw-r--r--mysql-test/t/grant.test5
-rw-r--r--mysql-test/t/grant2.test9
-rw-r--r--mysql-test/t/grant_cache.test14
-rw-r--r--mysql-test/t/greedy_optimizer.test313
-rw-r--r--mysql-test/t/group_min_max.test605
-rw-r--r--mysql-test/t/index_merge.test281
-rw-r--r--mysql-test/t/index_merge_bdb.test52
-rw-r--r--mysql-test/t/index_merge_innodb.test54
-rw-r--r--mysql-test/t/index_merge_innodb2.test52
-rw-r--r--mysql-test/t/index_merge_ror.test249
-rw-r--r--mysql-test/t/index_merge_ror_cpk.test108
-rw-r--r--mysql-test/t/innodb.test28
-rw-r--r--mysql-test/t/insert.test39
-rw-r--r--mysql-test/t/join_nested.test754
-rw-r--r--mysql-test/t/join_outer.test27
-rw-r--r--mysql-test/t/key.test6
-rw-r--r--mysql-test/t/keywords.test8
-rw-r--r--mysql-test/t/lowercase_view-master.opt1
-rw-r--r--mysql-test/t/lowercase_view.test34
-rw-r--r--mysql-test/t/merge.test2
-rw-r--r--mysql-test/t/mix_innodb_myisam_binlog.test38
-rw-r--r--mysql-test/t/multi_update.test50
-rw-r--r--mysql-test/t/mysqlbinlog.test4
-rw-r--r--mysql-test/t/mysqlbinlog2.test16
-rw-r--r--mysql-test/t/mysqldump.test11
-rw-r--r--mysql-test/t/null.test7
-rw-r--r--mysql-test/t/null_key.test2
-rw-r--r--mysql-test/t/ps_1general.test5
-rw-r--r--mysql-test/t/query_cache.test21
-rw-r--r--mysql-test/t/range.test29
-rw-r--r--mysql-test/t/rowid_order_bdb.test108
-rw-r--r--mysql-test/t/rowid_order_innodb.test108
-rw-r--r--mysql-test/t/rpl000010-slave.opt2
-rw-r--r--mysql-test/t/rpl000015.test10
-rw-r--r--mysql-test/t/rpl000017.test2
-rw-r--r--mysql-test/t/rpl000018.test2
-rw-r--r--mysql-test/t/rpl_auto_increment-master.opt1
-rw-r--r--mysql-test/t/rpl_auto_increment.test104
-rw-r--r--mysql-test/t/rpl_change_master.test4
-rw-r--r--mysql-test/t/rpl_charset.test21
-rw-r--r--mysql-test/t/rpl_empty_master_crash.test2
-rw-r--r--mysql-test/t/rpl_error_ignored_table.test4
-rw-r--r--mysql-test/t/rpl_flush_log_loop.test2
-rw-r--r--mysql-test/t/rpl_heap.test2
-rw-r--r--mysql-test/t/rpl_loaddata.test8
-rw-r--r--mysql-test/t/rpl_loaddata_rule_m.test2
-rw-r--r--mysql-test/t/rpl_loaddata_rule_s.test2
-rw-r--r--mysql-test/t/rpl_log.test9
-rw-r--r--mysql-test/t/rpl_log_pos.test10
-rw-r--r--mysql-test/t/rpl_max_relay_size.test12
-rw-r--r--mysql-test/t/rpl_openssl.test4
-rw-r--r--mysql-test/t/rpl_redirect.test2
-rw-r--r--mysql-test/t/rpl_relayrotate-slave.opt3
-rw-r--r--mysql-test/t/rpl_relayrotate.test6
-rw-r--r--mysql-test/t/rpl_replicate_do.test2
-rw-r--r--mysql-test/t/rpl_reset_slave.test8
-rw-r--r--mysql-test/t/rpl_rotate_logs.test8
-rw-r--r--mysql-test/t/rpl_session_var.test42
-rw-r--r--mysql-test/t/rpl_trunc_binlog.test2
-rw-r--r--mysql-test/t/rpl_until.test10
-rw-r--r--mysql-test/t/rpl_user_variables.test2
-rw-r--r--mysql-test/t/schema.test8
-rw-r--r--mysql-test/t/select.test1
-rw-r--r--mysql-test/t/show_check.test17
-rw-r--r--mysql-test/t/sp-error.test638
-rw-r--r--mysql-test/t/sp-security.test216
-rw-r--r--mysql-test/t/sp-threads.test54
-rw-r--r--mysql-test/t/sp.test2343
-rw-r--r--mysql-test/t/sql_mode.test95
-rw-r--r--mysql-test/t/strict.test639
-rw-r--r--mysql-test/t/subselect.test5
-rw-r--r--mysql-test/t/sum_distinct.test188
-rw-r--r--mysql-test/t/system_mysql_db_fix.test2
-rw-r--r--mysql-test/t/trigger.test209
-rw-r--r--mysql-test/t/user_var.test3
-rw-r--r--mysql-test/t/variables.test16
-rw-r--r--mysql-test/t/view.test1560
-rw-r--r--mysql-test/t/view_skip_grants-master.opt1
-rw-r--r--mysql-test/t/view_skip_grants.test14
84 files changed, 9223 insertions, 160 deletions
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index 3c1f18b7524..a3862786cc3 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -326,9 +326,9 @@ drop table t1,t2;
CREATE TABLE t1 (
html varchar(5) default NULL,
rin int(11) default '0',
- out int(11) default '0'
+ rout int(11) default '0'
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('1',1,0);
-SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
+SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
drop table t1;
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 88c47803f48..6f0e5b3f14c 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -2,6 +2,8 @@
--disable_warnings
drop table if exists t1;
drop database if exists mysqltest;
+# If earlier test failed
+drop database if exists client_test_db;
--enable_warnings
--error 1051;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 8d8779e9d1b..e67d4fa3757 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -224,6 +224,7 @@ insert into t2 values('DEN','Denver','CO','BDL');
insert into t2 values('SDC','San Diego','CA','TWU');
insert into t2 values('NOL','New Orleans','LA','GTM');
insert into t2 values('LAK','Los Angeles','CA','TWU');
+insert into t2 values('AAA','AAA','AA','AME');
# Show the table contents
select * from t1;
diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test
index 2ae3c438243..3f547739679 100644
--- a/mysql-test/t/func_sapdb.test
+++ b/mysql-test/t/func_sapdb.test
@@ -30,10 +30,16 @@ select adddate("1997-12-31 23:59:59.000001", 10);
select subdate("1997-12-31 23:59:59.000001", 10);
select datediff("1997-12-31 23:59:59.000001","1997-12-30");
+select datediff("1997-11-30 23:59:59.000001","1997-12-31");
+SET @@SQL_MODE="ALLOW_INVALID_DATES";
select datediff("1997-11-31 23:59:59.000001","1997-12-31");
-select datediff("1997-11-31 23:59:59.000001",null);
+SET @@SQL_MODE="";
-select weekofyear("1997-11-31 23:59:59.000001");
+-- This will give a warning
+select datediff("1997-11-31 23:59:59.000001","1997-12-31");
+select datediff("1997-11-30 23:59:59.000001",null);
+
+select weekofyear("1997-11-30 23:59:59.000001");
select makedate(1997,1);
select makedate(1997,0);
@@ -106,7 +112,8 @@ insert into test values
SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test;
# PS doesn't support fractional seconds
--disable_ps_protocol
-SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
+SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq,
+ TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test;
--enable_ps_protocol
drop table t1, test;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 67192c55ef9..0ca3d86818e 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -255,6 +255,30 @@ select date_add(date,INTERVAL "1 1" YEAR_MONTH) from t1;
select date_add(date,INTERVAL "1:1:1" HOUR_SECOND) from t1;
select date_add(date,INTERVAL "1 1:1" DAY_MINUTE) from t1;
select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1;
+select date_add(date,INTERVAL "1" WEEK) from t1;
+select date_add(date,INTERVAL "1" QUARTER) from t1;
+select timestampadd(MINUTE, 1, date) from t1;
+select timestampadd(WEEK, 1, date) from t1;
+select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
+select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1;
+
+select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a;
+select timestampdiff(YEAR, '2002-05-01', '2001-01-01') as a;
+select timestampdiff(QUARTER, '2002-05-01', '2001-01-01') as a;
+select timestampdiff(MONTH, '2000-03-28', '2000-02-29') as a;
+select timestampdiff(MONTH, '1991-03-28', '2000-02-29') as a;
+select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a;
+select timestampdiff(SQL_TSI_HOUR, '2001-02-01', '2001-05-01') as a;
+select timestampdiff(SQL_TSI_DAY, '2001-02-01', '2001-05-01') as a;
+select timestampdiff(SQL_TSI_MINUTE, '2001-02-01 12:59:59', '2001-05-01 12:58:59') as a;
+select timestampdiff(SQL_TSI_SECOND, '2001-02-01 12:59:59', '2001-05-01 12:58:58') as a;
+select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a;
+
+select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1,
+ timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2,
+ timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3,
+ timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4;
+
select date_add(time,INTERVAL 1 SECOND) from t1;
drop table t1;
@@ -296,3 +320,5 @@ INSERT INTO t1 VALUES (NOW());
SELECT count(*) FROM t1 WHERE d>FROM_DAYS(TO_DAYS(@TMP)) AND d<=FROM_DAYS(TO_DAYS(@TMP)+1);
DROP TABLE t1;
+explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
+ timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index d9c281cfebc..4b1601c245f 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -258,3 +258,8 @@ DROP DATABASE testdb8;
DROP DATABASE testdb9;
DROP DATABASE testdb10;
+
+#
+# just SHOW PRIVILEGES test
+#
+SHOW PRIVILEGES;
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index f86be0c95b9..fe4a5b55b82 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -29,6 +29,15 @@ select current_user;
grant all privileges on `my\_1`.* to mysqltest_2@localhost with grant option;
--error 1044
grant all privileges on `my_%`.* to mysqltest_3@localhost with grant option;
+#
+# NO_AUTO_CREATE_USER mode
+#
+set @@sql_mode='NO_AUTO_CREATE_USER';
+select @@sql_mode;
+--error 1211
+grant select on `my\_1`.* to mysqltest_4@localhost with grant option;
+grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass'
+with grant option;
disconnect user1;
connection default;
show grants for mysqltest_1@localhost;
diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test
index e5bde977bb7..1ec4a52fdd1 100644
--- a/mysql-test/t/grant_cache.test
+++ b/mysql-test/t/grant_cache.test
@@ -10,7 +10,7 @@ drop database if exists mysqltest;
reset query cache;
flush status;
-connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection root;
show grants for current_user;
show grants;
@@ -25,7 +25,7 @@ insert into mysqltest.t2 values (3,3,3);
create table test.t1 (a char (10));
insert into test.t1 values ("test.t1");
select * from t1;
-connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,master.sock);
+connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection root2;
# put queries in cache
select * from t1;
@@ -43,7 +43,7 @@ grant SELECT on test.t1 to mysqltest_2@localhost;
grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
# The following queries should be fetched from cache
-connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,master.sock);
+connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user1;
show grants for current_user();
show status like "Qcache_queries_in_cache";
@@ -68,12 +68,12 @@ show status like "Qcache_hits";
show status like "Qcache_not_cached";
# Don't use '' as user because it will pick Unix login
-connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,master.sock);
+connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,$MASTER_MYSOCK);
connection unkuser;
show grants for current_user();
# The following queries should be fetched from cache
-connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,master.sock);
+connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user2;
select "user2";
select * from t1;
@@ -88,7 +88,7 @@ show status like "Qcache_hits";
show status like "Qcache_not_cached";
# The following queries should not be fetched from cache
-connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,master.sock);
+connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user3;
select "user3";
--replace_result 127.0.0.1 localhost
@@ -109,7 +109,7 @@ show status like "Qcache_hits";
show status like "Qcache_not_cached";
# Connect without a database
-connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,master.sock);
+connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user4;
select "user4";
show grants;
diff --git a/mysql-test/t/greedy_optimizer.test b/mysql-test/t/greedy_optimizer.test
new file mode 100644
index 00000000000..e547d85b7f3
--- /dev/null
+++ b/mysql-test/t/greedy_optimizer.test
@@ -0,0 +1,313 @@
+#
+# A simple test of the greedy query optimization algorithm and the switches that
+# control the optimizationprocess.
+#
+
+#
+# Schema
+#
+--disable_warnings
+drop table if exists t1,t2,t3,t4,t5,t6,t7;
+--enable_warnings
+
+create table t1 (
+ c11 integer,c12 integer,c13 integer,c14 integer,c15 integer,c16 integer,
+ primary key (c11)
+);
+create table t2 (
+ c21 integer,c22 integer,c23 integer,c24 integer,c25 integer,c26 integer
+);
+create table t3 (
+ c31 integer,c32 integer,c33 integer,c34 integer,c35 integer,c36 integer,
+ primary key (c31)
+);
+create table t4 (
+ c41 integer,c42 integer,c43 integer,c44 integer,c45 integer,c46 integer
+);
+create table t5 (
+ c51 integer,c52 integer,c53 integer,c54 integer,c55 integer,c56 integer,
+ primary key (c51)
+);
+create table t6 (
+ c61 integer,c62 integer,c63 integer,c64 integer,c65 integer,c66 integer
+);
+create table t7 (
+ c71 integer,c72 integer,c73 integer,c74 integer,c75 integer,c76 integer,
+ primary key (c71)
+);
+
+#
+# Data
+# cardinality(Ti) = cardinality(T(i-1)) + 3
+#
+insert into t1 values (1,2,3,4,5,6);
+insert into t1 values (2,2,3,4,5,6);
+insert into t1 values (3,2,3,4,5,6);
+
+insert into t2 values (1,2,3,4,5,6);
+insert into t2 values (2,2,3,4,5,6);
+insert into t2 values (3,2,3,4,5,6);
+insert into t2 values (4,2,3,4,5,6);
+insert into t2 values (5,2,3,4,5,6);
+insert into t2 values (6,2,3,4,5,6);
+
+insert into t3 values (1,2,3,4,5,6);
+insert into t3 values (2,2,3,4,5,6);
+insert into t3 values (3,2,3,4,5,6);
+insert into t3 values (4,2,3,4,5,6);
+insert into t3 values (5,2,3,4,5,6);
+insert into t3 values (6,2,3,4,5,6);
+insert into t3 values (7,2,3,4,5,6);
+insert into t3 values (8,2,3,4,5,6);
+insert into t3 values (9,2,3,4,5,6);
+
+insert into t4 values (1,2,3,4,5,6);
+insert into t4 values (2,2,3,4,5,6);
+insert into t4 values (3,2,3,4,5,6);
+insert into t4 values (4,2,3,4,5,6);
+insert into t4 values (5,2,3,4,5,6);
+insert into t4 values (6,2,3,4,5,6);
+insert into t4 values (7,2,3,4,5,6);
+insert into t4 values (8,2,3,4,5,6);
+insert into t4 values (9,2,3,4,5,6);
+insert into t4 values (10,2,3,4,5,6);
+insert into t4 values (11,2,3,4,5,6);
+insert into t4 values (12,2,3,4,5,6);
+
+insert into t5 values (1,2,3,4,5,6);
+insert into t5 values (2,2,3,4,5,6);
+insert into t5 values (3,2,3,4,5,6);
+insert into t5 values (4,2,3,4,5,6);
+insert into t5 values (5,2,3,4,5,6);
+insert into t5 values (6,2,3,4,5,6);
+insert into t5 values (7,2,3,4,5,6);
+insert into t5 values (8,2,3,4,5,6);
+insert into t5 values (9,2,3,4,5,6);
+insert into t5 values (10,2,3,4,5,6);
+insert into t5 values (11,2,3,4,5,6);
+insert into t5 values (12,2,3,4,5,6);
+insert into t5 values (13,2,3,4,5,6);
+insert into t5 values (14,2,3,4,5,6);
+insert into t5 values (15,2,3,4,5,6);
+
+insert into t6 values (1,2,3,4,5,6);
+insert into t6 values (2,2,3,4,5,6);
+insert into t6 values (3,2,3,4,5,6);
+insert into t6 values (4,2,3,4,5,6);
+insert into t6 values (5,2,3,4,5,6);
+insert into t6 values (6,2,3,4,5,6);
+insert into t6 values (7,2,3,4,5,6);
+insert into t6 values (8,2,3,4,5,6);
+insert into t6 values (9,2,3,4,5,6);
+insert into t6 values (10,2,3,4,5,6);
+insert into t6 values (11,2,3,4,5,6);
+insert into t6 values (12,2,3,4,5,6);
+insert into t6 values (13,2,3,4,5,6);
+insert into t6 values (14,2,3,4,5,6);
+insert into t6 values (15,2,3,4,5,6);
+insert into t6 values (16,2,3,4,5,6);
+insert into t6 values (17,2,3,4,5,6);
+insert into t6 values (18,2,3,4,5,6);
+
+insert into t7 values (1,2,3,4,5,6);
+insert into t7 values (2,2,3,4,5,6);
+insert into t7 values (3,2,3,4,5,6);
+insert into t7 values (4,2,3,4,5,6);
+insert into t7 values (5,2,3,4,5,6);
+insert into t7 values (6,2,3,4,5,6);
+insert into t7 values (7,2,3,4,5,6);
+insert into t7 values (8,2,3,4,5,6);
+insert into t7 values (9,2,3,4,5,6);
+insert into t7 values (10,2,3,4,5,6);
+insert into t7 values (11,2,3,4,5,6);
+insert into t7 values (12,2,3,4,5,6);
+insert into t7 values (13,2,3,4,5,6);
+insert into t7 values (14,2,3,4,5,6);
+insert into t7 values (15,2,3,4,5,6);
+insert into t7 values (16,2,3,4,5,6);
+insert into t7 values (17,2,3,4,5,6);
+insert into t7 values (18,2,3,4,5,6);
+insert into t7 values (19,2,3,4,5,6);
+insert into t7 values (20,2,3,4,5,6);
+insert into t7 values (21,2,3,4,5,6);
+
+#
+# The actual test begins here
+#
+
+# Check the default values for the optimizer paramters
+
+select @@optimizer_search_depth;
+select @@optimizer_prune_level;
+
+-- This value swithes back to the old implementation of 'find_best()'
+-- set optimizer_search_depth=63; - old (independent of the optimizer_prune_level)
+--
+-- These are the values for the parameters that control the greedy optimizer
+-- (total 6 combinations - 3 for optimizer_search_depth, 2 for optimizer_prune_level):
+--
+-- set optimizer_search_depth=0; - automatic
+-- set optimizer_search_depth=1; - min
+-- set optimizer_search_depth=62; - max (default)
+--
+-- set optimizer_prune_level=0 - exhaustive;
+-- set optimizer_prune_level=1 - heuristic; -- default
+
+
+#
+# Compile several queries with all combinations of the query
+# optimizer parameters. Each test query has two variants, where
+# in the second variant the tables in the FROM clause are in
+# inverse order to the tables in the first variant.
+# Due to pre-sorting of tables before compilation, there should
+# be no difference in the plans for each two such query variants.
+#
+
+# First, for reference compile the test queries with the 'old' optimization
+# procedure 'find_best'. Notice that 'find_best' does not depend on the
+# choice of heuristic.
+
+set optimizer_search_depth=63;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+
+# Test the new optimization procedures
+
+set optimizer_prune_level=0;
+select @@optimizer_prune_level;
+
+set optimizer_search_depth=0;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+set optimizer_search_depth=1;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+set optimizer_search_depth=62;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+
+set optimizer_prune_level=1;
+select @@optimizer_prune_level;
+
+set optimizer_search_depth=0;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+set optimizer_search_depth=1;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+set optimizer_search_depth=62;
+select @@optimizer_search_depth;
+
+-- 6-table join, chain
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, star
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71;
+show status like 'Last_query_cost';
+-- 6-table join, clique
+explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76;
+show status like 'Last_query_cost';
+
+drop table t1,t2,t3,t4,t5,t6,t7;
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
new file mode 100644
index 00000000000..0eb6fc49990
--- /dev/null
+++ b/mysql-test/t/group_min_max.test
@@ -0,0 +1,605 @@
+#
+# Test file for WL#1724 (Min/Max Optimization for Queries with Group By Clause).
+# The queries in this file test query execution via QUICK_GROUP_MIN_MAX_SELECT.
+#
+
+#
+# TODO:
+# Add queries with:
+# - C != const
+# - C IS NOT NULL
+# - HAVING clause
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (
+ a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+
+-- t2 is the same as t1, but with some NULLs in the MIN/MAX column, and one more
+-- nullable attribute
+
+--disable_warnings
+drop table if exists t2;
+--enable_warnings
+
+create table t2 (
+ a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+-- add few rows with NULL's in the MIN/MAX column
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+
+-- Table t3 is the same as t1, but with smaller column lenghts.
+-- This allows to test different branches of the cost computation procedure
+-- when the number of keys per block are less than the number of keys in the
+-- sub-groups formed by predicates over non-group attributes.
+
+--disable_warnings
+drop table if exists t3;
+--enable_warnings
+
+create table t3 (
+ a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+
+
+--
+-- Queries without a WHERE clause. These queries do not use ranges.
+--
+
+-- plans
+explain select a1, min(a2) from t1 group by a1;
+explain select a1, max(a2) from t1 group by a1;
+explain select a1, min(a2), max(a2) from t1 group by a1;
+explain select a1, a2, b, min(c), max(c) from t1 group by a1,a2,b;
+explain select a1,a2,b,max(c),min(c) from t1 group by a1,a2,b;
+explain select a1,a2,b,max(c),min(c) from t2 group by a1,a2,b;
+-- Select fields in different order
+explain select min(a2), a1, max(a2), min(a2), a1 from t1 group by a1;
+explain select a1, b, min(c), a1, max(c), b, a2, max(c), max(c) from t1 group by a1, a2, b;
+explain select min(a2) from t1 group by a1;
+explain select a2, min(c), max(c) from t1 group by a1,a2,b;
+
+-- queries
+select a1, min(a2) from t1 group by a1;
+select a1, max(a2) from t1 group by a1;
+select a1, min(a2), max(a2) from t1 group by a1;
+select a1, a2, b, min(c), max(c) from t1 group by a1,a2,b;
+select a1,a2,b,max(c),min(c) from t1 group by a1,a2,b;
+select a1,a2,b,max(c),min(c) from t2 group by a1,a2,b;
+-- Select fields in different order
+select min(a2), a1, max(a2), min(a2), a1 from t1 group by a1;
+select a1, b, min(c), a1, max(c), b, a2, max(c), max(c) from t1 group by a1, a2, b;
+select min(a2) from t1 group by a1;
+select a2, min(c), max(c) from t1 group by a1,a2,b;
+
+--
+-- Queries with a where clause
+--
+
+-- A) Preds only over the group 'A' attributes
+-- plans
+explain select a1,a2,b,min(c),max(c) from t1 where a1 < 'd' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where a1 >= 'b' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+explain select a1, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where a1 >= 'c' or a2 < 'b' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+explain select a1,min(c),max(c) from t1 where a1 >= 'b' group by a1,a2,b;
+explain select a1, max(c) from t1 where a1 in ('a','b','d') group by a1,a2,b;
+
+explain select a1,a2,b, max(c) from t2 where a1 < 'd' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where a1 < 'd' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where a1 >= 'b' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+explain select a1, max(c) from t2 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where a1 >= 'c' or a2 < 'b' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+explain select a1,min(c),max(c) from t2 where a1 >= 'b' group by a1,a2,b;
+explain select a1, max(c) from t2 where a1 in ('a','b','d') group by a1,a2,b;
+
+-- queries
+select a1,a2,b,min(c),max(c) from t1 where a1 < 'd' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where a1 >= 'b' group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+select a1, max(c) from t1 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where a1 >= 'c' or a2 < 'b' group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+select a1,min(c),max(c) from t1 where a1 >= 'b' group by a1,a2,b;
+select a1, max(c) from t1 where a1 in ('a','b','d') group by a1,a2,b;
+
+select a1,a2,b, max(c) from t2 where a1 < 'd' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where a1 < 'd' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where a1 >= 'b' group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+select a1, max(c) from t2 where a1 >= 'c' or a1 < 'b' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where a1 >= 'c' or a2 < 'b' group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where a1 = 'z' or a1 = 'b' or a1 = 'd' group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') group by a1,a2,b;
+select a1,min(c),max(c) from t2 where a1 >= 'b' group by a1,a2,b;
+select a1, max(c) from t2 where a1 in ('a','b','d') group by a1,a2,b;
+
+-- B) Equalities only over the non-group 'B' attributes
+-- plans
+explain select a1,a2,b,max(c),min(c) from t1 where (a2 = 'a') and (b = 'b') group by a1;
+explain select a1,max(c),min(c) from t1 where (a2 = 'a') and (b = 'b') group by a1;
+explain select a1,a2,b, max(c) from t1 where (b = 'b') group by a1,a2;
+explain select a1,a2,b,min(c),max(c) from t1 where (b = 'b') group by a1,a2;
+explain select a1,a2, max(c) from t1 where (b = 'b') group by a1,a2;
+
+explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') group by a1;
+explain select a1,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') group by a1;
+explain select a1,a2,b, max(c) from t2 where (b = 'b') group by a1,a2;
+explain select a1,a2,b,min(c),max(c) from t2 where (b = 'b') group by a1,a2;
+explain select a1,a2, max(c) from t2 where (b = 'b') group by a1,a2;
+
+-- these queries test case 2) in TRP_GROUP_MIN_MAX::update_cost()
+explain select a1,a2,b,max(c),min(c) from t3 where (a2 = 'a') and (b = 'b') group by a1;
+explain select a1,max(c),min(c) from t3 where (a2 = 'a') and (b = 'b') group by a1;
+
+-- queries
+select a1,a2,b,max(c),min(c) from t1 where (a2 = 'a') and (b = 'b') group by a1;
+select a1,max(c),min(c) from t1 where (a2 = 'a') and (b = 'b') group by a1;
+select a1,a2,b, max(c) from t1 where (b = 'b') group by a1,a2;
+select a1,a2,b,min(c),max(c) from t1 where (b = 'b') group by a1,a2;
+select a1,a2, max(c) from t1 where (b = 'b') group by a1,a2;
+
+select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') group by a1;
+select a1,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') group by a1;
+select a1,a2,b, max(c) from t2 where (b = 'b') group by a1,a2;
+select a1,a2,b,min(c),max(c) from t2 where (b = 'b') group by a1,a2;
+select a1,a2, max(c) from t2 where (b = 'b') group by a1,a2;
+
+-- these queries test case 2) in TRP_GROUP_MIN_MAX::update_cost()
+select a1,a2,b,max(c),min(c) from t3 where (a2 = 'a') and (b = 'b') group by a1;
+select a1,max(c),min(c) from t3 where (a2 = 'a') and (b = 'b') group by a1;
+
+
+-- IS NULL (makes sense for t2 only)
+-- plans
+explain select a1,a2,b,min(c) from t2 where (a2 = 'a') and b is NULL group by a1;
+explain select a1,a2,b,max(c) from t2 where (a2 = 'a') and b is NULL group by a1;
+explain select a1,a2,b,min(c) from t2 where b is NULL group by a1,a2;
+explain select a1,a2,b,max(c) from t2 where b is NULL group by a1,a2;
+explain select a1,a2,b,min(c),max(c) from t2 where b is NULL group by a1,a2;
+explain select a1,a2,b,min(c),max(c) from t2 where b is NULL group by a1,a2;
+-- queries
+select a1,a2,b,min(c) from t2 where (a2 = 'a') and b is NULL group by a1;
+select a1,a2,b,max(c) from t2 where (a2 = 'a') and b is NULL group by a1;
+select a1,a2,b,min(c) from t2 where b is NULL group by a1,a2;
+select a1,a2,b,max(c) from t2 where b is NULL group by a1,a2;
+select a1,a2,b,min(c),max(c) from t2 where b is NULL group by a1,a2;
+select a1,a2,b,min(c),max(c) from t2 where b is NULL group by a1,a2;
+
+-- C) Range predicates for the MIN/MAX attribute
+-- plans
+explain select a1,a2,b, max(c) from t1 where (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (c > 'f123') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c > 'f123') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (c < 'a0') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c < 'a0') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (c < 'k321') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c < 'k321') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c < 'c5') or (c = 'g412') or (c = 'k421') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where ((c > 'b111') and (c <= 'g112')) or ((c > 'd000') and (c <= 'i110')) group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (c between 'b111' and 'g112') or (c between 'd000' and 'i110') group by a1,a2,b;
+
+explain select a1,a2,b, max(c) from t2 where (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (c > 'f123') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c > 'f123') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (c < 'a0') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c < 'a0') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (c < 'k321') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c < 'k321') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (c < 'c5') or (c = 'g412') or (c = 'k421') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where ((c > 'b111') and (c <= 'g112')) or ((c > 'd000') and (c <= 'i110')) group by a1,a2,b;
+
+-- queries
+select a1,a2,b, max(c) from t1 where (c > 'b1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (c > 'f123') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c > 'f123') group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (c < 'a0') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c < 'a0') group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (c < 'k321') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c < 'k321') group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c < 'c5') or (c = 'g412') or (c = 'k421') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where ((c > 'b111') and (c <= 'g112')) or ((c > 'd000') and (c <= 'i110')) group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (c between 'b111' and 'g112') or (c between 'd000' and 'i110') group by a1,a2,b;
+
+select a1,a2,b, max(c) from t2 where (c > 'b1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (c > 'f123') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c > 'f123') group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (c < 'a0') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c < 'a0') group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (c < 'k321') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c < 'k321') group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c < 'a0') or (c > 'b1') group by a1,a2,b;
+select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (c < 'c5') or (c = 'g412') or (c = 'k421') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where ((c > 'b111') and (c <= 'g112')) or ((c > 'd000') and (c <= 'i110')) group by a1,a2,b;
+
+-- analyze the sub-select
+explain select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c = t1.c )
+group by a1,a2,b;
+
+-- the sub-select is unrelated to MIN/MAX
+explain select a1,a2,b,min(c),max(c) from t1
+where exists ( select * from t2 where t2.c > 'b1' )
+group by a1,a2,b;
+
+
+-- A,B,C) Predicates referencing mixed classes of attributes
+-- plans
+explain select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (c > 'b111') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t1 where (a2 >= 'b') and (b = 'a') and (c > 'b111') group by a1,a2,b;
+explain select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c < 'h112') or (c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122')) group by a1,a2,b;
+explain select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122') or (c < 'h112') or (c = 'c111')) group by a1,a2,b;
+explain select a1,a2,b,min(c) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+explain select a1,a2,b,min(c) from t1 where (ord(a1) > 97) and (ord(a2) + ord(a1) > 194) and (b = 'c') group by a1,a2,b;
+
+explain select a1,a2,b,min(c),max(c) from t2 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (a1 >= 'c' or a2 < 'b') and (c > 'b111') group by a1,a2,b;
+explain select a1,a2,b,min(c),max(c) from t2 where (a2 >= 'b') and (b = 'a') and (c > 'b111') group by a1,a2,b;
+explain select a1,a2,b,min(c) from t2 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c < 'h112') or (c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122')) group by a1,a2,b;
+explain select a1,a2,b,min(c) from t2 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122') or (c < 'h112') or (c = 'c111')) group by a1,a2,b;
+explain select a1,a2,b,min(c) from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+-- queries
+select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (c > 'b111') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t1 where (a2 >= 'b') and (b = 'a') and (c > 'b111') group by a1,a2,b;
+select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c < 'h112') or (c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122')) group by a1,a2,b;
+select a1,a2,b,min(c) from t1 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122') or (c < 'h112') or (c = 'c111')) group by a1,a2,b;
+select a1,a2,b,min(c) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+select a1,a2,b,min(c) from t1 where (ord(a1) > 97) and (ord(a2) + ord(a1) > 194) and (b = 'c') group by a1,a2,b;
+
+select a1,a2,b,min(c),max(c) from t2 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (a1 >= 'c' or a2 < 'b') and (c > 'b111') group by a1,a2,b;
+select a1,a2,b,min(c),max(c) from t2 where (a2 >= 'b') and (b = 'a') and (c > 'b111') group by a1,a2,b;
+select a1,a2,b,min(c) from t2 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c < 'h112') or (c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122')) group by a1,a2,b;
+select a1,a2,b,min(c) from t2 where ((a1 > 'a') or (a1 < '9')) and ((a2 >= 'b') and (a2 < 'z')) and (b = 'a') and ((c = 'j121') or (c > 'k121' and c < 'm122') or (c > 'o122') or (c < 'h112') or (c = 'c111')) group by a1,a2,b;
+select a1,a2,b,min(c) from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+
+--
+-- GROUP BY queries without MIN/MAX
+--
+
+-- plans
+explain select a1,a2,b from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+explain select a1,a2,b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+explain select a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+explain select a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+explain select a1,a2,b from t2 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+explain select a1,a2,b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+explain select a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+explain select a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+-- queries
+select a1,a2,b from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+select a1,a2,b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+select a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+select a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+select a1,a2,b from t2 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
+select a1,a2,b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+select a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+select a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+
+
+--
+-- DISTINCT queries
+--
+
+-- plans
+explain select distinct a1,a2,b from t1;
+explain select distinct a1,a2,b from t1 where (a2 >= 'b') and (b = 'a');
+explain select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+explain select distinct b from t1 where (a2 >= 'b') and (b = 'a');
+
+explain select distinct a1,a2,b from t2;
+explain select distinct a1,a2,b from t2 where (a2 >= 'b') and (b = 'a');
+explain select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+explain select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+explain select distinct b from t2 where (a2 >= 'b') and (b = 'a');
+
+-- queries
+select distinct a1,a2,b from t1;
+select distinct a1,a2,b from t1 where (a2 >= 'b') and (b = 'a');
+select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+select distinct b from t1 where (a2 >= 'b') and (b = 'a');
+
+select distinct a1,a2,b from t2;
+select distinct a1,a2,b from t2 where (a2 >= 'b') and (b = 'a');
+select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+select distinct b from t2 where (a2 >= 'b') and (b = 'a');
+
+-- BUG 6303
+select distinct t_00.a1
+from t1 t_00
+where exists ( select * from t2 where a1 = t_00.a1 );
+
+
+--
+-- DISTINCT queries with GROUP-BY
+--
+
+-- plans
+explain select distinct a1,a2,b from t1;
+explain select distinct a1,a2,b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+explain select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+explain select distinct b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+
+explain select distinct a1,a2,b from t2;
+explain select distinct a1,a2,b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+explain select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+explain select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+explain select distinct b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+
+-- queries
+select distinct a1,a2,b from t1;
+select distinct a1,a2,b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+select distinct b from t1 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+
+select distinct a1,a2,b from t2;
+select distinct a1,a2,b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121') group by a1,a2,b;
+select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
+select distinct b from t2 where (a2 >= 'b') and (b = 'a') group by a1,a2,b;
+
+
+--
+-- COUNT (DISTINCT cols) queries
+--
+
+explain select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a');
+explain select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+explain select count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+explain select count(distinct b) from t1 where (a2 >= 'b') and (b = 'a');
+explain select ord(a1) + count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a');
+
+select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a');
+select count(distinct a1,a2,b,c) from t1 where (a2 >= 'b') and (b = 'a') and (c = 'i121');
+select count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
+select count(distinct b) from t1 where (a2 >= 'b') and (b = 'a');
+select ord(a1) + count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2 > 'a');
+
+--
+-- Queries with expressions in the select clause
+--
+
+explain select a1,a2,b, concat(min(c), max(c)) from t1 where a1 < 'd' group by a1,a2,b;
+explain select concat(a1,min(c)),b from t1 where a1 < 'd' group by a1,a2,b;
+explain select concat(a1,min(c)),b,max(c) from t1 where a1 < 'd' group by a1,a2,b;
+explain select concat(a1,a2),b,min(c),max(c) from t1 where a1 < 'd' group by a1,a2,b;
+explain select concat(ord(min(b)),ord(max(b))),min(b),max(b) from t1 group by a1,a2;
+
+select a1,a2,b, concat(min(c), max(c)) from t1 where a1 < 'd' group by a1,a2,b;
+select concat(a1,min(c)),b from t1 where a1 < 'd' group by a1,a2,b;
+select concat(a1,min(c)),b,max(c) from t1 where a1 < 'd' group by a1,a2,b;
+select concat(a1,a2),b,min(c),max(c) from t1 where a1 < 'd' group by a1,a2,b;
+select concat(ord(min(b)),ord(max(b))),min(b),max(b) from t1 group by a1,a2;
+
+
+--
+-- Negative examples: queries that should NOT be treated as optimizable by
+-- QUICK_GROUP_MIN_MAX_SELECT
+--
+
+-- select a non-indexed attribute
+explain select a1,a2,b,d,min(c),max(c) from t1 group by a1,a2,b;
+
+explain select a1,a2,b,d from t1 group by a1,a2,b;
+
+-- predicate that references an attribute that is after the MIN/MAX argument
+-- in the index
+explain select a1,a2,min(b),max(b) from t1
+where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2;
+
+-- predicate that references a non-indexed attribute
+explain select a1,a2,b,min(c),max(c) from t1
+where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b;
+
+explain select a1,a2,b,c from t1
+where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b,c;
+
+-- non-equality predicate for a non-group select attribute
+explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') or (b < 'b') group by a1;
+explain select a1,a2,b from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a111') group by a1,a2,b;
+
+-- non-group field with an equality predicate that references a keypart after the
+-- MIN/MAX argument
+explain select a1,a2,min(b),c from t2 where (a2 = 'a') and (c = 'a111') group by a1;
+select a1,a2,min(b),c from t2 where (a2 = 'a') and (c = 'a111') group by a1;
+
+-- disjunction for a non-group select attribute
+explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') or (b = 'a') group by a1;
+
+-- non-range predicate for the MIN/MAX attribute
+explain select a1,a2,b,min(c),max(c) from t2
+where (c > 'a000') and (c <= 'd999') and (c like '_8__') group by a1,a2,b;
+
+-- not all attributes are indexed by one index
+explain select a1, a2, b, c, min(d), max(d) from t1 group by a1,a2,b,c;
+
+-- other aggregate functions than MIN/MAX
+explain select a1,a2,count(a2) from t1 group by a1,a2,b;
+explain select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b;
+explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;
+
+drop table t1;
+drop table t2;
+drop table t3;
+
+#
+# Bug #6142: a problem with the empty innodb table
+#
+
+create table t1 (
+ a varchar(30), b varchar(30), primary key(a), key(b)
+) engine=innodb;
+select distinct a from t1;
+drop table t1;
diff --git a/mysql-test/t/index_merge.test b/mysql-test/t/index_merge.test
new file mode 100644
index 00000000000..a4f7b71e5a3
--- /dev/null
+++ b/mysql-test/t/index_merge.test
@@ -0,0 +1,281 @@
+#
+# Index merge tests
+#
+
+--disable_warnings
+drop table if exists t0, t1, t2, t3,t4;
+--enable_warnings
+
+# Create and fill a table with simple keys
+create table t0
+(
+ key1 int not null,
+ INDEX i1(key1)
+);
+
+--disable_query_log
+insert into t0 values (1),(2),(3),(4),(5),(6),(7),(8);
+
+let $1=7;
+set @d=8;
+while ($1)
+{
+ eval insert into t0 select key1+@d from t0;
+ eval set @d=@d*2;
+ dec $1;
+}
+--enable_query_log
+
+alter table t0 add key2 int not null, add index i2(key2);
+alter table t0 add key3 int not null, add index i3(key3);
+alter table t0 add key4 int not null, add index i4(key4);
+alter table t0 add key5 int not null, add index i5(key5);
+alter table t0 add key6 int not null, add index i6(key6);
+alter table t0 add key7 int not null, add index i7(key7);
+alter table t0 add key8 int not null, add index i8(key8);
+
+update t0 set key2=key1,key3=key1,key4=key1,key5=key1,key6=key1,key7=key1,key8=1024-key1;
+analyze table t0;
+
+# 1. One index
+explain select * from t0 where key1 < 3 or key1 > 1020;
+
+# 2. Simple cases
+explain
+select * from t0 where key1 < 3 or key2 > 1020;
+select * from t0 where key1 < 3 or key2 > 1020;
+
+explain select * from t0 where key1 < 3 or key2 <4;
+
+explain
+select * from t0 where (key1 > 30 and key1<35) or (key2 >32 and key2 < 40);
+select * from t0 where (key1 > 30 and key1<35) or (key2 >32 and key2 < 40);
+
+# 3. Check that index_merge doesn't break "ignore/force/use index"
+explain select * from t0 ignore index (i2) where key1 < 3 or key2 <4;
+explain select * from t0 where (key1 < 3 or key2 <4) and key3 = 50;
+explain select * from t0 use index (i1,i2) where (key1 < 3 or key2 <4) and key3 = 50;
+
+explain select * from t0 where (key1 > 1 or key2 > 2);
+explain select * from t0 force index (i1,i2) where (key1 > 1 or key2 > 2);
+
+
+# 4. Check if conjuncts are grouped by keyuse
+explain
+ select * from t0 where key1<3 or key2<3 or (key1>5 and key1<8) or
+ (key1>10 and key1<12) or (key2>100 and key2<110);
+
+# 5. Check index_merge with conjuncts that are always true/false
+# verify fallback to "range" if there is only one non-confluent condition
+explain select * from t0 where key2 = 45 or key1 <=> null;
+
+explain select * from t0 where key2 = 45 or key1 is not null;
+explain select * from t0 where key2 = 45 or key1 is null;
+
+# the last conj. is always false and will be discarded
+explain select * from t0 where key2=10 or key3=3 or key4 <=> null;
+
+# the last conj. is always true and will cause 'all' scan
+explain select * from t0 where key2=10 or key3=3 or key4 is null;
+
+# some more complicated cases
+explain select key1 from t0 where (key1 <=> null) or (key2 < 5) or
+ (key3=10) or (key4 <=> null);
+explain select key1 from t0 where (key1 <=> null) or (key1 < 5) or
+ (key3=10) or (key4 <=> null);
+
+# 6.Several ways to do index_merge, (ignored) index_merge vs. range
+explain select * from t0 where
+ (key1 < 3 or key2 < 3) and (key3 < 4 or key4 < 4) and (key5 < 5 or key6 < 5);
+
+explain
+select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4);
+
+select * from t0 where (key1 < 3 or key2 < 6) and (key1 < 7 or key3 < 4);
+
+
+explain select * from t0 where
+ (key1 < 3 or key2 < 3) and (key3 < 4 or key4 < 4) and (key5 < 2 or key6 < 2);
+
+# now index_merge is not used at all when "range" is possible
+explain select * from t0 where
+ (key1 < 3 or key2 < 3) and (key3 < 100);
+
+# this even can cause "all" scan:
+explain select * from t0 where
+ (key1 < 3 or key2 < 3) and (key3 < 1000);
+
+
+# 7. Complex cases
+# tree_or(List<SEL_IMERGE>, range SEL_TREE).
+explain select * from t0 where
+ ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4))
+ or
+ key2 > 5;
+
+explain select * from t0 where
+ ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4))
+ or
+ key1 < 7;
+
+select * from t0 where
+ ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4))
+ or
+ key1 < 7;
+
+# tree_or(List<SEL_IMERGE>, List<SEL_IMERGE>).
+explain select * from t0 where
+ ((key1 < 4 or key2 < 4) and (key3 <5 or key5 < 4))
+ or
+ ((key5 < 5 or key6 < 6) and (key7 <7 or key8 < 4));
+
+explain select * from t0 where
+ ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4))
+ or
+ ((key7 <7 or key8 < 4) and (key5 < 5 or key6 < 6));
+
+explain select * from t0 where
+ ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4))
+ or
+ ((key3 <7 or key5 < 2) and (key5 < 5 or key6 < 6));
+
+explain select * from t0 where
+ ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4))
+ or
+ (((key3 <7 and key7 < 6) or key5 < 2) and (key5 < 5 or key6 < 6));
+
+explain select * from t0 where
+ ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4))
+ or
+ ((key3 >=5 or key5 < 2) and (key5 < 5 or key6 < 6));
+
+explain select * from t0 force index(i1, i2, i3, i4, i5, i6 ) where
+ ((key3 <5 or key5 < 4) and (key1 < 4 or key2 < 4))
+ or
+ ((key3 >=5 or key5 < 2) and (key5 < 5 or key6 < 6));
+
+# 8. Verify that "order by" after index merge uses filesort
+select * from t0 where key1 < 5 or key8 < 4 order by key1;
+
+explain
+select * from t0 where key1 < 5 or key8 < 4 order by key1;
+
+# 9. Check that index_merge cost is compared to 'index' where possible
+create table t2 like t0;
+insert into t2 select * from t0;
+
+alter table t2 add index i1_3(key1, key3);
+alter table t2 add index i2_3(key2, key3);
+alter table t2 drop index i1;
+alter table t2 drop index i2;
+alter table t2 add index i321(key3, key2, key1);
+
+# index_merge vs 'index', index_merge is better.
+explain select key3 from t2 where key1 = 100 or key2 = 100;
+
+# index_merge vs 'index', 'index' is better.
+explain select key3 from t2 where key1 <100 or key2 < 100;
+
+# index_merge vs 'all', index_merge is better.
+explain select key7 from t2 where key1 <100 or key2 < 100;
+
+# 10. Multipart keys.
+create table t4 (
+ key1a int not null,
+ key1b int not null,
+ key2 int not null,
+ key2_1 int not null,
+ key2_2 int not null,
+ key3 int not null,
+
+ index i1a (key1a, key1b),
+ index i1b (key1b, key1a),
+
+ index i2_1(key2, key2_1),
+ index i2_2(key2, key2_1)
+);
+
+insert into t4 select key1,key1,key1 div 10, key1 % 10, key1 % 10, key1 from t0;
+
+# the following will be handled by index_merge:
+select * from t4 where key1a = 3 or key1b = 4;
+explain select * from t4 where key1a = 3 or key1b = 4;
+
+# and the following will not
+explain select * from t4 where key2 = 1 and (key2_1 = 1 or key3 = 5);
+
+explain select * from t4 where key2 = 1 and (key2_1 = 1 or key2_2 = 5);
+
+explain select * from t4 where key2_1 = 1 or key2_2 = 5;
+
+
+# 11. Multitable selects
+create table t1 like t0;
+insert into t1 select * from t0;
+
+# index_merge on first table in join
+explain select * from t0 left join t1 on (t0.key1=t1.key1)
+ where t0.key1=3 or t0.key2=4;
+
+select * from t0 left join t1 on (t0.key1=t1.key1)
+ where t0.key1=3 or t0.key2=4;
+
+explain
+select * from t0,t1 where (t0.key1=t1.key1) and ( t0.key1=3 or t0.key2=4);
+
+# index_merge vs. ref
+explain
+select * from t0,t1 where (t0.key1=t1.key1) and
+ (t0.key1=3 or t0.key2=4) and t1.key1<200;
+
+# index_merge vs. ref
+explain
+select * from t0,t1 where (t0.key1=t1.key1) and
+ (t0.key1=3 or t0.key2<4) and t1.key1=2;
+
+# index_merge on second table in join
+explain select * from t0,t1 where t0.key1 = 5 and
+ (t1.key1 = t0.key1 or t1.key8 = t0.key1);
+
+# Fix for bug#1974
+explain select * from t0,t1 where t0.key1 < 3 and
+ (t1.key1 = t0.key1 or t1.key8 = t0.key1);
+
+# index_merge inside union
+explain select * from t1 where key1=3 or key2=4
+ union select * from t1 where key1<4 or key3=5;
+
+# index merge in subselect
+explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
+
+# 12. check for long index_merges.
+create table t3 like t0;
+insert into t3 select * from t0;
+alter table t3 add key9 int not null, add index i9(key9);
+alter table t3 add keyA int not null, add index iA(keyA);
+alter table t3 add keyB int not null, add index iB(keyB);
+alter table t3 add keyC int not null, add index iC(keyC);
+update t3 set key9=key1,keyA=key1,keyB=key1,keyC=key1;
+
+explain select * from t3 where
+ key1=1 or key2=2 or key3=3 or key4=4 or
+ key5=5 or key6=6 or key7=7 or key8=8 or
+ key9=9 or keyA=10 or keyB=11 or keyC=12;
+
+select * from t3 where
+ key1=1 or key2=2 or key3=3 or key4=4 or
+ key5=5 or key6=6 or key7=7 or key8=8 or
+ key9=9 or keyA=10 or keyB=11 or keyC=12;
+
+# Test for Bug#3183
+explain select * from t0 where key1 < 3 or key2 < 4;
+select * from t0 where key1 < 3 or key2 < 4;
+
+update t0 set key8=123 where key1 < 3 or key2 < 4;
+select * from t0 where key1 < 3 or key2 < 4;
+
+delete from t0 where key1 < 3 or key2 < 4;
+select * from t0 where key1 < 3 or key2 < 4;
+select count(*) from t0;
+
+drop table t0, t1, t2, t3, t4;
diff --git a/mysql-test/t/index_merge_bdb.test b/mysql-test/t/index_merge_bdb.test
new file mode 100644
index 00000000000..c49e6ab3175
--- /dev/null
+++ b/mysql-test/t/index_merge_bdb.test
@@ -0,0 +1,52 @@
+#
+# 2-sweeps read Index_merge test
+#
+-- source include/have_bdb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (
+ pk int primary key,
+ key1 int,
+ key2 int,
+ filler char(200),
+ filler2 char(200),
+ index(key1),
+ index(key2)
+) engine=bdb;
+
+
+--disable_query_log
+let $1=1000;
+while ($1)
+{
+ eval insert into t1 values($1, $1, $1, 'filler-data','filler-data-2');
+ dec $1;
+}
+--enable_query_log
+
+select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
+
+set @maxv=1000;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or key1=18 or key1=60;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or key1 < 3 or key1 > @maxv-11;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or
+ (key1 < 5) or (key1 > 10 and key1 < 15) or (key1 >= 50 and key1 < 55 ) or (key1 > @maxv-10);
+
+select * from t1 where
+ (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 )
+ or
+ (key1 < 5) or (key1 > @maxv-10);
+
+drop table t1;
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
new file mode 100644
index 00000000000..2da40c5719a
--- /dev/null
+++ b/mysql-test/t/index_merge_innodb.test
@@ -0,0 +1,54 @@
+#
+# Index merge tests
+#
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1
+(
+ key1 int not null,
+ key2 int not null,
+
+ INDEX i1(key1),
+ INDEX i2(key2)
+) engine=innodb;
+
+--disable_query_log
+let $1=200;
+while ($1)
+{
+ eval insert into t1 values (200-$1, $1);
+ dec $1;
+}
+--enable_query_log
+
+# No primary key
+explain select * from t1 where key1 < 5 or key2 > 197;
+
+select * from t1 where key1 < 5 or key2 > 197;
+
+explain select * from t1 where key1 < 3 or key2 > 195;
+select * from t1 where key1 < 3 or key2 > 195;
+
+# Primary key as case-sensitive string with \0s.
+# also make primary key be longer then max. index length of MyISAM.
+alter table t1 add str1 char (255) not null,
+ add zeroval int not null default 0,
+ add str2 char (255) not null,
+ add str3 char (255) not null;
+
+update t1 set str1='aaa', str2='bbb', str3=concat(key2, '-', key1 div 2, '_' ,if(key1 mod 2 = 0, 'a', 'A'));
+
+alter table t1 add primary key (str1, zeroval, str2, str3);
+
+explain select * from t1 where key1 < 5 or key2 > 197;
+
+select * from t1 where key1 < 5 or key2 > 197;
+
+explain select * from t1 where key1 < 3 or key2 > 195;
+select * from t1 where key1 < 3 or key2 > 195;
+
+drop table t1;
diff --git a/mysql-test/t/index_merge_innodb2.test b/mysql-test/t/index_merge_innodb2.test
new file mode 100644
index 00000000000..ec4ea672bc1
--- /dev/null
+++ b/mysql-test/t/index_merge_innodb2.test
@@ -0,0 +1,52 @@
+#
+# 2-sweeps read Index_merge test
+#
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (
+ pk int primary key,
+ key1 int,
+ key2 int,
+ filler char(200),
+ filler2 char(200),
+ index(key1),
+ index(key2)
+) engine=innodb;
+
+
+--disable_query_log
+let $1=1000;
+while ($1)
+{
+ eval insert into t1 values($1, $1, $1, 'filler-data','filler-data-2');
+ dec $1;
+}
+--enable_query_log
+
+select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
+
+set @maxv=1000;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or key1=18 or key1=60;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or key1 < 3 or key1 > @maxv-11;
+
+select * from t1 where
+ (pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
+ or
+ (key1 < 5) or (key1 > 10 and key1 < 15) or (key1 >= 50 and key1 < 55 ) or (key1 > @maxv-10);
+
+select * from t1 where
+ (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 )
+ or
+ (key1 < 5) or (key1 > @maxv-10);
+
+drop table t1;
diff --git a/mysql-test/t/index_merge_ror.test b/mysql-test/t/index_merge_ror.test
new file mode 100644
index 00000000000..223bd241d96
--- /dev/null
+++ b/mysql-test/t/index_merge_ror.test
@@ -0,0 +1,249 @@
+#
+# ROR-index_merge tests.
+#
+--disable_warnings
+drop table if exists t0,t1,t2;
+--enable_warnings
+--disable_query_log
+create table t1
+(
+ /* Field names reflect value(rowid) distribution, st=STairs, swt= SaWTooth */
+ st_a int not null,
+ swt1a int not null,
+ swt2a int not null,
+
+ st_b int not null,
+ swt1b int not null,
+ swt2b int not null,
+
+ /* fields/keys for row retrieval tests */
+ key1 int,
+ key2 int,
+ key3 int,
+ key4 int,
+
+ /* make rows much bigger then keys */
+ filler1 char (200),
+ filler2 char (200),
+ filler3 char (200),
+ filler4 char (200),
+ filler5 char (200),
+ filler6 char (200),
+
+ /* order of keys is important */
+ key sta_swt12a(st_a,swt1a,swt2a),
+ key sta_swt1a(st_a,swt1a),
+ key sta_swt2a(st_a,swt2a),
+ key sta_swt21a(st_a,swt2a,swt1a),
+
+ key st_a(st_a),
+ key stb_swt1a_2b(st_b,swt1b,swt2a),
+ key stb_swt1b(st_b,swt1b),
+ key st_b(st_b),
+
+ key(key1),
+ key(key2),
+ key(key3),
+ key(key4)
+) ;
+
+# Fill table
+create table t0 as select * from t1;
+let $cnt=1000;
+while ($cnt)
+{
+ eval insert into t0 values (1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 'data1', 'data2', 'data3', 'data4', 'data5', 'data6');
+ dec $cnt;
+}
+
+alter table t1 disable keys;
+let $1=4;
+while ($1)
+{
+ let $2=4;
+ while ($2)
+ {
+ let $3=4;
+ while ($3)
+ {
+ eval insert into t1 select $1, $2, $3, $1 ,$2, $3, key1, key2, key3, key4, filler1, filler2, filler3, filler4, filler5, filler6 from t0;
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+}
+
+# Row retrieval tests
+# -1 is used for values 'out of any range we are using'
+# insert enough rows for index intersection to be used for (key1,key2)
+insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 100, 100,'key1-key2-key3-key4');
+let $cnt=400;
+while ($cnt)
+{
+ eval insert into t1 (key1, key2, key3, key4, filler1) values (100, -1, 100, -1,'key1-key3');
+ dec $cnt;
+}
+let $cnt=400;
+while ($cnt)
+{
+ eval insert into t1 (key1, key2, key3, key4, filler1) values (-1, 100, -1, 100,'key2-key4');
+ dec $cnt;
+}
+alter table t1 enable keys;
+--enable_query_log
+select count(*) from t1;
+
+# One row results tests for cases where a single row matches all conditions
+explain select key1,key2 from t1 where key1=100 and key2=100;
+select key1,key2 from t1 where key1=100 and key2=100;
+
+explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+
+# Several-rows results
+insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, -1, -1, 'key1-key2');
+insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, 100, 100, 'key4-key3');
+
+# ROR-intersection, not covering
+explain select key1,key2,filler1 from t1 where key1=100 and key2=100;
+select key1,key2,filler1 from t1 where key1=100 and key2=100;
+
+# ROR-intersection, covering
+explain select key1,key2 from t1 where key1=100 and key2=100;
+select key1,key2 from t1 where key1=100 and key2=100;
+
+# ROR-union of ROR-intersections
+explain select key1,key2,key3,key4 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+select key1,key2,key3,key4 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+
+# 3-way ROR-intersection
+explain select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100;
+select key1,key2,key3 from t1 where key1=100 and key2=100 and key3=100;
+
+# ROR-union(ROR-intersection, ROR-range)
+insert into t1 (key1,key2,key3,key4,filler1) values (101,101,101,101, 'key1234-101');
+explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=101;
+select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=101;
+
+# Run some ROR updates/deletes
+select key1,key2, filler1 from t1 where key1=100 and key2=100;
+update t1 set filler1='to be deleted' where key1=100 and key2=100;
+update t1 set key1=200,key2=200 where key1=100 and key2=100;
+delete from t1 where key1=200 and key2=200;
+select key1,key2,filler1 from t1 where key2=100 and key2=200;
+
+# ROR-union(ROR-intersection) with one of ROR-intersection giving empty
+# results
+explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+
+delete from t1 where key3=100 and key4=100;
+
+# ROR-union with all ROR-intersections giving empty results
+explain select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+select key1,key2,key3,key4,filler1 from t1 where key1=100 and key2=100 or key3=100 and key4=100;
+
+# ROR-intersection with empty result
+explain select key1,key2 from t1 where key1=100 and key2=100;
+select key1,key2 from t1 where key1=100 and key2=100;
+
+# ROR-union tests with various cases.
+# All scans returning duplicate rows:
+insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key1-key2-key3-key4-1');
+insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key1-key2-key3-key4-2');
+insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 200, 200,'key1-key2-key3-key4-3');
+
+explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+
+insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, -1, 200,'key4');
+
+explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+
+insert into t1 (key1, key2, key3, key4, filler1) values (-1, -1, 200, -1,'key3');
+
+explain select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+select key1,key2,key3,key4,filler1 from t1 where key3=200 or (key1=100 and key2=100) or key4=200;
+
+##
+## Optimizer tests
+##
+
+# Check that the shortest key is used for ROR-intersection, covering and non-covering.
+explain select * from t1 where st_a=1 and st_b=1;
+explain select st_a,st_b from t1 where st_a=1 and st_b=1;
+
+# Check if "ingore index" syntax works
+explain select st_a from t1 ignore index (st_a) where st_a=1 and st_b=1;
+
+# Do many tests
+# Check that keys that don't improve selectivity are skipped.
+#
+
+explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1;
+
+explain select * from t1 where st_b=1 and swt1b=1 and swt2b=1;
+
+explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1;
+
+explain select * from t1 ignore index (sta_swt21a, stb_swt1a_2b)
+ where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1;
+
+explain select * from t1 ignore index (sta_swt21a, sta_swt12a, stb_swt1a_2b)
+ where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1;
+
+explain select * from t1 ignore index (sta_swt21a, sta_swt12a, stb_swt1a_2b, stb_swt1b)
+ where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1;
+
+explain select * from t1
+ where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1;
+
+explain select * from t1
+ where st_a=1 and swt1a=1 and st_b=1 and swt1b=1 and swt1b=1;
+
+explain select st_a from t1
+ where st_a=1 and swt1a=1 and st_b=1 and swt1b=1 and swt1b=1;
+
+explain select st_a from t1
+ where st_a=1 and swt1a=1 and st_b=1 and swt1b=1 and swt1b=1;
+
+drop table t0,t1;
+
+# 'Partially' covered fields test
+
+create table t2 (
+ a char(10),
+ b char(10),
+ filler1 char(255),
+ filler2 char(255),
+ key(a(5)),
+ key(b(5))
+);
+
+--disable_query_log
+let $1=8;
+while ($1)
+{
+ eval insert into t2 values (repeat(char($1+64), 8),repeat(char($1+64), 8),'filler1', 'filler2');
+ dec $1;
+}
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+--enable_query_log
+
+# The table row buffer is reused. Fill it with rows that don't match.
+select count(a) from t2 where a='BBBBBBBB';
+select count(a) from t2 where b='BBBBBBBB';
+
+# BUG#1:
+explain select count(a) from t2 where a='AAAAAAAA' and b='AAAAAAAA';
+select count(a) from t2 where a='AAAAAAAA' and b='AAAAAAAA';
+select count(a) from t2 ignore index(a,b) where a='AAAAAAAA' and b='AAAAAAAA';
+
+insert into t2 values ('ab', 'ab', 'uh', 'oh');
+explain select a from t2 where a='ab';
+drop table t2;
diff --git a/mysql-test/t/index_merge_ror_cpk.test b/mysql-test/t/index_merge_ror_cpk.test
new file mode 100644
index 00000000000..bf8eb5b77c7
--- /dev/null
+++ b/mysql-test/t/index_merge_ror_cpk.test
@@ -0,0 +1,108 @@
+#
+# Clustered PK ROR-index_merge tests
+#
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1
+(
+ pk1 int not null,
+ pk2 int not null,
+
+ key1 int not null,
+ key2 int not null,
+
+ pktail1ok int not null,
+ pktail2ok int not null,
+ pktail3bad int not null,
+ pktail4bad int not null,
+ pktail5bad int not null,
+
+ pk2copy int not null,
+ badkey int not null,
+
+ filler1 char (200),
+ filler2 char (200),
+ key (key1),
+ key (key2),
+
+ /* keys with tails from CPK members */
+ key (pktail1ok, pk1),
+ key (pktail2ok, pk1, pk2),
+ key (pktail3bad, pk2, pk1),
+ key (pktail4bad, pk1, pk2copy),
+ key (pktail5bad, pk1, pk2, pk2copy),
+
+ primary key (pk1, pk2)
+) engine=innodb;
+
+--disable_query_log
+set autocommit=0;
+let $1=10000;
+while ($1)
+{
+ eval insert into t1 values ($1 div 10,$1 mod 100, $1/100,$1/100, $1/100,$1/100,$1/100,$1/100,$1/100, $1 mod 100, $1/1000,'filler-data-$1','filler2');
+ dec $1;
+}
+set autocommit=1;
+--enable_query_log
+
+# Verify that range scan on CPK is ROR
+# (use index_intersection because it is impossible to check that for index union)
+explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+# CPK scan + 1 ROR range scan is a special case
+select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+
+# Verify that CPK fields are considered to be covered by index scans
+explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
+select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
+
+# Verify that CPK is always used for index intersection scans
+# (this is because it is used as a filter, not for retrieval)
+explain select * from t1 where badkey=1 and key1=10;
+explain select * from t1 where pk1 < 7500 and key1 = 10;
+
+# Verify that keys with 'tails' of PK members are ok.
+explain select * from t1 where pktail1ok=1 and key1=10;
+explain select * from t1 where pktail2ok=1 and key1=10;
+
+select ' The following is actually a deficiency, it uses sort_union currently:' as 'note:';
+explain select * from t1 where (pktail2ok=1 and pk1< 50000) or key1=10;
+
+explain select * from t1 where pktail3bad=1 and key1=10;
+explain select * from t1 where pktail4bad=1 and key1=10;
+explain select * from t1 where pktail5bad=1 and key1=10;
+
+# Test for problem with innodb key values prefetch buffer:
+explain select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
+select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
+
+drop table t1;
+# Testcase for BUG#4984
+create table t1
+(
+ RUNID varchar(22),
+ SUBMITNR varchar(5),
+ ORDERNR char(1) ,
+ PROGRAMM varchar(8),
+ TESTID varchar(4),
+ UCCHECK char(1),
+ ETEXT varchar(80),
+ ETEXT_TYPE char(1),
+ INFO char(1),
+ SEVERITY tinyint(3),
+ TADIRFLAG char(1),
+ PRIMARY KEY (RUNID,SUBMITNR,ORDERNR,PROGRAMM,TESTID,UCCHECK),
+ KEY `TVERM~KEY` (PROGRAMM,TESTID,UCCHECK)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+update t1 set `ETEXT` = '', `ETEXT_TYPE`='', `INFO`='', `SEVERITY`='', `TADIRFLAG`=''
+WHERE
+ `RUNID`= '' AND `SUBMITNR`= '' AND `ORDERNR`='' AND `PROGRAMM`='' AND
+ `TESTID`='' AND `UCCHECK`='';
+
+drop table t1;
+
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 50ab3bdb8bd..f9b1de44b81 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -998,7 +998,7 @@ CREATE TABLE t1 (
`id` int(10) unsigned NOT NULL auto_increment,
`id_object` int(10) unsigned default '0',
`id_version` int(10) unsigned NOT NULL default '1',
- label varchar(100) NOT NULL default '',
+ `label` varchar(100) NOT NULL default '',
`description` text,
PRIMARY KEY (`id`),
KEY `id_object` (`id_object`),
@@ -1016,8 +1016,8 @@ CREATE TABLE t2 (
INSERT INTO t2 VALUES("3524", "1"),("3525", "1"),("1794", "4"),("102", "5"),("1822", "6"),("3382", "9");
-SELECT t2.id, t1.label FROM t2 INNER JOIN
-(SELECT t1.id_object as id_object FROM t1 WHERE t1.label LIKE '%test%') AS lbl
+SELECT t2.id, t1.`label` FROM t2 INNER JOIN
+(SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl
ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object);
drop table t1,t2;
@@ -1155,5 +1155,27 @@ delete from t1;
commit;
show status like "binlog_cache_use";
show status like "binlog_cache_disk_use";
+drop table t1;
+
+#
+# range optimizer problem
+#
+
+create table t1 (x bigint unsigned not null primary key) engine=innodb;
+insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
+select * from t1;
+select count(*) from t1 where x>0;
+select count(*) from t1 where x=0;
+select count(*) from t1 where x<0;
+select count(*) from t1 where x < -16;
+select count(*) from t1 where x = -16;
+explain select count(*) from t1 where x > -16;
+
+# The following result should be (2). To be fixed when we add 'unsigned flag' to
+# Field::store(longlong)
+select count(*) from t1 where x > -16;
+select * from t1 where x > -16;
+select count(*) from t1 where x = 18446744073709551601;
drop table t1;
+
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index 54379685731..c56bc74877e 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
--enable_warnings
create table t1 (a int not null);
@@ -87,6 +87,7 @@ use mysqltest;
create table t1 (c int);
insert into mysqltest.t1 set mysqltest.t1.c = '1';
drop database mysqltest;
+use test;
#
# Test of wrong values for float data (bug #2082)
@@ -94,7 +95,6 @@ drop database mysqltest;
# PS gives sligthly different numbers for max-float/max-double
--disable_ps_protocol
-use test;
create table t1(number int auto_increment primary key, original_value varchar(50), f_double double, f_float float, f_double_7_2 double(7,2), f_float_4_3 float (4,3), f_double_u double unsigned, f_float_u float unsigned, f_double_15_1_u double(15,1) unsigned, f_float_3_1_u float (3,1) unsigned);
set @value= "aa";
@@ -117,13 +117,10 @@ set @value= "-1e+1111111111a";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--query_vertical select * from t1 where number =last_insert_id()
+--error 1367
set @value= 1e+1111111111;
-insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
---query_vertical select * from t1 where number =last_insert_id()
-
+--error 1367
set @value= -1e+1111111111;
-insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
---query_vertical select * from t1 where number =last_insert_id()
set @value= 1e+111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
@@ -143,3 +140,31 @@ insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@val
drop table t1;
--enable_ps_protocol
+
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+disable_query_log;
+let $1 = 100;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1(t) values ('$1');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'$2');
+ let $3 = 10;
+ while ($3)
+ {
+ eval insert into t3(id3,t) values ($1,'$2');
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+select count(*) from t2;
+insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
+select count(*) from t2;
+drop table t1,t2,t3;
diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test
new file mode 100644
index 00000000000..9591f1fa7ed
--- /dev/null
+++ b/mysql-test/t/join_nested.test
@@ -0,0 +1,754 @@
+
+--disable_warnings
+DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+--enable_warnings
+
+CREATE TABLE t0 (a int, b int, c int);
+CREATE TABLE t1 (a int, b int, c int);
+CREATE TABLE t2 (a int, b int, c int);
+CREATE TABLE t3 (a int, b int, c int);
+CREATE TABLE t4 (a int, b int, c int);
+CREATE TABLE t5 (a int, b int, c int);
+CREATE TABLE t6 (a int, b int, c int);
+CREATE TABLE t7 (a int, b int, c int);
+CREATE TABLE t8 (a int, b int, c int);
+CREATE TABLE t9 (a int, b int, c int);
+
+INSERT INTO t0 VALUES (1,1,0), (1,2,0), (2,2,0);
+INSERT INTO t1 VALUES (1,3,0), (2,2,0), (3,2,0);
+INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0);
+INSERT INTO t3 VALUES (1,2,0), (2,2,0);
+INSERT INTO t4 VALUES (3,2,0), (4,2,0);
+INSERT INTO t5 VALUES (3,1,0), (2,2,0), (3,3,0);
+INSERT INTO t6 VALUES (3,2,0), (6,2,0), (6,1,0);
+INSERT INTO t7 VALUES (1,1,0), (2,2,0);
+INSERT INTO t8 VALUES (0,2,0), (1,2,0);
+INSERT INTO t9 VALUES (1,1,0), (1,2,0), (3,3,0);
+
+
+SELECT t2.a,t2.b
+ FROM t2;
+
+SELECT t3.a,t3.b
+ FROM t3;
+
+SELECT t4.a,t4.b
+ FROM t4;
+
+SELECT t3.a,t3.b,t4.a,t4.b
+ FROM t3,t4;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t2.b=t4.b;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b;
+
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t2.b=t4.b
+ WHERE t3.a=1 OR t3.c IS NULL;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t2.b=t4.b
+ WHERE t3.a=1 OR t3.c IS NULL;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t2.b=t4.b
+ WHERE t3.a>1 OR t3.c IS NULL;
+
+SELECT t5.a,t5.b
+ FROM t5;
+
+SELECT t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t3,t4,t5;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4, t5)
+ ON t2.b=t4.b;
+
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4, t5)
+ ON t2.b=t4.b
+ WHERE t3.a>1 OR t3.c IS NULL;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4, t5)
+ ON t2.b=t4.b
+ WHERE t3.a>1 OR t3.c IS NULL;
+
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4, t5)
+ ON t2.b=t4.b
+ WHERE (t3.a>1 OR t3.c IS NULL) AND
+ (t5.a<3 OR t5.c IS NULL);
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4, t5)
+ ON t2.b=t4.b
+ WHERE (t3.a>1 OR t3.c IS NULL) AND
+ (t5.a<3 OR t5.c IS NULL);
+
+SELECT t6.a,t6.b
+ FROM t6;
+
+SELECT t7.a,t7.b
+ FROM t7;
+
+SELECT t6.a,t6.b,t7.a,t7.b
+ FROM t6,t7;
+
+SELECT t8.a,t8.b
+ FROM t8;
+
+EXPLAIN EXTENDED
+SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10;
+
+SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10;
+
+SELECT t5.a,t5.b
+ FROM t5;
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b;
+
+SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b AND
+ (t8.a < 1 OR t8.c IS NULL);
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ WHERE t2.a > 3 AND
+ (t6.a < 6 OR t6.c IS NULL);
+
+SELECT t1.a,t1.b
+ FROM t1;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2);
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2)
+ WHERE (t2.a >= 4 OR t2.c IS NULL);
+
+SELECT t0.a,t0.b
+ FROM t0;
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2)
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL);
+
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2)
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL);
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+SELECT t9.a,t9.b
+ FROM t9;
+
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+SELECT t1.a,t1.b
+ FROM t1;
+
+SELECT t2.a,t2.b
+ FROM t2;
+
+SELECT t3.a,t3.b
+ FROM t3;
+
+SELECT t2.a,t2.b,t3.a,t3.b
+ FROM t2
+ LEFT JOIN
+ t3
+ ON t2.b=t3.b;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b
+ FROM t1, t2
+ LEFT JOIN
+ t3
+ ON t2.b=t3.b
+ WHERE t1.a <= 2;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b
+ FROM t1, t3
+ RIGHT JOIN
+ t2
+ ON t2.b=t3.b
+ WHERE t1.a <= 2;
+
+SELECT t3.a,t3.b,t4.a,t4.b
+ FROM t3,t4;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t1, t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b
+ WHERE t1.a <= 2;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t1, (t3, t4)
+ RIGHT JOIN
+ t2
+ ON t3.a=1 AND t2.b=t4.b
+ WHERE t1.a <= 2;
+
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t1, t3, t4
+ RIGHT JOIN
+ t2
+ ON t3.a=1 AND t2.b=t4.b
+ WHERE t1.a <= 2;
+
+EXPLAIN EXTENDED
+SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t1, t3, t4
+ RIGHT JOIN
+ t2
+ ON t3.a=1 AND t2.b=t4.b
+ WHERE t1.a <= 2;
+
+CREATE INDEX idx_b ON t2(b);
+
+EXPLAIN EXTENDED
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t3,t4
+ LEFT JOIN
+ (t1,t2)
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+
+SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
+ FROM t3,t4
+ LEFT JOIN
+ (t1,t2)
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+CREATE INDEX idx_b ON t4(b);
+CREATE INDEX idx_b ON t5(b);
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+CREATE INDEX idx_b ON t8(b);
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+CREATE INDEX idx_b ON t1(b);
+CREATE INDEX idx_a ON t0(a);
+
+EXPLAIN EXTENDED
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
+ t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
+ FROM t0,t1
+ LEFT JOIN
+ (
+ t2
+ LEFT JOIN
+ (t3, t4)
+ ON t3.a=1 AND t2.b=t4.b,
+ t5
+ LEFT JOIN
+ (
+ t6,
+ t7
+ LEFT JOIN
+ t8
+ ON t7.b=t8.b AND t6.b < 10
+ )
+ ON t6.b >= 2 AND t5.b=t7.b
+ )
+ ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
+ (t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
+ (t1.a != 2),
+ t9
+ WHERE t0.a=1 AND
+ t0.b=t1.b AND
+ (t2.a >= 4 OR t2.c IS NULL) AND
+ (t3.a < 5 OR t3.c IS NULL) AND
+ (t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND
+ (t5.a >=2 OR t5.c IS NULL) AND
+ (t6.a >=4 OR t6.c IS NULL) AND
+ (t7.a <= 2 OR t7.c IS NULL) AND
+ (t8.a < 1 OR t8.c IS NULL) AND
+ (t8.b=t9.b OR t8.c IS NULL) AND
+ (t9.a=1);
+
+SELECT t2.a,t2.b
+ FROM t2;
+
+SELECT t3.a,t3.b
+ FROM t3;
+
+SELECT t2.a,t2.b,t3.a,t3.b
+ FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+ WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
+
+SELECT t2.a,t2.b,t3.a,t3.b
+ FROM t2 LEFT JOIN (t3) ON t2.b=t3.b
+ WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
+
+ALTER TABLE t3
+ CHANGE COLUMN a a1 int,
+ CHANGE COLUMN c c1 int;
+
+SELECT t2.a,t2.b,t3.a1,t3.b
+ FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+ WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL);
+
+SELECT t2.a,t2.b,t3.a1,t3.b
+ FROM t2 NATURAL LEFT JOIN t3
+ WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL);
+
+DROP TABLE t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+INSERT INTO t3 VALUES (2);
+INSERT INTO t1 VALUES (2);
+
+#check proper syntax for nested outer joins
+
+SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.a=t3.a;
+
+#must be equivalent to:
+
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+
+#check that everything is al right when all tables contain not more than 1 row
+#(bug #4922)
+
+DELETE FROM t1 WHERE a=2;
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+DELETE FROM t2;
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a;
+
+DROP TABLE t1,t2,t3;
+
+#on expression for a nested outer join does not depend on the outer table
+#bug #4976
+
+CREATE TABLE t1(a int, key (a));
+CREATE TABLE t2(b int, key (b));
+CREATE TABLE t3(c int, key (c));
+
+INSERT INTO t1 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
+(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
+
+INSERT INTO t2 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
+(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
+
+INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5);
+
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c;
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+
+DELETE FROM t3;
+EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
+
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index bc96318ae2e..fc06aa4f544 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1,t2,t3,t4,t5;
+drop table if exists t0,t1,t2,t3,t4,t5;
--enable_warnings
CREATE TABLE t1 (
@@ -506,3 +506,28 @@ select s.*, '*', m.*, (s.match_1_h - m.home) UUX from
order by UUX desc;
drop table t1, t2;
+
+# Test for bug #5896
+
+CREATE TABLE t0 (a0 int PRIMARY KEY);
+CREATE TABLE t1 (a1 int PRIMARY KEY);
+CREATE TABLE t2 (a2 int);
+CREATE TABLE t3 (a3 int);
+INSERT INTO t0 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+
+SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON a1=0;
+SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
+EXPLAIN SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0;
+SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
+EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1;
+
+INSERT INTO t0 VALUES (0);
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
+EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1;
+
+DROP TABLE t0,t1,t2,t3;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 5ee2f68ab83..8885f69e60c 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -129,7 +129,11 @@ create table t2
INSERT t2 select * from t1;
SELECT * FROM t2 WHERE name='[T,U]_axpy';
SELECT * FROM t2 WHERE name='[T,U]_axpby';
-drop table t1,t2;
+# Test possible problems with warnings in CREATE ... SELECT
+CREATE TABLE t3 SELECT * FROM t2 WHERE name='[T,U]_axpby';
+SELECT * FROM t2 WHERE name='[T,U]_axpby';
+
+drop table t1,t2,t3;
#
# Test bug with long primary key
diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test
index e7ec63afe54..3392bfa1b3b 100644
--- a/mysql-test/t/keywords.test
+++ b/mysql-test/t/keywords.test
@@ -6,10 +6,12 @@
drop table if exists t1;
--enable_warnings
-create table t1 (time time, date date, timestamp timestamp);
-insert into t1 values ("12:22:22","97:02:03","1997-01-02");
+create table t1 (time time, date date, timestamp timestamp,
+quarter int, week int, year int, timestampadd int, timestampdiff int);
+insert into t1 values ("12:22:22","97:02:03","1997-01-02",1,2,3,4,5);
select * from t1;
-select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
+select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time),
+ t1.quarter+t1.week, t1.year+timestampadd, timestampdiff from t1;
drop table t1;
create table events(binlog int);
insert into events values(1);
diff --git a/mysql-test/t/lowercase_view-master.opt b/mysql-test/t/lowercase_view-master.opt
new file mode 100644
index 00000000000..62ab6dad1e0
--- /dev/null
+++ b/mysql-test/t/lowercase_view-master.opt
@@ -0,0 +1 @@
+--lower_case_table_names=1
diff --git a/mysql-test/t/lowercase_view.test b/mysql-test/t/lowercase_view.test
new file mode 100644
index 00000000000..2a2757650ae
--- /dev/null
+++ b/mysql-test/t/lowercase_view.test
@@ -0,0 +1,34 @@
+--disable_warnings
+drop table if exists t1Aa,t2Aa,v1Aa,v2Aa;
+drop view if exists t1Aa,t2Aa,v1Aa,v2Aa;
+drop database if exists MySQLTest;
+--enable_warnings
+
+#
+# different cases in VIEW
+#
+create database MySQLTest;
+use MySQLTest;
+create table TaB (Field int);
+create view ViE as select * from TAb;
+show create table VIe;
+drop database MySQLTest;
+use test;
+
+#
+# test of updating and fetching from the same table check
+#
+create table t1Aa (col1 int);
+create table t2Aa (col1 int);
+create view v1Aa as select * from t1Aa;
+create view v2Aa as select * from v1Aa;
+-- error 1093
+update v2aA set col1 = (select max(col1) from v1aA);
+#update v2aA,t2aA set v2aA.col1 = (select max(col1) from v1aA) where v2aA.col1 = t2aA.col1;
+-- error 1093
+delete from v2aA where col1 = (select max(col1) from v1aA);
+#delete v2aA from v2aA,t2aA where (select max(col1) from v1aA) > 0 and v2aA.col1 = t2aA.col1;
+-- error 1093
+insert into v2aA values ((select max(col1) from v1aA));
+drop view v2Aa,v1Aa;
+drop table t1Aa,t2Aa;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 9580c1ab44c..9d367260049 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -284,4 +284,6 @@ insert into t2 values (1);
create table t3 engine=merge union=(t1, t2) select * from t1;
--error 1093
create table t3 engine=merge union=(t1, t2) select * from t2;
+--error 1093
+create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
drop table t1, t2;
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index 9c576b080ca..00be4c83efc 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -25,7 +25,8 @@ insert into t1 values(1);
insert into t2 select * from t1;
commit;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -37,7 +38,8 @@ insert into t2 select * from t1;
# should say some changes to non-transact1onal tables couldn't be rolled back
rollback;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -51,7 +53,8 @@ insert into t2 select * from t1;
rollback to savepoint my_savepoint;
commit;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -67,7 +70,8 @@ insert into t1 values(7);
commit;
select a from t1 order by a; # check that savepoints work :)
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
# and when ROLLBACK is not explicit?
delete from t1;
@@ -87,7 +91,8 @@ connection con2;
# so SHOW BINLOG EVENTS may come before con1 does the loggin. To be sure that
# logging has been done, we use a user lock.
select get_lock("a",10);
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
# and when not in a transact1on?
delete from t1;
@@ -97,10 +102,11 @@ reset master;
insert into t1 values(9);
insert into t2 select * from t1;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
# Check that when the query updat1ng the MyISAM table is the first in the
-# transact1on, we log it immediately.
+# transaction, we log it immediately.
delete from t1;
delete from t2;
reset master;
@@ -108,11 +114,13 @@ reset master;
insert into t1 values(10); # first make t1 non-empty
begin;
insert into t2 select * from t1;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
insert into t1 values(11);
commit;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
# Check that things work like before this BEGIN/ROLLBACK code was added,
@@ -129,7 +137,8 @@ insert into t1 values(12);
insert into t2 select * from t1;
commit;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -140,7 +149,8 @@ insert into t1 values(13);
insert into t2 select * from t1;
rollback;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -154,7 +164,8 @@ insert into t2 select * from t1;
rollback to savepoint my_savepoint;
commit;
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
delete from t1;
delete from t2;
@@ -170,6 +181,7 @@ insert into t1 values(18);
commit;
select a from t1 order by a; # check that savepoints work :)
-show binlog events from 79;
+--replace_column 5 #
+show binlog events from 95;
drop table t1,t2;
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index e2aebd014f8..8a213ab791c 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -159,6 +159,8 @@ LOCK TABLES t1 write, t2 read;
DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n;
--error 1099
UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+--QQ This should not generate an error
+--error 1099
UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
unlock tables;
LOCK TABLES t1 write, t2 write;
@@ -426,8 +428,54 @@ drop table t1, t2, t3;
#
create table t1 (col1 int);
create table t2 (col1 int);
--- error 1093
+-- QQ The following should give error 1093
update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1;
-- error 1093
delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1;
drop table t1,t2;
+
+#
+# Test for bug #1980.
+#
+set @ttype_save=@@storage_engine;
+
+--disable_warnings
+set @@storage_engine=innodb;
+create table t1 ( c char(8) not null );
+--enable_warnings
+
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+
+create table t2 like t1;
+insert into t2 select * from t1;
+
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+
+drop table t1,t2;
+
+--disable_warnings
+set @@storage_engine=bdb;
+create table t1 ( c char(8) not null );
+--enable_warnings
+
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+
+create table t2 like t1;
+insert into t2 select * from t1;
+
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+
+set @@storage_engine=@ttype_save;
+drop table t1,t2;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index ea66a44d44e..a8bbe60d58e 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -61,7 +61,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=27 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=118 $MYSQL_TEST_DIR/var/log/master-bin.000002
# These are tests for remote binlog.
# They should return the same as previous test.
@@ -93,7 +93,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=118 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# clean up
drop table t1, t2;
diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test
index c6cff7558d4..6a4c99c746d 100644
--- a/mysql-test/t/mysqlbinlog2.test
+++ b/mysql-test/t/mysqlbinlog2.test
@@ -46,11 +46,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=497 $MYSQL_TEST_DIR/var/log/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --start-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=497 $MYSQL_TEST_DIR/var/log/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --stop-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -75,11 +75,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=497 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --start-position=601 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=32 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --stop-position=123 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -102,11 +102,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=497 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --short-form --start-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=497 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --short-form --stop-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -129,11 +129,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=497 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+--exec $MYSQL_BINLOG --short-form --start-position=601 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=32 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+--exec $MYSQL_BINLOG --short-form --stop-position=123 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 89b3739f955..e8bb98d5ae0 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -24,7 +24,7 @@ DROP TABLE t1;
#
CREATE TABLE t1 (a double);
-INSERT INTO t1 VALUES (-9e999999);
+INSERT INTO t1 VALUES ('-9e999999');
# The following replaces is here because some systems replaces the above
# double with '-inf' and others with MAX_DOUBLE
--replace_result (-1.79769313486232e+308) (RES) (NULL) (RES)
@@ -127,3 +127,12 @@ insert into t1 values (1),(2),(3);
--exec rm $MYSQL_TEST_DIR/var/tmp/t1.sql
--exec rm $MYSQL_TEST_DIR/var/tmp/t1.txt
drop table t1;
+
+#
+# dump of view
+#
+create table t1(a int);
+create view v1 as select * from t1;
+--exec $MYSQL_DUMP --skip-comments test
+drop view v1;
+drop table t1;
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index 7d30fd06ba7..027443c485a 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -100,9 +100,9 @@ drop table t1;
select cast(NULL as signed);
#
-# Test case for bug #4256
+# IS NULL is unable to use index in range if column is declared not null
+# (Bug #4256)
#
-
create table t1(i int, key(i));
insert into t1 values(1);
insert into t1 select i*2 from t1;
@@ -114,8 +114,11 @@ insert into t1 select i*2 from t1;
insert into t1 select i*2 from t1;
insert into t1 select i*2 from t1;
insert into t1 select i*2 from t1;
+insert into t1 values(null);
explain select * from t1 where i=2 or i is null;
+select count(*) from t1 where i=2 or i is null;
alter table t1 change i i int not null;
explain select * from t1 where i=2 or i is null;
+select count(*) from t1 where i=2 or i is null;
drop table t1;
diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test
index 9b346a181bf..d7f6a634d1e 100644
--- a/mysql-test/t/null_key.test
+++ b/mysql-test/t/null_key.test
@@ -26,6 +26,8 @@ select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
select * from t1 where (a is null or a = 7) and b=7;
select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
+select * from t1 where a > 1 and a < 3 limit 1;
+select * from t1 where a > 8 and a < 9;
create table t2 like t1;
insert into t2 select * from t1;
alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test
index 9e4acc2bf24..89c49d087b7 100644
--- a/mysql-test/t/ps_1general.test
+++ b/mysql-test/t/ps_1general.test
@@ -468,9 +468,7 @@ prepare stmt1 from ' handler t1 open ';
## commit/rollback
---error 1295
prepare stmt3 from ' commit ' ;
---error 1295
prepare stmt3 from ' rollback ' ;
@@ -571,11 +569,8 @@ execute stmt3 using @arg00;
select m from t3;
drop table t3;
---error 1295
prepare stmt3 from ' create index t2_idx on t2(b) ';
---error 1295
prepare stmt3 from ' drop index t2_idx on t2 ' ;
---error 1295
prepare stmt3 from ' alter table t2 drop primary key ';
## RENAME TABLE
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index d570073b1d2..ed89184a0bc 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -615,9 +615,7 @@ set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1;
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
-#
-# Keep things tidy
-#
+
DROP TABLE t1;
#
@@ -637,7 +635,6 @@ DROP TABLE t1;
set character_set_results=null;
select @@character_set_results;
set character_set_results=default;
-
#
# query cache and environment variables
#
@@ -672,4 +669,20 @@ select group_concat(a) FROM t1 group by b;
set group_concat_max_len=default;
drop table t1;
+# comments before command
+#
+create table t1 (a int);
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+/**/ select * from t1;
+/**/ select * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+
+#
+# Keep things tidy
+#
+DROP TABLE t1;
SET GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 44f55da5722..e0d2e07bef2 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -195,13 +195,15 @@ explain select count(*) from t1 where x in (1,2);
drop table t1;
#
-# bug #1172
+# bug #1172: "Force index" option caused server crash
#
CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1));
INSERT INTO t1 VALUES (0),(0),(1),(1);
CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+explain select * from t1 force index(i1), t2 force index(j1) where
+ (t1.key1 <t2.keya + 1) and t2.keya=3;
DROP TABLE t1,t2;
#
@@ -376,8 +378,12 @@ insert into t2(id, uid, name) select id, uid, name from t1;
select count(*) from t1;
select count(*) from t2;
+analyze table t1,t2;
+
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
@@ -410,26 +416,7 @@ select count(*) from t2 where x < -16;
select count(*) from t2 where x = -16;
select count(*) from t2 where x > -16;
select count(*) from t2 where x = 18446744073709551601;
-
-drop table t1;
---disable_warnings
-create table t1 (x bigint unsigned not null primary key) engine=innodb;
---enable_warnings
-insert into t1(x) values (0xfffffffffffffff0);
-insert into t1(x) values (0xfffffffffffffff1);
-select * from t1;
-select count(*) from t1 where x>0;
-select count(*) from t1 where x=0;
-select count(*) from t1 where x<0;
-select count(*) from t1 where x < -16;
-select count(*) from t1 where x = -16;
-# The following query returns wrong value because the range optimizer can't
-# handle search on a signed value for an unsigned parameter. This will be fixed in
-# 5.0
-select count(*) from t1 where x > -16;
-select count(*) from t1 where x = 18446744073709551601;
-
-drop table t1;
+drop table t1,t2;
#
# Bug #6045: Binary Comparison regression in MySQL 4.1
diff --git a/mysql-test/t/rowid_order_bdb.test b/mysql-test/t/rowid_order_bdb.test
new file mode 100644
index 00000000000..ef133054c35
--- /dev/null
+++ b/mysql-test/t/rowid_order_bdb.test
@@ -0,0 +1,108 @@
+#
+# Test for rowid ordering (and comparison) functions.
+# do index_merge select for tables with PK of various types.
+#
+--disable_warnings
+drop table if exists t1, t2, t3,t4;
+--enable_warnings
+
+-- source include/have_bdb.inc
+
+# Signed number as rowid
+create table t1 (
+ pk1 int not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=bdb;
+insert into t1 values (-5, 1, 1),
+ (-100, 1, 1),
+ (3, 1, 1),
+ (0, 1, 1),
+ (10, 1, 1);
+explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Unsigned numbers as rowids
+create table t1 (
+ pk1 int unsigned not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=bdb;
+insert into t1 values (0, 1, 1),
+ (0xFFFFFFFF, 1, 1),
+ (0xFFFFFFFE, 1, 1),
+ (1, 1, 1),
+ (2, 1, 1);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Case-insensitive char(N)
+create table t1 (
+ pk1 char(4) not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=bdb collate latin2_general_ci;
+insert into t1 values ('a1', 1, 1),
+ ('b2', 1, 1),
+ ('A3', 1, 1),
+ ('B4', 1, 1);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Multi-part PK
+create table t1 (
+ pk1 int not NULL,
+ pk2 char(4) not NULL collate latin1_german1_ci,
+ pk3 char(4) not NULL collate latin1_bin,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1,pk2,pk3),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=bdb;
+insert into t1 values
+ (1, 'u', 'u', 1, 1),
+ (1, 'u', char(0xEC), 1, 1),
+ (1, 'u', 'x', 1, 1);
+insert ignore into t1 select pk1, char(0xEC), pk3, key1, key2 from t1;
+insert ignore into t1 select pk1, 'x', pk3, key1, key2 from t1 where pk2='u';
+insert ignore into t1 select 2, pk2, pk3, key1, key2 from t1;
+select * from t1;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+
+# Hidden PK
+alter table t1 drop primary key;
+select * from t1;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Variable-length PK
+# this is also test for Bug#2688
+create table t1 (
+ pk1 varchar(8) NOT NULL default '',
+ pk2 varchar(4) NOT NULL default '',
+ key1 int(11),
+ key2 int(11),
+ primary key(pk1, pk2),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=bdb;
+insert into t1 values ('','empt',2,2),
+ ('a','a--a',2,2),
+ ('bb','b--b',2,2),
+ ('ccc','c--c',2,2),
+ ('dddd','d--d',2,2);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+
+drop table t1;
+
diff --git a/mysql-test/t/rowid_order_innodb.test b/mysql-test/t/rowid_order_innodb.test
new file mode 100644
index 00000000000..fb4959d78e6
--- /dev/null
+++ b/mysql-test/t/rowid_order_innodb.test
@@ -0,0 +1,108 @@
+#
+# Test for rowid ordering (and comparison) functions.
+# do index_merge select for tables with PK of various types.
+#
+--disable_warnings
+drop table if exists t1, t2, t3,t4;
+--enable_warnings
+
+-- source include/have_innodb.inc
+
+# Signed number as rowid
+create table t1 (
+ pk1 int not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=innodb;
+insert into t1 values (-5, 1, 1),
+ (-100, 1, 1),
+ (3, 1, 1),
+ (0, 1, 1),
+ (10, 1, 1);
+explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Unsigned numbers as rowids
+create table t1 (
+ pk1 int unsigned not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=innodb;
+insert into t1 values (0, 1, 1),
+ (0xFFFFFFFF, 1, 1),
+ (0xFFFFFFFE, 1, 1),
+ (1, 1, 1),
+ (2, 1, 1);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Case-insensitive char(N)
+create table t1 (
+ pk1 char(4) not NULL,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=innodb collate latin2_general_ci;
+insert into t1 values ('a1', 1, 1),
+ ('b2', 1, 1),
+ ('A3', 1, 1),
+ ('B4', 1, 1);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Multi-part PK
+create table t1 (
+ pk1 int not NULL,
+ pk2 char(4) not NULL collate latin1_german1_ci,
+ pk3 char(4) not NULL collate latin1_bin,
+ key1 int(11),
+ key2 int(11),
+ PRIMARY KEY (pk1,pk2,pk3),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=innodb;
+insert into t1 values
+ (1, 'u', 'u', 1, 1),
+ (1, 'u', char(0xEC), 1, 1),
+ (1, 'u', 'x', 1, 1);
+insert ignore into t1 select pk1, char(0xEC), pk3, key1, key2 from t1;
+insert ignore into t1 select pk1, 'x', pk3, key1, key2 from t1 where pk2='u';
+insert ignore into t1 select 2, pk2, pk3, key1, key2 from t1;
+select * from t1;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+
+# Hidden PK
+alter table t1 drop primary key;
+select * from t1;
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
+# Variable-length PK
+# this is also test for Bug#2688
+create table t1 (
+ pk1 varchar(8) NOT NULL default '',
+ pk2 varchar(4) NOT NULL default '',
+ key1 int(11),
+ key2 int(11),
+ primary key(pk1, pk2),
+ KEY key1 (key1),
+ KEY key2 (key2)
+) engine=innodb;
+insert into t1 values ('','empt',2,2),
+ ('a','a--a',2,2),
+ ('bb','b--b',2,2),
+ ('ccc','c--c',2,2),
+ ('dddd','d--d',2,2);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+
+drop table t1;
+
diff --git a/mysql-test/t/rpl000010-slave.opt b/mysql-test/t/rpl000010-slave.opt
index 429a7f63f7b..0dbfb311e33 100644
--- a/mysql-test/t/rpl000010-slave.opt
+++ b/mysql-test/t/rpl000010-slave.opt
@@ -1 +1 @@
---disconnect-slave-event-count=1
+--disconnect-slave-event-count=2
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index b7fff94f7f3..da73c5f4db2 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -1,4 +1,4 @@
-connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
connection master;
reset master;
@@ -7,24 +7,24 @@ save_master_pos;
connection slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
change master to master_host='127.0.0.1';
# The following needs to be cleaned up when change master is fixed
--replace_result $MASTER_MYPORT MASTER_PORT $MYSQL_TCP_PORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
--replace_result $MASTER_MYPORT MASTER_PORT
eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$MASTER_MYPORT;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
connection master;
--disable_warnings
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index cf808a2cbc0..3b39a6b49a6 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -1,4 +1,4 @@
-connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
connection master;
reset master;
diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test
index 884ec9727d2..fd2be2399a5 100644
--- a/mysql-test/t/rpl000018.test
+++ b/mysql-test/t/rpl000018.test
@@ -4,7 +4,7 @@
#
require_manager;
-connect (master,localhost,root,,test,0,master.sock);
+connect (master,localhost,root,,test,0,$MASTER_MYPORT);
connect (slave,localhost,root,,test,0,slave.sock);
connection master;
reset master;
diff --git a/mysql-test/t/rpl_auto_increment-master.opt b/mysql-test/t/rpl_auto_increment-master.opt
new file mode 100644
index 00000000000..a8a6af19da9
--- /dev/null
+++ b/mysql-test/t/rpl_auto_increment-master.opt
@@ -0,0 +1 @@
+--auto-increment-increment=10 --auto-increment-offset=2
diff --git a/mysql-test/t/rpl_auto_increment.test b/mysql-test/t/rpl_auto_increment.test
new file mode 100644
index 00000000000..cfe1d44b11a
--- /dev/null
+++ b/mysql-test/t/rpl_auto_increment.test
@@ -0,0 +1,104 @@
+#
+# Test of auto_increment with offset
+#
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+create table t1 (a int not null auto_increment,b int, primary key (a)) engine=myisam auto_increment=3;
+insert into t1 values (NULL,1),(NULL,2),(NULL,3);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+create table t1 (a int not null auto_increment,b int, primary key (a)) engine=myisam;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where b=4;
+insert into t1 values (NULL,5),(NULL,6);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+
+drop table t1;
+
+set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10;
+show variables like "%auto%";
+
+create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL);
+insert into t1 values (250),(NULL);
+select * from t1;
+insert into t1 values (1000);
+set @@insert_id=400;
+insert into t1 values(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+#
+# Same test with innodb (as the innodb code is a bit different)
+#
+create table t1 (a int not null auto_increment, primary key (a)) engine=innodb;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL);
+insert into t1 values (250),(NULL);
+select * from t1;
+insert into t1 values (1000);
+set @@insert_id=400;
+insert into t1 values(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
+create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL),(NULL);
+insert into t1 values (500),(NULL),(502),(NULL),(NULL);
+select * from t1;
+set @@insert_id=600;
+--error 1062
+insert into t1 values(600),(NULL),(NULL);
+set @@insert_id=600;
+insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+#
+# Test that auto-increment works when slave has rows in the table
+#
+set @@session.auto_increment_increment=10, @@session.auto_increment_offset=1;
+
+create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
+
+sync_slave_with_master;
+insert into t1 values(2),(12),(22),(32),(42);
+connection master;
+
+insert into t1 values (NULL),(NULL);
+insert into t1 values (3),(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+
+drop table t1;
+
+# End cleanup
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test
index e6452b5b619..ddac966b073 100644
--- a/mysql-test/t/rpl_change_master.test
+++ b/mysql-test/t/rpl_change_master.test
@@ -12,11 +12,11 @@ connection slave;
stop slave;
select * from t1;
--replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Will restart from after the values(2), which is bug
select release_lock("a");
diff --git a/mysql-test/t/rpl_charset.test b/mysql-test/t/rpl_charset.test
index 9b9f53a94de..839fe5d377b 100644
--- a/mysql-test/t/rpl_charset.test
+++ b/mysql-test/t/rpl_charset.test
@@ -106,7 +106,8 @@ select * from mysqltest2.t1 order by a;
connection master;
drop database mysqltest2;
drop database mysqltest3;
-show binlog events from 79;
+--replace_column 2 # 5 #
+show binlog events from 95;
sync_slave_with_master;
# Check that we can't change global.collation_server
@@ -149,20 +150,24 @@ select hex(c1), hex(c2) from t1;
sync_slave_with_master;
select hex(c1), hex(c2) from t1;
-# Now test for BUG##5705: SET CHARATER_SET_SERVERetc will be lost if
+# Now test for BUG##5705: SET CHARACTER_SET_SERVER etc will be lost if
# STOP SLAVE before following query
stop slave;
delete from t1;
-change master to master_log_pos=5801;
-start slave until master_log_file='master-bin.000001', master_log_pos=5937;
-# Slave is supposed to stop _after_ the INSERT, even though 5937 is
+
+# Note that the following positions may change between MySQL versions!
+
+# This position should be position for the SET
+change master to master_log_pos=6763;
+
+# This position should be position of the INSERT command
+start slave until master_log_file='master-bin.000001', master_log_pos=6921;
+
+# Slave is supposed to stop _after_ the INSERT, even though 'master_log_pos' is
# the position of the beginning of the INSERT; after SET slave is not
# supposed to increment position.
wait_for_slave_to_stop;
-# When you merge this into 5.0 you will have to adjust positions
-# above; the first master_log_pos above should be the one of the SET,
-# the second should be the one of the INSERT.
start slave;
sync_with_master;
select hex(c1), hex(c2) from t1;
diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test
index bee9ef72dc4..98a630c69ca 100644
--- a/mysql-test/t/rpl_empty_master_crash.test
+++ b/mysql-test/t/rpl_empty_master_crash.test
@@ -1,6 +1,6 @@
source include/master-slave.inc;
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
#
diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test
index 0062a67ff1a..487869e5fef 100644
--- a/mysql-test/t/rpl_error_ignored_table.test
+++ b/mysql-test/t/rpl_error_ignored_table.test
@@ -15,7 +15,7 @@ sync_with_master;
# The port number is different when doing the release build with
# Do-compile, hence we have to replace the port number here accordingly
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# check that the table has been ignored, because otherwise the test is nonsense
show tables like 't1';
@@ -48,7 +48,7 @@ connection master;
--error 0,1053;
reap;
connection master1;
-show binlog events from 79;
+show binlog events from 95;
save_master_pos;
connection slave;
# SQL slave thread should not have stopped (because table of the killed
diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test
index 74920722868..ccaae8ad765 100644
--- a/mysql-test/t/rpl_flush_log_loop.test
+++ b/mysql-test/t/rpl_flush_log_loop.test
@@ -18,5 +18,5 @@ sleep 5;
flush logs;
sleep 5;
--replace_result $SLAVE_MYPORT SLAVE_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
diff --git a/mysql-test/t/rpl_heap.test b/mysql-test/t/rpl_heap.test
index 0bc71eaf30c..3452f3990bf 100644
--- a/mysql-test/t/rpl_heap.test
+++ b/mysql-test/t/rpl_heap.test
@@ -7,7 +7,7 @@ require_manager;
# issue a query after the server restart.
# Maybe this is something awkward in mysqltest or in the manager?
# So we use sockets.
-connect (master,localhost,root,,test,0,master.sock);
+connect (master,localhost,root,,test,0,$MASTER_MYPORT);
connect (slave,localhost,root,,test,0,slave.sock);
connection master;
diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test
index 10213644836..487ad4a7aa6 100644
--- a/mysql-test/t/rpl_loaddata.test
+++ b/mysql-test/t/rpl_loaddata.test
@@ -37,7 +37,7 @@ select * from t3;
# restarted for this test, the file_id is uncertain (would cause test
# failures). So instead, we test if the binlog looks long enough to
# contain LOAD DATA. That is, I (Guilhem) have done SHOW BINLOG EVENTS on my
-# machine, saw that the binlog is of size 964 when things go fine.
+# machine, saw that the binlog is of size 1068 (in 5.0.0) when things go fine.
# If LOAD DATA was not logged, the binlog would be shorter.
show master status;
@@ -72,7 +72,7 @@ set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Trigger error again to test CHANGE MASTER
@@ -92,7 +92,7 @@ stop slave;
change master to master_user='test';
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Trigger error again to test RESET SLAVE
@@ -114,7 +114,7 @@ wait_for_slave_to_stop;
stop slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
diff --git a/mysql-test/t/rpl_loaddata_rule_m.test b/mysql-test/t/rpl_loaddata_rule_m.test
index 678dae13889..3f19a09c6f7 100644
--- a/mysql-test/t/rpl_loaddata_rule_m.test
+++ b/mysql-test/t/rpl_loaddata_rule_m.test
@@ -19,5 +19,5 @@ create database mysqltest;
create table t1(a int, b int, unique(b));
use mysqltest;
load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
-show binlog events from 79; # should be nothing
+show binlog events from 95; # should be nothing
drop database mysqltest;
diff --git a/mysql-test/t/rpl_loaddata_rule_s.test b/mysql-test/t/rpl_loaddata_rule_s.test
index 1ea4f6825f5..8163cd20f00 100644
--- a/mysql-test/t/rpl_loaddata_rule_s.test
+++ b/mysql-test/t/rpl_loaddata_rule_s.test
@@ -17,4 +17,4 @@ save_master_pos;
connection slave;
sync_with_master;
select count(*) from t1; # check that LOAD was replicated
-show binlog events from 79; # should be nothing
+show binlog events from 95; # should be nothing
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test
index 8fdccdd068d..178199d6160 100644
--- a/mysql-test/t/rpl_log.test
+++ b/mysql-test/t/rpl_log.test
@@ -38,9 +38,9 @@ select count(*) from t1;
drop table t1;
--replace_result $VERSION VERSION
show binlog events;
-show binlog events from 79 limit 1;
-show binlog events from 79 limit 2;
-show binlog events from 79 limit 2,1;
+show binlog events from 95 limit 1;
+show binlog events from 95 limit 2;
+show binlog events from 95 limit 2,1;
flush logs;
# We need an extra update before doing save_master_pos.
@@ -82,6 +82,7 @@ insert into t1 values (1);
drop table t1;
--replace_result $VERSION VERSION
show binlog events;
+--replace_result $VERSION VERSION
show binlog events in 'master-bin.000002';
show binary logs;
save_master_pos;
@@ -94,7 +95,7 @@ show binlog events in 'slave-bin.000001' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
show binlog events in 'slave-bin.000002' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Need to recode the following
diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test
index a40736577c8..634bf9449fd 100644
--- a/mysql-test/t/rpl_log_pos.test
+++ b/mysql-test/t/rpl_log_pos.test
@@ -5,7 +5,7 @@ source include/master-slave.inc;
show master status;
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
change master to master_log_pos=73;
@@ -15,19 +15,19 @@ stop slave;
change master to master_log_pos=73;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
start slave;
sleep 5;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
change master to master_log_pos=173;
start slave;
sleep 2;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
connection master;
show master status;
@@ -38,7 +38,7 @@ insert into t1 values (1),(2),(3);
save_master_pos;
connection slave;
stop slave;
-change master to master_log_pos=79;
+change master to master_log_pos=95;
start slave;
sync_with_master;
select * from t1;
diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test
index cbcc115a942..963a76fb959 100644
--- a/mysql-test/t/rpl_max_relay_size.test
+++ b/mysql-test/t/rpl_max_relay_size.test
@@ -29,7 +29,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
reset slave;
@@ -38,7 +38,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
reset slave;
@@ -47,7 +47,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# Tests below are mainly to ensure that we have not coded with wrong assumptions
@@ -58,7 +58,7 @@ reset slave;
# (to make sure it does not crash).
flush logs;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
reset slave;
@@ -74,7 +74,7 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# one more rotation, to be sure Relay_Log_Space is correctly updated
flush logs;
@@ -84,7 +84,7 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
connection master;
diff --git a/mysql-test/t/rpl_openssl.test b/mysql-test/t/rpl_openssl.test
index 8a36904f4d4..779ec4e84bf 100644
--- a/mysql-test/t/rpl_openssl.test
+++ b/mysql-test/t/rpl_openssl.test
@@ -45,7 +45,7 @@ select * from t1;
#checking show slave status
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
#checking if replication works without ssl also performing clean up
@@ -58,5 +58,5 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
diff --git a/mysql-test/t/rpl_redirect.test b/mysql-test/t/rpl_redirect.test
index c533c0052f0..d505351cc69 100644
--- a/mysql-test/t/rpl_redirect.test
+++ b/mysql-test/t/rpl_redirect.test
@@ -14,7 +14,7 @@ sync_with_master;
#discover slaves
connection master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
SHOW SLAVE STATUS;
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW SLAVE HOSTS;
diff --git a/mysql-test/t/rpl_relayrotate-slave.opt b/mysql-test/t/rpl_relayrotate-slave.opt
index 8b671423363..3a4abbf091e 100644
--- a/mysql-test/t/rpl_relayrotate-slave.opt
+++ b/mysql-test/t/rpl_relayrotate-slave.opt
@@ -1,4 +1,3 @@
--O max_binlog_size=16384
+-O max_relay_log_size=16384
--innodb
--log-warnings
-
diff --git a/mysql-test/t/rpl_relayrotate.test b/mysql-test/t/rpl_relayrotate.test
index 1bc6b574663..2fde590356a 100644
--- a/mysql-test/t/rpl_relayrotate.test
+++ b/mysql-test/t/rpl_relayrotate.test
@@ -55,8 +55,10 @@ start slave;
# reading, MASTER_POS_WAIT() will do it for sure
# (the only statement with position>=3000 is COMMIT).
select master_pos_wait('master-bin.001',3000)>=0;
-select * from t1 where a=8000;
-
+select max(a) from t1;
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+show slave status;
connection master;
# The following DROP is a very important cleaning task:
diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test
index 7066f6e53d8..108dd54ce0a 100644
--- a/mysql-test/t/rpl_replicate_do.test
+++ b/mysql-test/t/rpl_replicate_do.test
@@ -33,6 +33,6 @@ connection slave;
sync_with_master;
# show slave status, just to see of it prints replicate-do-table
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
diff --git a/mysql-test/t/rpl_reset_slave.test b/mysql-test/t/rpl_reset_slave.test
index d58e9c711d1..1b27e059f92 100644
--- a/mysql-test/t/rpl_reset_slave.test
+++ b/mysql-test/t/rpl_reset_slave.test
@@ -11,24 +11,24 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
change master to master_user='test';
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# test of crash with temp tables & RESET SLAVE
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index da4d5f0bce1..c3c0ff5be10 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -9,7 +9,7 @@
# changes
# - Test creating a duplicate key error and recover from it
-connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
--disable_warnings
drop table if exists t1, t2, t3, t4;
--enable_warnings
@@ -55,7 +55,7 @@ create table t1 (s text);
insert into t1 values('Could not break slave'),('Tried hard');
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
select * from t1;
connection master;
@@ -108,7 +108,7 @@ show binary logs;
insert into t2 values (65);
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
select * from t2;
@@ -140,7 +140,7 @@ sync_with_master;
select * from t4;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
# because of concurrent insert, the table may not be up to date
# if we do not lock
diff --git a/mysql-test/t/rpl_session_var.test b/mysql-test/t/rpl_session_var.test
new file mode 100644
index 00000000000..2379df721b7
--- /dev/null
+++ b/mysql-test/t/rpl_session_var.test
@@ -0,0 +1,42 @@
+# Replication of session variables.
+# FOREIGN_KEY_CHECKS is tested in rpl_insert_id.test
+
+source include/master-slave.inc;
+drop table if exists t1;
+create table t1(a varchar(100),b int);
+set @@session.sql_mode=pipes_as_concat;
+insert into t1 values('My'||'SQL', 1);
+set @@session.sql_mode=default;
+insert into t1 values('My'||'SQL', 2);
+select * from t1 where b<3 order by a;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1 where b<3 order by a;
+connection master;
+# if the slave does the next sync_with_master fine, then it means it accepts the
+# two lines of ANSI syntax below, which is what we want to check.
+set @@session.sql_mode=ignore_space;
+insert into t1 values(password ('MySQL'), 3);
+set @@session.sql_mode=ansi_quotes;
+create table "t2" ("a" int);
+drop table t1, t2;
+set @@session.sql_mode=default;
+create table t1(a int auto_increment primary key);
+create table t2(b int, a int);
+set @@session.sql_auto_is_null=1;
+insert into t1 values(null);
+insert into t2 select 1,a from t1 where a is null;
+set @@session.sql_auto_is_null=0;
+insert into t1 values(null);
+insert into t2 select 2,a from t1 where a is null;
+select * from t2 order by b;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t2 order by b;
+connection master;
+drop table t1,t2;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test
index 2ade41ee96d..b2e7e52f5e4 100644
--- a/mysql-test/t/rpl_trunc_binlog.test
+++ b/mysql-test/t/rpl_trunc_binlog.test
@@ -21,5 +21,5 @@ start slave;
# can't sync_with_master so we must sleep
sleep 3;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test
index 5eaec0727b6..f7ca51ecabc 100644
--- a/mysql-test/t/rpl_until.test
+++ b/mysql-test/t/rpl_until.test
@@ -24,7 +24,7 @@ show binlog events;
# try to replicate all queries until drop of t1
connection slave;
-start slave until master_log_file='master-bin.000001', master_log_pos=244;
+start slave until master_log_file='master-bin.000001', master_log_pos=304;
sleep 2;
# here table should be still not deleted
select * from t1;
@@ -42,7 +42,7 @@ sleep 2;
show slave status;
# try replicate all until second insert to t2;
-start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537;
+start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=710;
sleep 2;
select * from t2;
--replace_result $MASTER_MYPORT MASTER_MYPORT
@@ -57,8 +57,8 @@ connection slave;
sync_with_master;
stop slave;
-# this should stop immideately
-start slave until master_log_file='master-bin.000001', master_log_pos=561;
+# this should stop immediately as we are already there
+start slave until master_log_file='master-bin.000001', master_log_pos=710;
# 2 is not enough when running with valgrind
real_sleep 4
# here the sql slave thread should be stopped
@@ -79,4 +79,4 @@ start slave until relay_log_file='slave-relay-bin.000002';
start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561;
start slave sql_thread;
-start slave until master_log_file='master-bin.000001', master_log_pos=561;
+start slave until master_log_file='master-bin.000001', master_log_pos=710;
diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test
index 73b3ace473e..01d4b0e033c 100644
--- a/mysql-test/t/rpl_user_variables.test
+++ b/mysql-test/t/rpl_user_variables.test
@@ -46,7 +46,7 @@ save_master_pos;
connection slave;
sync_with_master;
select * from t1;
-show binlog events from 141;
+show binlog events from 179;
connection master;
drop table t1;
save_master_pos;
diff --git a/mysql-test/t/schema.test b/mysql-test/t/schema.test
new file mode 100644
index 00000000000..d9bd607b2db
--- /dev/null
+++ b/mysql-test/t/schema.test
@@ -0,0 +1,8 @@
+#
+# Just a couple of tests to make sure that schema works.
+#
+
+create schema foo;
+show create schema foo;
+show schemas;
+drop schema foo;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 5bae44796dc..3619cf116d1 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -10,6 +10,7 @@
drop table if exists t1,t2,t3,t4;
# The following may be left from older tests
drop table if exists t1_1,t1_2,t9_1,t9_2;
+drop view if exists v1;
--enable_warnings
CREATE TABLE t1 (
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index efbe2e9371d..b09d7240721 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -172,16 +172,24 @@ CREATE TABLE `a/b` (i INT);
#CREATE TABLE ```ab````cd``` (i INT);
#SHOW CREATE TABLE ```ab````cd```;
#DROP TABLE ```ab````cd```;
-
+#
#CREATE TABLE ```a` (i INT);
#SHOW CREATE TABLE ```a`;
#DROP TABLE ```a`;
-
-SET sql_mode= 'ANSI_QUOTES';
-
+#
+#SET sql_mode= 'ANSI_QUOTES';
+#
#CREATE TABLE """a" (i INT);
#SHOW CREATE TABLE """a";
#DROP TABLE """a";
+#
+#Bug #4374 SHOW TABLE STATUS FROM ignores collation_connection
+#set names latin1;
+#create database `ä`;
+#create table `ä`.`ä` (a int) engine=heap;
+#--replace_column 7 # 8 # 9 #
+#show table status from `ä` LIKE 'ä';
+#drop database `ä`;
#########################################################
# end of part that must be uncommented when WL#1324 is done
#########################################################
@@ -312,7 +320,6 @@ delete from mysql.db
where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
flush privileges;
-#Bug #4374 SHOW TABLE STATUS FROM ignores collation_connection
# This test fails on MAC OSX, so it is temporary disabled.
# This needs WL#1324 to be done.
#set names latin1;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
new file mode 100644
index 00000000000..c04f8e6f9e9
--- /dev/null
+++ b/mysql-test/t/sp-error.test
@@ -0,0 +1,638 @@
+#
+# Stored PROCEDURE error tests
+#
+
+# Make sure we don't have any procedures left.
+delete from mysql.proc;
+
+delimiter |;
+
+# This should give three syntax errors (sometimes crashed; bug #643)
+# (Unfortunately, this is not a 100% test, on some platforms this
+# passed despite the bug.)
+--error 1064
+create procedure syntaxerror(t int)|
+--error 1064
+create procedure syntaxerror(t int)|
+--error 1064
+create procedure syntaxerror(t int)|
+
+# Check that we get the right error, i.e. UDF declaration parses correctly,
+# but foo.so doesn't exist.
+# This generates an error message containing a misleading errno which
+# might vary between systems (it usually doesn't have anything to do with
+# the actual failing dlopen()).
+#--error 1126
+#create function foo returns real soname "foo.so"|
+
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( x int )|
+insert into t3 values (2), (3)|
+
+create procedure bad_into(out param int)
+ select x from t3 into param|
+
+--error 1172
+call bad_into(@x)|
+
+drop procedure bad_into|
+drop table t3|
+
+
+create procedure proc1()
+ set @x = 42|
+
+create function func1() returns int
+ return 42|
+
+# Can't create recursively
+--error 1303
+create procedure foo()
+ create procedure bar() set @x=3|
+--error 1303
+create procedure foo()
+ create function bar() returns double return 2.3|
+
+# Already exists
+--error 1304
+create procedure proc1()
+ set @x = 42|
+--error 1304
+create function func1() returns int
+ return 42|
+
+drop procedure proc1|
+drop function func1|
+
+# Does not exist
+--error 1305
+alter procedure foo|
+--error 1305
+alter function foo|
+--error 1305
+drop procedure foo|
+--error 1305
+drop function foo|
+--error 1305
+call foo()|
+drop procedure if exists foo|
+--error 1305
+show create procedure foo|
+
+# LEAVE/ITERATE/GOTO with no match
+--error 1308
+create procedure foo()
+foo: loop
+ leave bar;
+end loop|
+--error 1308
+create procedure foo()
+foo: loop
+ iterate bar;
+end loop|
+--error 1308
+create procedure foo()
+foo: begin
+ iterate foo;
+end|
+--error 1308
+create procedure foo()
+begin
+ goto foo;
+end|
+--error 1308
+create procedure foo()
+begin
+ begin
+ label foo;
+ end;
+ goto foo;
+end|
+--error 1308
+create procedure foo()
+begin
+ goto foo;
+ begin
+ label foo;
+ end;
+end|
+--error 1308
+create procedure foo()
+begin
+ begin
+ goto foo;
+ end;
+ begin
+ label foo;
+ end;
+end|
+--error 1308
+create procedure foo()
+begin
+ begin
+ label foo;
+ end;
+ begin
+ goto foo;
+ end;
+end|
+
+# Redefining label
+--error 1309
+create procedure foo()
+foo: loop
+ foo: loop
+ set @x=2;
+ end loop foo;
+end loop foo|
+
+# End label mismatch
+--error 1310
+create procedure foo()
+foo: loop
+ set @x=2;
+end loop bar|
+
+# RETURN in FUNCTION only
+--error 1313
+create procedure foo()
+ return 42|
+
+# Doesn't allow queries in FUNCTIONs (for now :-( )
+--error 1314
+create function foo() returns int
+begin
+ declare x int;
+ select max(c) into x from test.t;
+ return x;
+end|
+
+# Wrong number of arguments
+create procedure p(x int)
+ insert into test.t1 values (x)|
+create function f(x int) returns int
+ return x+42|
+
+--error 1318
+call p()|
+--error 1318
+call p(1, 2)|
+--error 1318
+select f()|
+--error 1318
+select f(1, 2)|
+
+drop procedure p|
+drop function f|
+
+--error 1319
+create procedure p(val int, out res int)
+begin
+ declare x int default 0;
+ declare continue handler for foo set x = 1;
+
+ insert into test.t1 values (val);
+ if (x) then
+ set res = 0;
+ else
+ set res = 1;
+ end if;
+end|
+
+--error 1319
+create procedure p(val int, out res int)
+begin
+ declare x int default 0;
+ declare foo condition for 1146;
+ declare continue handler for bar set x = 1;
+
+ insert into test.t1 values (val);
+ if (x) then
+ set res = 0;
+ else
+ set res = 1;
+ end if;
+end|
+
+--error 1320
+create function f(val int) returns int
+begin
+ declare x int;
+
+ set x = val+3;
+end|
+
+create function f(val int) returns int
+begin
+ declare x int;
+
+ set x = val+3;
+ if x < 4 then
+ return x;
+ end if;
+end|
+
+--error 1321
+select f(10)|
+
+drop function f|
+
+--error 1322
+create procedure p()
+begin
+ declare c cursor for insert into test.t1 values ("foo", 42);
+
+ open c;
+ close c;
+end|
+
+--error 1323
+create procedure p()
+begin
+ declare x int;
+ declare c cursor for select * into x from test.t limit 1;
+
+ open c;
+ close c;
+end|
+
+--error 1324
+create procedure p()
+begin
+ declare c cursor for select * from test.t;
+
+ open cc;
+ close c;
+end|
+
+--disable_warnings
+drop table if exists t1|
+--enable_warnings
+create table t1 (val int)|
+
+create procedure p()
+begin
+ declare c cursor for select * from test.t1;
+
+ open c;
+ open c;
+ close c;
+end|
+--error 1325
+call p()|
+drop procedure p|
+
+create procedure p()
+begin
+ declare c cursor for select * from test.t1;
+
+ open c;
+ close c;
+ close c;
+end|
+--error 1326
+call p()|
+drop procedure p|
+
+--error 1305
+alter procedure bar3 sql security invoker|
+
+drop table t1|
+
+--disable_warnings
+drop table if exists t1|
+--enable_warnings
+create table t1 (val int, x float)|
+insert into t1 values (42, 3.1), (19, 1.2)|
+
+--error 1327
+create procedure p()
+begin
+ declare x int;
+ declare c cursor for select * from t1;
+
+ open c;
+ fetch c into x, y;
+ close c;
+end|
+
+create procedure p()
+begin
+ declare x int;
+ declare c cursor for select * from t1;
+
+ open c;
+ fetch c into x;
+ close c;
+end|
+--error 1328
+call p()|
+drop procedure p|
+
+create procedure p()
+begin
+ declare x int;
+ declare y float;
+ declare z int;
+ declare c cursor for select * from t1;
+
+ open c;
+ fetch c into x, y, z;
+ close c;
+end|
+--error 1328
+call p()|
+drop procedure p|
+
+--error 1330
+create procedure p(in x int, x char(10))
+begin
+end|
+--error 1330
+create function p(x int, x char(10))
+begin
+end|
+
+--error 1331
+create procedure p()
+begin
+ declare x float;
+ declare x int;
+end|
+
+--error 1332
+create procedure p()
+begin
+ declare c condition for 1064;
+ declare c condition for 1065;
+end|
+
+--error 1333
+create procedure p()
+begin
+ declare c cursor for select * from t1;
+ declare c cursor for select field from t1;
+end|
+
+# USE is not allowed
+--error 1336
+create procedure u()
+ use sptmp|
+
+# Enforced standard order of declarations
+--error 1337
+create procedure p()
+begin
+ declare c cursor for select * from t1;
+ declare x int;
+end|
+--error 1337
+create procedure p()
+begin
+ declare x int;
+ declare continue handler for sqlstate '42S99' set x = 1;
+ declare foo condition for sqlstate '42S99';
+end|
+
+--error 1338
+create procedure p()
+begin
+ declare x int;
+ declare continue handler for sqlstate '42S99' set x = 1;
+ declare c cursor for select * from t1;
+end|
+
+--error 1358
+create procedure p()
+begin
+ declare continue handler for sqlexception
+ begin
+ goto L1;
+ end;
+
+ select field from t1;
+ label L1;
+end|
+
+#
+# BUG#1965
+#
+create procedure bug1965()
+begin
+ declare c cursor for select val from t1 order by valname;
+ open c;
+ close c;
+end|
+
+--error 1054
+call bug1965()|
+drop procedure bug1965|
+
+#
+# BUG#1966
+#
+--error 1327
+select 1 into a|
+
+#
+# BUG#1654
+#
+--error 1314
+create function bug1654()
+ returns int
+return (select sum(t.data) from test.t2 t)|
+
+#
+# BUG#1653
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (column_1_0 int)|
+
+create procedure bug1653()
+ update t3 set column_1 = 0|
+
+--error 1054
+call bug1653()|
+drop table t3|
+create table t3 (column_1 int)|
+call bug1653()|
+
+drop procedure bug1653|
+drop table t3|
+
+#
+# BUG#2259
+#
+# Note: When this bug existed, it did not necessarily cause a crash
+# in all builds, but valgrind did give warnings.
+create procedure bug2259()
+begin
+ declare v1 int;
+ declare c1 cursor for select s1 from t10;
+
+ fetch c1 into v1;
+end|
+
+--error 1326
+call bug2259()|
+drop procedure bug2259|
+
+#
+# BUG#2272
+#
+create procedure bug2272()
+begin
+ declare v int;
+
+ update t1 set v = 42;
+end|
+
+insert into t1 values (666, 51.3)|
+--error 1054
+call bug2272()|
+delete from t1|
+drop procedure bug2272|
+
+#
+# BUG#2329
+#
+create procedure bug2329_1()
+begin
+ declare v int;
+
+ insert into t1 (v) values (5);
+end|
+
+create procedure bug2329_2()
+begin
+ declare v int;
+
+ replace t1 set v = 5;
+end|
+
+--error 1054
+call bug2329_1()|
+--error 1054
+call bug2329_2()|
+drop procedure bug2329_1|
+drop procedure bug2329_2|
+
+#
+# BUG#3287
+#
+create function bug3287() returns int
+begin
+ declare v int default null;
+
+ case
+ when v is not null then return 1;
+ end case;
+ return 2;
+end|
+--error 1339
+select bug3287()|
+drop function bug3287|
+
+create procedure bug3287(x int)
+case x
+when 0 then
+ insert into test.t1 values (x, 0.1);
+when 1 then
+ insert into test.t1 values (x, 1.1);
+end case|
+--error 1339
+call bug3287(2)|
+drop procedure bug3287|
+
+#
+# BUG#3297
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (5),(6)|
+
+create procedure bug3279(out y int)
+begin
+ declare x int default 0;
+ begin
+ declare exit handler for sqlexception set x = x+1;
+ insert into t3 values (5);
+ end;
+ if x < 2 then
+ set x = x+1;
+ insert into t3 values (6);
+ end if;
+ set y = x;
+end|
+
+set @x = 0|
+--error 1062
+call bug3279(@x)|
+select @x|
+drop procedure bug3279|
+drop table t3|
+
+#
+# BUG#3339
+#
+--error 1049
+create procedure nodb.bug3339() begin end|
+
+#
+# BUG#2653
+#
+create procedure bug2653_1(a int, out b int)
+ set b = aa|
+
+create procedure bug2653_2(a int, out b int)
+begin
+ if aa < 0 then
+ set b = - a;
+ else
+ set b = a;
+ end if;
+end|
+
+--error 1054
+call bug2653_1(1, @b)|
+--error 1054
+call bug2653_2(2, @b)|
+
+drop procedure bug2653_1|
+drop procedure bug2653_2|
+
+#
+# BUG#4344
+#
+--error 1357
+create procedure bug4344() drop procedure bug4344|
+--error 1357
+create procedure bug4344() drop function bug4344|
+
+#
+# BUG#3294: Stored procedure crash if table dropped before use
+# (Actually, when an error occurs within an error handler.)
+--disable_warnings
+drop procedure if exists bug3294|
+--enable_warnings
+create procedure bug3294()
+begin
+ declare continue handler for sqlexception drop table t5;
+ drop table t5;
+end|
+
+--error 1051
+call bug3294()|
+drop procedure bug3294|
+
+
+drop table t1|
+
+delimiter ;|
diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test
new file mode 100644
index 00000000000..2b53bbc528a
--- /dev/null
+++ b/mysql-test/t/sp-security.test
@@ -0,0 +1,216 @@
+#
+# Testing SQL SECURITY of stored procedures
+#
+
+connect (con1root,localhost,root,,);
+
+connection con1root;
+use test;
+
+# Create user user1 with no particular access rights
+grant usage on *.* to user1@localhost;
+flush privileges;
+
+--disable_warnings
+drop database if exists db1_secret;
+--enable_warnings
+# Create our secret database
+create database db1_secret;
+
+# Can create a procedure in other db
+create procedure db1_secret.dummy() begin end;
+drop procedure db1_secret.dummy;
+
+use db1_secret;
+
+create table t1 ( u varchar(64), i int );
+
+# A test procedure and function
+create procedure stamp(i int)
+ insert into db1_secret.t1 values (user(), i);
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'stamp';
+
+create function db() returns varchar(64) return database();
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like 'db';
+
+# root can, of course
+call stamp(1);
+select * from t1;
+select db();
+
+connect (con2user1,localhost,user1,,);
+connect (con3anon,localhost,anon,,);
+
+
+#
+# User1 can
+#
+connection con2user1;
+
+# This should work...
+call db1_secret.stamp(2);
+select db1_secret.db();
+
+# ...but not this
+--error 1044
+select * from db1_secret.t1;
+
+# ...and not this
+--error 1049
+create procedure db1_secret.dummy() begin end;
+--error 1305
+drop procedure db1_secret.dummy;
+
+
+#
+# Anonymous can
+#
+connection con3anon;
+
+# This should work...
+call db1_secret.stamp(3);
+select db1_secret.db();
+
+# ...but not this
+--error 1044
+select * from db1_secret.t1;
+
+# ...and not this
+--error 1049
+create procedure db1_secret.dummy() begin end;
+--error 1305
+drop procedure db1_secret.dummy;
+
+
+#
+# Check it out
+#
+connection con1root;
+select * from t1;
+
+#
+# Change to invoker's rights
+#
+alter procedure stamp sql security invoker;
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'stamp';
+
+alter function db sql security invoker;
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like 'db';
+
+# root still can
+call stamp(4);
+select * from t1;
+select db();
+
+#
+# User1 cannot
+#
+connection con2user1;
+
+# This should not work
+--error 1044
+call db1_secret.stamp(5);
+--error 1044
+select db1_secret.db();
+
+#
+# Anonymous cannot
+#
+connection con3anon;
+
+# This should not work
+--error 1044
+call db1_secret.stamp(6);
+--error 1044
+select db1_secret.db();
+
+#
+# BUG#2777
+#
+
+connection con1root;
+--disable_warnings
+drop database if exists db2;
+--enable_warnings
+create database db2;
+
+use db2;
+
+create table t2 (s1 int);
+insert into t2 values (0);
+
+grant usage on db2.* to user1@localhost;
+grant select on db2.* to user1@localhost;
+grant usage on db2.* to user2@localhost;
+grant select,insert,update,delete on db2.* to user2@localhost;
+flush privileges;
+
+connection con2user1;
+use db2;
+
+create procedure p () insert into t2 values (1);
+
+# Check that this doesn't work.
+--error 1044
+call p();
+
+connect (con4user2,localhost,user2,,);
+
+connection con4user2;
+use db2;
+
+# This should not work, since p is executed with definer's (user1's) rights.
+--error 1044
+call p();
+select * from t2;
+
+create procedure q () insert into t2 values (2);
+
+call q();
+select * from t2;
+
+connection con2user1;
+use db2;
+
+# This should work
+call q();
+select * from t2;
+
+
+#
+# BUG#6030: Stored procedure has no appropriate DROP privilege
+# (or ALTER for that matter)
+
+# still connection con2user1 in db2
+
+# This should work:
+alter procedure p modifies sql data;
+drop procedure p;
+
+# This should NOT work
+--error 1370
+alter procedure q modifies sql data;
+--error 1370
+drop procedure q;
+
+connection con1root;
+use db2;
+# But root always can
+alter procedure q modifies sql data;
+drop procedure q;
+
+
+# Clean up
+#Still connection con1root;
+use test;
+select type,db,name from mysql.proc;
+drop database db1_secret;
+drop database db2;
+# Make sure the routines are gone
+select type,db,name from mysql.proc;
+# Get rid of the users
+delete from mysql.user where user='user1' or user='user2';
diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test
new file mode 100644
index 00000000000..27888158f03
--- /dev/null
+++ b/mysql-test/t/sp-threads.test
@@ -0,0 +1,54 @@
+#
+# Testing stored procedures with multiple connections
+#
+
+connect (con1root,localhost,root,,);
+connect (con2root,localhost,root,,);
+
+connection con1root;
+use test;
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (s1 int, s2 int, s3 int);
+
+delimiter //;
+create procedure bug4934()
+begin
+ insert into t1 values (1,0,1);
+end//
+delimiter ;//
+
+
+connection con2root;
+use test;
+
+call bug4934();
+select * from t1;
+
+
+connection con1root;
+
+drop table t1;
+create table t1 (s1 int, s2 int, s3 int);
+
+drop procedure bug4934;
+delimiter //;
+create procedure bug4934()
+begin
+end//
+delimiter ;//
+
+
+connection con2root;
+
+select * from t1;
+call bug4934();
+select * from t1;
+
+connection con1root;
+
+drop table t1;
+drop procedure bug4934;
+
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
new file mode 100644
index 00000000000..88d1b8c0356
--- /dev/null
+++ b/mysql-test/t/sp.test
@@ -0,0 +1,2343 @@
+#
+# Basic stored PROCEDURE tests
+#
+# Please keep this file free of --error cases and other
+# things that will not run in a single debugged mysqld
+# process (e.g. master-slave things).
+
+use test;
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+drop procedure if exists goto1;
+drop procedure if exists goto2;
+drop procedure if exists goto3;
+drop procedure if exists goto4;
+drop procedure if exists goto5;
+drop procedure if exists goto6;
+drop procedure if exists into_outfile;
+drop procedure if exists into_dumpfile;
+drop procedure if exists create_select;
+drop procedure if exists bar;
+drop procedure if exists hndlr1;
+drop procedure if exists hndlr2;
+drop procedure if exists hndlr3;
+drop procedure if exists hndlr4;
+drop procedure if exists cur1;
+drop procedure if exists cur2;
+drop procedure if exists chistics;
+drop procedure if exists chistics2;
+drop procedure if exists modes;
+drop procedure if exists dummy;
+drop procedure if exists bug;
+drop procedure if exists bug2;
+drop function if exists fac;
+--enable_warnings
+
+create table t1 (
+ id char(16) not null,
+ data int not null
+);
+create table t2 (
+ s char(16),
+ i int,
+ d double
+);
+
+
+# Single statement, no params.
+create procedure foo42()
+ insert into test.t1 values ("foo", 42);
+
+call foo42();
+select * from t1;
+delete from t1;
+drop procedure foo42;
+
+
+# Single statement, two IN params.
+create procedure bar(x char(16), y int)
+ insert into test.t1 values (x, y);
+
+call bar("bar", 666);
+select * from t1;
+delete from t1;
+# Don't drop procedure yet...
+
+
+# Now for multiple statements...
+delimiter |;
+
+# Empty statement
+create procedure empty()
+begin
+end|
+
+call empty()|
+drop procedure empty|
+
+# Scope test. This is legal (warnings might be possible in the future,
+# but for the time being, we just accept it).
+create procedure scope(a int, b float)
+begin
+ declare b int;
+ declare c float;
+
+ begin
+ declare c int;
+ end;
+end|
+
+drop procedure scope|
+
+# Two statements.
+create procedure two(x1 char(16), x2 char(16), y int)
+begin
+ insert into test.t1 values (x1, y);
+ insert into test.t1 values (x2, y);
+end|
+
+call two("one", "two", 3)|
+select * from t1|
+delete from t1|
+drop procedure two|
+
+
+# Simple test of local variables and SET.
+create procedure locset(x char(16), y int)
+begin
+ declare z1, z2 int;
+ set z1 = y;
+ set z2 = z1+2;
+ insert into test.t1 values (x, z2);
+end|
+
+call locset("locset", 19)|
+select * from t1|
+delete from t1|
+drop procedure locset|
+
+
+# In some contexts local variables are not recognized
+# (and in some, you have to qualify the identifier).
+create procedure setcontext()
+begin
+ declare data int default 2;
+
+ insert into t1 (id, data) values ("foo", 1);
+ replace t1 set data = data, id = "bar";
+ update t1 set id = "kaka", data = 3 where t1.data = data;
+end|
+
+call setcontext()|
+select * from t1|
+delete from t1|
+drop procedure setcontext|
+
+
+# Set things to null
+create table t3 ( d date, i int, f double, s varchar(32) )|
+
+create procedure nullset()
+begin
+ declare ld date;
+ declare li int;
+ declare lf double;
+ declare ls varchar(32);
+
+ set ld = null, li = null, lf = null, ls = null;
+ insert into t3 values (ld, li, lf, ls);
+
+ insert into t3 (i, f, s) values ((ld is null), 1, "ld is null"),
+ ((li is null), 1, "li is null"),
+ ((li = 0), null, "li = 0"),
+ ((lf is null), 1, "lf is null"),
+ ((lf = 0), null, "lf = 0"),
+ ((ls is null), 1, "ls is null");
+end|
+
+call nullset()|
+select * from t3|
+drop table t3|
+drop procedure nullset|
+
+
+# The peculiar (non-standard) mixture of variables types in SET.
+create procedure mixset(x char(16), y int)
+begin
+ declare z int;
+
+ set @z = y, z = 666, max_join_size = 100;
+ insert into test.t1 values (x, z);
+end|
+
+call mixset("mixset", 19)|
+show variables like 'max_join_size'|
+select id,data,@z from t1|
+delete from t1|
+drop procedure mixset|
+
+
+# Multiple CALL statements, one with OUT parameter.
+create procedure zip(x char(16), y int)
+begin
+ declare z int;
+ call zap(y, z);
+ call bar(x, z);
+end|
+
+# SET local variables and OUT parameter.
+create procedure zap(x int, out y int)
+begin
+ declare z int;
+ set z = x+1, y = z;
+end|
+
+call zip("zip", 99)|
+select * from t1|
+delete from t1|
+drop procedure zip|
+drop procedure bar|
+
+# Top-level OUT parameter
+call zap(7, @zap)|
+select @zap|
+
+drop procedure zap|
+
+
+# "Deep" calls...
+create procedure c1(x int)
+ call c2("c", x)|
+create procedure c2(s char(16), x int)
+ call c3(x, s)|
+create procedure c3(x int, s char(16))
+ call c4("level", x, s)|
+create procedure c4(l char(8), x int, s char(16))
+ insert into t1 values (concat(l,s), x)|
+
+call c1(42)|
+select * from t1|
+delete from t1|
+drop procedure c1|
+drop procedure c2|
+drop procedure c3|
+drop procedure c4|
+
+# INOUT test
+create procedure iotest(x1 char(16), x2 char(16), y int)
+begin
+ call inc2(x2, y);
+ insert into test.t1 values (x1, y);
+end|
+
+create procedure inc2(x char(16), y int)
+begin
+ call inc(y);
+ insert into test.t1 values (x, y);
+end|
+
+create procedure inc(inout io int)
+ set io = io + 1|
+
+call iotest("io1", "io2", 1)|
+select * from t1|
+delete from t1|
+drop procedure iotest|
+drop procedure inc2|
+
+# Propagating top-level @-vars
+create procedure incr(inout x int)
+ call inc(x)|
+
+# Before
+select @zap|
+call incr(@zap)|
+# After
+select @zap|
+
+drop procedure inc|
+drop procedure incr|
+
+# Call-by-value test
+# The expected result is:
+# ("cbv2", 4)
+# ("cbv1", 4711)
+create procedure cbv1()
+begin
+ declare y int default 3;
+
+ call cbv2(y+1, y);
+ insert into test.t1 values ("cbv1", y);
+end|
+
+create procedure cbv2(y1 int, inout y2 int)
+begin
+ set y2 = 4711;
+ insert into test.t1 values ("cbv2", y1);
+end|
+
+call cbv1()|
+select * from t1|
+delete from t1|
+drop procedure cbv1|
+drop procedure cbv2|
+
+
+# Subselect arguments
+
+insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)|
+
+create procedure sub1(id char(16), x int)
+ insert into test.t1 values (id, x)|
+
+# QQ This doesn't work yet
+#create procedure sub2(id char(16))
+#begin
+# declare x int;
+# set x = (select sum(t.x) from test.t2 t);
+# insert into test.t1 values (id, x);
+#end|
+
+create function sub3(i int) returns int
+ return i+1|
+
+call sub1("sub1a", (select 7))|
+call sub1("sub1b", (select max(i) from t2))|
+call sub1("sub1c", (select i,d from t2 limit 1))|
+call sub1("sub1d", (select 1 from (select 1) a))|
+#call sub2("sub2");
+select * from t1|
+select sub3((select max(i) from t2))|
+drop procedure sub1|
+#drop procedure sub2|
+drop function sub3|
+delete from t2|
+
+# Basic tests of the flow control constructs
+
+# Just test on 'x'...
+create procedure a0(x int)
+while x do
+ set x = x-1;
+ insert into test.t1 values ("a0", x);
+end while|
+
+call a0(3)|
+select * from t1|
+delete from t1|
+drop procedure a0|
+
+
+# The same, but with a more traditional test.
+create procedure a(x int)
+while x > 0 do
+ set x = x-1;
+ insert into test.t1 values ("a", x);
+end while|
+
+call a(3)|
+select * from t1|
+delete from t1|
+drop procedure a|
+
+
+# REPEAT
+create procedure b(x int)
+repeat
+ insert into test.t1 values (repeat("b",3), x);
+ set x = x-1;
+until x = 0 end repeat|
+
+call b(3)|
+select * from t1|
+delete from t1|
+drop procedure b|
+
+
+# Check that repeat isn't parsed the wrong way
+create procedure b2(x int)
+repeat(select 1 into outfile 'b2');
+ insert into test.t1 values (repeat("b2",3), x);
+ set x = x-1;
+until x = 0 end repeat|
+
+# We don't actually want to call it.
+drop procedure b2|
+
+
+# Labelled WHILE with ITERATE (pointless really)
+create procedure c(x int)
+hmm: while x > 0 do
+ insert into test.t1 values ("c", x);
+ set x = x-1;
+ iterate hmm;
+ insert into test.t1 values ("x", x);
+end while hmm|
+
+call c(3)|
+select * from t1|
+delete from t1|
+drop procedure c|
+
+
+# Labelled WHILE with LEAVE
+create procedure d(x int)
+hmm: while x > 0 do
+ insert into test.t1 values ("d", x);
+ set x = x-1;
+ leave hmm;
+ insert into test.t1 values ("x", x);
+end while|
+
+call d(3)|
+select * from t1|
+delete from t1|
+drop procedure d|
+
+
+# LOOP, with simple IF statement
+create procedure e(x int)
+foo: loop
+ if x = 0 then
+ leave foo;
+ end if;
+ insert into test.t1 values ("e", x);
+ set x = x-1;
+end loop foo|
+
+call e(3)|
+select * from t1|
+delete from t1|
+drop procedure e|
+
+
+# A full IF statement
+create procedure f(x int)
+if x < 0 then
+ insert into test.t1 values ("f", 0);
+elseif x = 0 then
+ insert into test.t1 values ("f", 1);
+else
+ insert into test.t1 values ("f", 2);
+end if|
+
+call f(-2)|
+call f(0)|
+call f(4)|
+select * from t1|
+delete from t1|
+drop procedure f|
+
+
+# This form of CASE is really just syntactic sugar for IF-ELSEIF-...
+create procedure g(x int)
+case
+when x < 0 then
+ insert into test.t1 values ("g", 0);
+when x = 0 then
+ insert into test.t1 values ("g", 1);
+else
+ insert into test.t1 values ("g", 2);
+end case|
+
+call g(-42)|
+call g(0)|
+call g(1)|
+select * from t1|
+delete from t1|
+drop procedure g|
+
+
+# The "simple CASE"
+create procedure h(x int)
+case x
+when 0 then
+ insert into test.t1 values ("h0", x);
+when 1 then
+ insert into test.t1 values ("h1", x);
+else
+ insert into test.t1 values ("h?", x);
+end case|
+
+call h(0)|
+call h(1)|
+call h(17)|
+select * from t1|
+delete from t1|
+drop procedure h|
+
+
+# It's actually possible to LEAVE a BEGIN-END block
+create procedure i(x int)
+foo:
+begin
+ if x = 0 then
+ leave foo;
+ end if;
+ insert into test.t1 values ("i", x);
+end foo|
+
+call i(0)|
+call i(3)|
+select * from t1|
+delete from t1|
+drop procedure i|
+
+
+# The non-standard GOTO, for compatibility
+#
+# QQQ The "label" syntax is temporary, it will (hopefully)
+# change to the more common "L:" syntax soon.
+#
+create procedure goto1()
+begin
+ declare y int;
+
+label a;
+ select * from t1;
+ select count(*) into y from t1;
+ if y > 2 then
+ goto b;
+ end if;
+ insert into t1 values ("j", y);
+ goto a;
+label b;
+end|
+
+call goto1()|
+drop procedure goto1|
+
+# With dummy handlers, just to test restore of contexts with jumps
+create procedure goto2(a int)
+begin
+ declare x int default 0;
+ declare continue handler for sqlstate '42S98' set x = 1;
+
+label a;
+ select * from t1;
+b:
+ while x < 2 do
+ begin
+ declare continue handler for sqlstate '42S99' set x = 2;
+
+ if a = 0 then
+ set x = x + 1;
+ iterate b;
+ elseif a = 1 then
+ leave b;
+ elseif a = 2 then
+ set a = 1;
+ goto a;
+ end if;
+ end;
+ end while b;
+
+ select * from t1;
+end|
+
+call goto2(0)|
+call goto2(1)|
+call goto2(2)|
+
+drop procedure goto2|
+delete from t1|
+
+# Check label visibility for some more cases. We don't call these.
+create procedure goto3()
+begin
+ label L1;
+ begin
+ end;
+ goto L1;
+end|
+drop procedure goto3|
+
+create procedure goto4()
+begin
+ begin
+ label lab1;
+ begin
+ goto lab1;
+ end;
+ end;
+end|
+drop procedure goto4|
+
+create procedure goto5()
+begin
+ begin
+ begin
+ goto lab1;
+ end;
+ label lab1;
+ end;
+end|
+drop procedure goto5|
+
+create procedure goto6()
+begin
+ label L1;
+ goto L5;
+ begin
+ label L2;
+ goto L1;
+ goto L5;
+ begin
+ label L3;
+ goto L1;
+ goto L2;
+ goto L3;
+ goto L4;
+ goto L5;
+ end;
+ goto L2;
+ goto L4;
+ label L4;
+ end;
+ label L5;
+ goto L1;
+end|
+drop procedure goto6|
+
+# SELECT with one of more result set sent back to the clinet
+insert into t1 values ("foo", 3), ("bar", 19)|
+insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
+
+create procedure sel1()
+begin
+ select * from t1;
+end|
+
+call sel1()|
+drop procedure sel1|
+
+create procedure sel2()
+begin
+ select * from t1;
+ select * from t2;
+end|
+
+call sel2()|
+drop procedure sel2|
+delete from t1|
+delete from t2|
+
+# SELECT INTO local variables
+create procedure into_test(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select id,data into x,y from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test("into", 100)|
+select * from t1|
+delete from t1|
+drop procedure into_test|
+
+
+# SELECT INTO with a mix of local and global variables
+create procedure into_test2(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select id,data into x,@z from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test2("into", 100)|
+select id,data,@z from t1|
+delete from t1|
+drop procedure into_test2|
+
+
+# SELECT * INTO ... (bug test)
+create procedure into_test3()
+begin
+ declare x char(16);
+ declare y int;
+
+ select * into x,y from test.t1 limit 1;
+ insert into test.t2 values (x, y, 0.0);
+end|
+
+insert into t1 values ("into3", 19)|
+# Two call needed for bug test
+call into_test3()|
+call into_test3()|
+select * from t2|
+delete from t1|
+delete from t2|
+drop procedure into_test3|
+
+
+# SELECT INTO with no data is a warning ("no data", which we will
+# not see normally). When not caught, execution proceeds.
+create procedure into_test4()
+begin
+ declare x int;
+
+ select data into x from test.t1 limit 1;
+ insert into test.t3 values ("into4", x);
+end|
+
+delete from t1|
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( s char(16), d int)|
+call into_test4()|
+select * from t3|
+insert into t1 values ("i4", 77)|
+call into_test4()|
+select * from t3|
+delete from t1|
+drop table t3|
+drop procedure into_test4|
+
+
+# These two (and the two procedures above) caused an assert() to fail in
+# sql_base.cc:lock_tables() at some point.
+
+create procedure into_outfile(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select * into outfile "/tmp/spout" from test.t1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+system rm -f /tmp/spout|
+call into_outfile("ofile", 1)|
+system rm -f /tmp/spout|
+delete from t1|
+drop procedure into_outfile|
+
+create procedure into_dumpfile(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ select * into dumpfile "/tmp/spdump" from test.t1 limit 1;
+ insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+system rm -f /tmp/spdump|
+call into_dumpfile("dfile", 1)|
+system rm -f /tmp/spdump|
+delete from t1|
+drop procedure into_dumpfile|
+
+
+create procedure create_select(x char(16), y int)
+begin
+ insert into test.t1 values (x, y);
+ create table test.t3 select * from test.t1;
+ insert into test.t3 values (concat(x, "2"), y+2);
+end|
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+call create_select("cs", 90)|
+select * from t1, t3|
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+delete from t1|
+drop procedure create_select|
+
+
+# A minimal, constant FUNCTION.
+create function e() returns double
+ return 2.7182818284590452354|
+
+set @e = e()|
+select e(), @e|
+
+# A minimal function with one argument
+create function inc(i int) returns int
+ return i+1|
+
+select inc(1), inc(99), inc(-71)|
+
+# A minimal function with two arguments
+create function mul(x int, y int) returns int
+ return x*y|
+
+select mul(1,1), mul(3,5), mul(4711, 666)|
+
+# A minimal string function
+create function append(s1 char(8), s2 char(8)) returns char(16)
+ return concat(s1, s2)|
+
+select append("foo", "bar")|
+
+# A function with flow control
+create function fac(n int unsigned) returns bigint unsigned
+begin
+ declare f bigint unsigned default 1;
+
+ while n > 1 do
+ set f = f * n;
+ set n = n - 1;
+ end while;
+ return f;
+end|
+
+select fac(1), fac(2), fac(5), fac(10)|
+
+# Nested calls
+create function fun(d double, i int, u int unsigned) returns double
+ return mul(inc(i), fac(u)) / e()|
+
+select fun(2.3, 3, 5)|
+
+
+# Various function calls in differen statements
+
+insert into t2 values (append("xxx", "yyy"), mul(4,3), e())|
+insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))|
+
+# These don't work yet.
+select * from t2 where s = append("a", "b")|
+select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)|
+select * from t2 where d = e()|
+select * from t2|
+delete from t2|
+
+drop function e|
+drop function inc|
+drop function mul|
+drop function append|
+drop function fun|
+
+
+#
+# CONDITIONs and HANDLERs
+#
+
+create procedure hndlr1(val int)
+begin
+ declare x int default 0;
+ declare foo condition for 1146;
+ declare bar condition for sqlstate '42S98'; # Just for testing syntax
+ declare zip condition for sqlstate value '42S99'; # Just for testing syntax
+ declare continue handler for foo set x = 1;
+
+ insert into test.t666 values ("hndlr1", val); # Non-existing table
+ if (x) then
+ insert into test.t1 values ("hndlr1", val); # This instead then
+ end if;
+end|
+
+call hndlr1(42)|
+select * from t1|
+delete from t1|
+drop procedure hndlr1|
+
+create procedure hndlr2(val int)
+begin
+ declare x int default 0;
+
+ begin
+ declare exit handler for sqlstate '42S02' set x = 1;
+
+ insert into test.t666 values ("hndlr2", val); # Non-existing table
+ end;
+
+ insert into test.t1 values ("hndlr2", x);
+end|
+
+call hndlr2(42)|
+select * from t1|
+delete from t1|
+drop procedure hndlr2|
+
+
+create procedure hndlr3(val int)
+begin
+ declare x int default 0;
+ declare continue handler for sqlexception # Any error
+ begin
+ declare z int;
+
+ set z = 2 * val;
+ set x = 1;
+ end;
+
+ if val < 10 then
+ begin
+ declare y int;
+
+ set y = val + 10;
+ insert into test.t666 values ("hndlr3", y); # Non-existing table
+ if x then
+ insert into test.t1 values ("hndlr3", y);
+ end if;
+ end;
+ end if;
+end|
+
+call hndlr3(3)|
+select * from t1|
+delete from t1|
+drop procedure hndlr3|
+
+
+# Variables might be uninitialized when using handlers
+# (Otherwise the compiler can detect if a variable is not set, but
+# not in this case.)
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( id char(16), data int )|
+
+create procedure hndlr4()
+begin
+ declare x int default 0;
+ declare val int; # No default
+ declare continue handler for sqlstate '02000' set x=1;
+
+ select data into val from test.t3 where id='z' limit 1; # No hits
+
+ insert into test.t3 values ('z', val);
+end|
+
+call hndlr4()|
+select * from t3|
+drop table t3|
+drop procedure hndlr4|
+
+
+#
+# Cursors
+#
+create procedure cur1()
+begin
+ declare a char(16);
+ declare b int;
+ declare c double;
+ declare done int default 0;
+ declare c cursor for select * from test.t2;
+ declare continue handler for sqlstate '02000' set done = 1;
+
+ open c;
+ repeat
+ fetch c into a, b, c;
+ if not done then
+ insert into test.t1 values (a, b+c);
+ end if;
+ until done end repeat;
+ close c;
+end|
+
+insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)|
+call cur1()|
+select * from t1|
+drop procedure cur1|
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( s char(16), i int )|
+
+create procedure cur2()
+begin
+ declare done int default 0;
+ declare c1 cursor for select id,data from test.t1;
+ declare c2 cursor for select i from test.t2;
+ declare continue handler for sqlstate '02000' set done = 1;
+
+ open c1;
+ open c2;
+ repeat
+ begin
+ declare a char(16);
+ declare b,c int;
+
+ fetch from c1 into a, b;
+ fetch next from c2 into c;
+ if not done then
+ if b < c then
+ insert into test.t3 values (a, b);
+ else
+ insert into test.t3 values (a, c);
+ end if;
+ end if;
+ end;
+ until done end repeat;
+ close c1;
+ close c2;
+end|
+
+call cur2()|
+select * from t3|
+delete from t1|
+delete from t2|
+drop table t3|
+drop procedure cur2|
+
+
+# The few characteristics we parse
+create procedure chistics()
+ language sql
+ modifies sql data
+ not deterministic
+ sql security definer
+ comment 'Characteristics procedure test'
+ insert into t1 values ("chistics", 1)|
+
+show create procedure chistics|
+# Call it, just to make sure.
+call chistics()|
+select * from t1|
+delete from t1|
+alter procedure chistics sql security invoker|
+show create procedure chistics|
+drop procedure chistics|
+
+create function chistics() returns int
+ language sql
+ deterministic
+ sql security invoker
+ comment 'Characteristics procedure test'
+ return 42|
+
+show create function chistics|
+# Call it, just to make sure.
+select chistics()|
+alter function chistics
+ no sql
+ comment 'Characteristics function test'|
+show create function chistics|
+drop function chistics|
+
+
+# Check mode settings
+insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)|
+
+set @@sql_mode = 'ANSI'|
+delimiter $|
+create procedure modes(out c1 int, out c2 int)
+begin
+ declare done int default 0;
+ declare x int;
+ declare c cursor for select data from t1;
+ declare continue handler for sqlstate '02000' set done = 1;
+
+ select 1 || 2 into c1;
+ set c2 = 0;
+ open c;
+ repeat
+ fetch c into x;
+ if not done then
+ set c2 = c2 + 1;
+ end if;
+ until done end repeat;
+ close c;
+end$
+delimiter |$
+set @@sql_mode = ''|
+
+set sql_select_limit = 1|
+call modes(@c1, @c2)|
+set sql_select_limit = default|
+
+select @c1, @c2|
+delete from t1|
+drop procedure modes|
+
+
+# Check that dropping a database without routines works.
+# (Dropping with routines is tested in sp-security.test)
+# First an empty db.
+create database sp_db1|
+drop database sp_db1|
+
+# Again, with a table.
+create database sp_db2|
+use sp_db2|
+# Just put something in here...
+create table t3 ( s char(4), t int )|
+insert into t3 values ("abcd", 42), ("dcba", 666)|
+use test|
+drop database sp_db2|
+
+# And yet again, with just a procedure.
+create database sp_db3|
+use sp_db3|
+create procedure dummy(out x int)
+ set x = 42|
+use test|
+drop database sp_db3|
+# Check that it's gone
+select type,db,name from mysql.proc where db = 'sp_db3'|
+
+
+# ROW_COUNT() function after a CALL
+# We test the other cases here too, although it's not strictly SP specific
+create procedure rc()
+begin
+ delete from t1;
+ insert into t1 values ("a", 1), ("b", 2), ("c", 3);
+end|
+
+call rc()|
+select row_count()|
+update t1 set data=42 where id = "b";
+select row_count()|
+delete from t1|
+select row_count()|
+delete from t1|
+select row_count()|
+select * from t1|
+select row_count()|
+drop procedure rc|
+
+
+#
+# Test cases for old bugs
+#
+
+#
+# BUG#822
+#
+create procedure bug(a_id char(16), a_data int)
+begin
+ declare n int;
+ select count(*) into n from t1 where id = a_id and data = a_data;
+ if n = 0 then
+ insert into t1 (id, data) values (a_id, a_data);
+ end if;
+end|
+
+call bug('foo', 42)|
+call bug('foo', 42)|
+call bug('bar', 666)|
+select * from t1|
+delete from t1|
+drop procedure bug|
+
+#
+# BUG#1495
+#
+create procedure bug()
+begin
+ declare x int;
+
+ select data into x from t1 order by id limit 1;
+ if x > 10 then
+ insert into t1 values ("less", x-10);
+ else
+ insert into t1 values ("more", x+10);
+ end if;
+end|
+
+insert into t1 values ('foo', 12)|
+call bug()|
+delete from t1 where id='foo'|
+insert into t1 values ('bar', 7)|
+call bug()|
+delete from t1 where id='bar'|
+select * from t1|
+delete from t1|
+drop procedure bug|
+
+#
+# BUG#1547
+#
+create procedure bug(s char(16))
+begin
+ declare x int;
+
+ select data into x from t1 where s = id limit 1;
+ if x > 10 then
+ insert into t1 values ("less", x-10);
+ else
+ insert into t1 values ("more", x+10);
+ end if;
+end|
+
+insert into t1 values ("foo", 12), ("bar", 7)|
+call bug("foo")|
+call bug("bar")|
+select * from t1|
+delete from t1|
+drop procedure bug|
+
+#
+# BUG#1656
+#
+--disable_warnings
+drop table if exists t70|
+--enable_warnings
+create table t70 (s1 int,s2 int)|
+insert into t70 values (1,2)|
+
+create procedure bug(out p1 int, out p2 int)
+ select * into p1, p1 from t70|
+
+call bug(@1, @2)|
+select @1, @2|
+drop table t70|
+drop procedure bug|
+
+#
+# BUG#1862
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3(a int)|
+
+create procedure bug()
+begin
+ insert into t3 values(2);
+ flush tables;
+end|
+
+call bug()|
+# the second call caused a segmentation
+call bug()|
+select * from t3|
+drop table t3|
+drop procedure bug|
+
+#
+# BUG#1874
+#
+create procedure bug()
+begin
+ declare x int;
+ declare y double;
+ select max(data) into x from t1;
+ insert into t2 values ("max", x, 0);
+ select min(data) into x from t1;
+ insert into t2 values ("min", x, 0);
+ select sum(data) into x from t1;
+ insert into t2 values ("sum", x, 0);
+ select avg(data) into y from t1;
+ insert into t2 values ("avg", 0, y);
+end|
+
+insert into t1 (data) values (3), (1), (5), (9), (4)|
+call bug()|
+select * from t2|
+delete from t1|
+delete from t2|
+drop procedure bug|
+
+#
+# BUG#2260
+#
+create procedure bug()
+begin
+ declare v1 int;
+ declare c1 cursor for select data from t1;
+ declare continue handler for not found set @x2 = 1;
+
+ open c1;
+ fetch c1 into v1;
+ set @x2 = 2;
+ close c1;
+end|
+
+call bug()|
+select @x2|
+drop procedure bug|
+
+#
+# BUG#2267
+#
+create procedure bug2267_1()
+begin
+ show procedure status;
+end|
+
+create procedure bug2267_2()
+begin
+ show function status;
+end|
+
+create procedure bug2267_3()
+begin
+ show create procedure bug2267_1;
+end|
+
+create procedure bug2267_4()
+begin
+ show create function fac;
+end|
+
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+call bug2267_1()|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+call bug2267_2()|
+call bug2267_3()|
+call bug2267_4()|
+
+drop procedure bug2267_1|
+drop procedure bug2267_2|
+drop procedure bug2267_3|
+drop procedure bug2267_4|
+
+#
+# BUG#2227
+#
+create procedure bug(x int)
+begin
+ declare y float default 2.6;
+ declare z char(16) default "zzz";
+
+ select 1.3, x, y, 42, z;
+end|
+
+call bug(9)|
+drop procedure bug|
+
+#
+# BUG#2614
+#
+create procedure bug()
+begin
+ drop table if exists t3;
+ create table t3 (id int default '0' not null);
+ insert into t3 select 12;
+ insert into t3 select * from t3;
+end|
+
+--disable_warnings
+call bug()|
+--enable_warnings
+call bug()|
+drop table t3|
+drop procedure bug|
+
+#
+# BUG#2674
+#
+create function bug () returns int
+ return @@sort_buffer_size|
+
+set @osbs = @@sort_buffer_size|
+set @@sort_buffer_size = 262000|
+select bug()|
+drop function bug|
+set @@sort_buffer_size = @osbs|
+
+#
+# BUG#3259
+#
+create procedure bug3259_1 () begin end|
+create procedure BUG3259_2 () begin end|
+create procedure Bug3259_3 () begin end|
+
+call BUG3259_1()|
+call BUG3259_1()|
+call bug3259_2()|
+call Bug3259_2()|
+call bug3259_3()|
+call bUG3259_3()|
+
+drop procedure bUg3259_1|
+drop procedure BuG3259_2|
+drop procedure BUG3259_3|
+
+#
+# BUG##2772
+#
+create function bug() returns char(10) character set latin2
+ return 'a'|
+
+select bug()|
+drop function bug|
+
+#
+# BUG#2776
+#
+create procedure bug(out x int)
+begin
+ declare v int;
+
+ set v = default;
+ set x = v;
+end|
+
+create procedure bug2(out x int)
+begin
+ declare v int default 42;
+
+ set v = default;
+ set x = v;
+end|
+
+set @x = 1|
+call bug(@x)|
+select @x|
+call bug2(@x)|
+select @x|
+drop procedure bug|
+drop procedure bug2|
+
+#
+# BUG#2780
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (s1 smallint)|
+
+insert into t3 values (123456789012)|
+
+create procedure bug()
+begin
+ declare exit handler for sqlwarning set @x = 1;
+
+ set @x = 0;
+ insert into t3 values (123456789012);
+ insert into t3 values (0);
+end|
+
+call bug()|
+select @x|
+select * from t3|
+
+drop procedure bug|
+drop table t3|
+
+#
+# BUG#1863
+#
+create table t3 (content varchar(10) )|
+insert into t3 values ("test1")|
+insert into t3 values ("test2")|
+create table t4 (f1 int, rc int, t3 int)|
+
+create procedure bug1863(in1 int)
+begin
+
+ declare ind int default 0;
+ declare t1 int;
+ declare t2 int;
+ declare t3 int;
+
+ declare rc int default 0;
+ declare continue handler for 1065 set rc = 1;
+
+ drop table if exists temp_t1;
+ create temporary table temp_t1 (
+ f1 int auto_increment, f2 varchar(20), primary key (f1)
+ );
+
+ insert into temp_t1 (f2) select content from t3;
+
+ select f2 into t3 from temp_t1 where f1 = 10;
+
+ if (rc) then
+ insert into t4 values (1, rc, t3);
+ end if;
+
+ insert into t4 values (2, rc, t3);
+
+end|
+
+call bug1863(10)|
+call bug1863(10)|
+select * from t4|
+
+drop procedure bug1863|
+drop table t3, t4|
+
+#
+# BUG#2656
+#
+--disable_warnings
+drop table if exists t3, t4|
+--enable_warnings
+
+create table t3 (
+ OrderID int not null,
+ MarketID int,
+ primary key (OrderID)
+)|
+
+create table t4 (
+ MarketID int not null,
+ Market varchar(60),
+ Status char(1),
+ primary key (MarketID)
+)|
+
+insert t3 (OrderID,MarketID) values (1,1)|
+insert t3 (OrderID,MarketID) values (2,2)|
+insert t4 (MarketID,Market,Status) values (1,"MarketID One","A")|
+insert t4 (MarketID,Market,Status) values (2,"MarketID Two","A")|
+
+create procedure bug2656_1()
+begin
+ select
+ m.Market
+ from t4 m JOIN t3 o
+ ON o.MarketID != 1 and o.MarketID = m.MarketID;
+end |
+
+create procedure bug2656_2()
+begin
+ select
+ m.Market
+ from
+ t4 m, t3 o
+ where
+ m.MarketID != 1 and m.MarketID = o.MarketID;
+
+end |
+
+call bug2656_1()|
+call bug2656_1()|
+call bug2656_2()|
+call bug2656_2()|
+drop procedure bug2656_1|
+drop procedure bug2656_2|
+drop table t3, t4|
+
+
+#
+# BUG#3426
+#
+create procedure bug3426(in_time int unsigned, out x int)
+begin
+ if in_time is null then
+ set @stamped_time=10;
+ set x=1;
+ else
+ set @stamped_time=in_time;
+ set x=2;
+ end if;
+end|
+
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+# Clear SP cache
+alter procedure bug3426 sql security invoker|
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+
+drop procedure bug3426|
+
+#
+# BUG#3448
+#
+--disable_warnings
+drop table if exists t3, t4|
+
+create table t3 (
+ a int primary key,
+ ach char(1)
+) engine = innodb|
+
+create table t4 (
+ b int primary key ,
+ bch char(1)
+) engine = innodb|
+--enable_warnings
+
+insert into t3 values (1 , 'aCh1' ) , ('2' , 'aCh2')|
+insert into t4 values (1 , 'bCh1' )|
+
+create procedure bug3448()
+ select * from t3 inner join t4 on t3.a = t4.b|
+
+select * from t3 inner join t4 on t3.a = t4.b|
+call bug3448()|
+call bug3448()|
+
+drop procedure bug3448|
+drop table t3, t4|
+
+
+#
+# BUG#3734
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (
+ id int unsigned auto_increment not null primary key,
+ title VARCHAR(200),
+ body text,
+ fulltext (title,body)
+)|
+
+insert into t3 (title,body) values
+ ('MySQL Tutorial','DBMS stands for DataBase ...'),
+ ('How To Use MySQL Well','After you went through a ...'),
+ ('Optimizing MySQL','In this tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...')|
+
+create procedure bug3734 (param1 varchar(100))
+ select * from t3 where match (title,body) against (param1)|
+
+call bug3734('database')|
+call bug3734('Security')|
+
+drop procedure bug3734|
+drop table t3|
+
+#
+# BUG#3863
+#
+create procedure bug3863()
+begin
+ set @a = 0;
+ while @a < 5 do
+ set @a = @a + 1;
+ end while;
+end|
+
+call bug3863()|
+select @a|
+call bug3863()|
+select @a|
+
+drop procedure bug3863|
+
+#
+# BUG#2460
+#
+
+create table t3 (
+ id int(10) unsigned not null default 0,
+ rid int(10) unsigned not null default 0,
+ msg text not null,
+ primary key (id),
+ unique key rid (rid, id)
+)|
+
+create procedure bug2460_1(in v int)
+begin
+ ( select n0.id from t3 as n0 where n0.id = v )
+ union
+ ( select n0.id from t3 as n0, t3 as n1
+ where n0.id = n1.rid and n1.id = v )
+ union
+ ( select n0.id from t3 as n0, t3 as n1, t3 as n2
+ where n0.id = n1.rid and n1.id = n2.rid and n2.id = v );
+end|
+
+call bug2460_1(2)|
+call bug2460_1(2)|
+insert into t3 values (1, 1, 'foo'), (2, 1, 'bar'), (3, 1, 'zip zap')|
+call bug2460_1(2)|
+call bug2460_1(2)|
+
+create procedure bug2460_2()
+begin
+ drop table if exists t3;
+ create table t3 (s1 int);
+ insert into t3 select 1 union select 1;
+end|
+
+call bug2460_2()|
+call bug2460_2()|
+select * from t3|
+
+drop procedure bug2460_1|
+drop procedure bug2460_2|
+drop table t3|
+
+
+#
+# BUG#2564
+#
+set @@sql_mode = ''|
+create procedure bug2564_1()
+ comment 'Joe''s procedure'
+ insert into `t1` values ("foo", 1)|
+
+set @@sql_mode = 'ANSI_QUOTES'|
+create procedure bug2564_2()
+ insert into "t1" values ('foo', 1)|
+
+delimiter $|
+set @@sql_mode = ''$
+create function bug2564_3(x int, y int) returns int
+ return x || y$
+
+set @@sql_mode = 'ANSI'$
+create function bug2564_4(x int, y int) returns int
+ return x || y$
+delimiter |$
+
+set @@sql_mode = ''|
+show create procedure bug2564_1|
+show create procedure bug2564_2|
+show create function bug2564_3|
+show create function bug2564_4|
+
+drop procedure bug2564_1|
+drop procedure bug2564_2|
+drop function bug2564_3|
+drop function bug2564_4|
+
+#
+# BUG#3132
+#
+create function bug3132(s char(20)) returns char(50)
+ return concat('Hello, ', s, '!')|
+
+select bug3132('Bob') union all select bug3132('Judy')|
+drop function bug3132|
+
+#
+# BUG#3843
+#
+create procedure bug3843()
+ analyze table t1|
+
+# Testing for packets out of order
+call bug3843()|
+call bug3843()|
+select 1+2|
+
+drop procedure bug3843|
+
+#
+# BUG#3368
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( s1 char(10) )|
+insert into t3 values ('a'), ('b')|
+
+create procedure bug3368(v char(10))
+begin
+ select group_concat(v) from t3;
+end|
+
+call bug3368('x')|
+call bug3368('yz')|
+drop procedure bug3368|
+drop table t3|
+
+#
+# BUG#4579
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (f1 int, f2 int);
+insert into t3 values (1,1);
+
+create procedure bug4579_1 ()
+begin
+ declare sf1 int;
+
+ select f1 into sf1 from t3 where f1=1 and f2=1;
+ update t3 set f2 = f2 + 1 where f1=1 and f2=1;
+ call bug4579_2();
+end|
+
+create procedure bug4579_2 ()
+begin
+end|
+
+call bug4579_1()|
+call bug4579_1()|
+call bug4579_1()|
+
+drop procedure bug4579_1|
+drop procedure bug4579_2|
+drop table t3|
+
+
+#
+# BUG#4726
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+
+create table t3 (f1 int, f2 int, f3 int)|
+insert into t3 values (1,1,1)|
+
+create procedure bug4726()
+begin
+ declare tmp_o_id INT;
+ declare tmp_d_id INT default 1;
+
+ while tmp_d_id <= 2 do
+ begin
+ select f1 into tmp_o_id from t3 where f2=1 and f3=1;
+ set tmp_d_id = tmp_d_id + 1;
+ end;
+ end while;
+end|
+
+call bug4726()|
+call bug4726()|
+call bug4726()|
+
+drop procedure bug4726|
+drop table t3|
+
+#
+# BUG#4318
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+
+create table t3 (s1 int)|
+insert into t3 values (3), (4)|
+
+create procedure bug4318()
+ handler t3 read next|
+
+handler t3 open|
+# Expect no results, as tables are closed, but there shouldn't be any errors
+call bug4318()|
+call bug4318()|
+handler t3 close|
+
+drop procedure bug4318|
+drop table t3|
+
+#
+# BUG#4902: Stored procedure with SHOW WARNINGS leads to packet error
+#
+# Added tests for most other show commands we could find too.
+# (Skipping those already tested, and the ones depending on optional handlers.)
+#
+# Note: This will return a large number of results of different formats,
+# which makes it impossible to filter with --replace_column.
+# It's possible that some of these are not deterministic across
+# platforms. If so, just remove the offending command.
+#
+create procedure bug4902()
+begin
+ show charset like 'foo';
+ show collation like 'foo';
+ show column types;
+ show create table t1;
+ show create database test;
+ show databases like 'foo';
+ show errors;
+ show columns from t1;
+ show grants for 'root'@'localhost';
+ show keys from t1;
+ show open tables like 'foo';
+ show privileges;
+ show status like 'foo';
+ show tables like 'foo';
+ show variables like 'foo';
+ show warnings;
+end|
+#show binlog events;
+#show storage engines;
+#show master status;
+#show slave hosts;
+#show slave status;
+
+call bug4902()|
+call bug4902()|
+
+drop procedure bug4902|
+
+# We need separate SP for SHOW PROCESSLIST since we want use replace_column
+create procedure bug4902_2()
+begin
+ show processlist;
+end|
+--replace_column 1 # 6 #
+call bug4902_2()|
+--replace_column 1 # 6 #
+call bug4902_2()|
+drop procedure bug4902_2|
+
+#
+# BUG#4904
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+
+create procedure bug4904()
+begin
+ declare continue handler for sqlstate 'HY000' begin end;
+
+ create table t2 as select * from t;
+end|
+
+call bug4904()|
+
+drop procedure bug4904|
+
+#
+# BUG#336
+#
+create procedure bug336(out y int)
+begin
+ declare x int;
+ set x = (select sum(t.data) from test.t1 t);
+ set y = x;
+end|
+
+insert into t1 values ("a", 2), ("b", 3)|
+call bug336(@y)|
+select @y|
+delete from t1|
+drop procedure bug336|
+
+#
+# BUG#3157
+#
+create procedure bug3157()
+begin
+ if exists(select * from t1) then
+ set @n= @n + 1;
+ end if;
+ if (select count(*) from t1) then
+ set @n= @n + 1;
+ end if;
+end|
+
+set @n = 0|
+insert into t1 values ("a", 1)|
+call bug3157()|
+select @n|
+delete from t1|
+drop procedure bug3157|
+
+#
+# BUG#5251: mysql changes creation time of a procedure/function when altering
+#
+create procedure bug5251()
+begin
+end|
+
+select created into @c1 from mysql.proc
+ where db='test' and name='bug5251'|
+--sleep 2
+alter procedure bug5251 comment 'foobar'|
+select count(*) from mysql.proc
+ where db='test' and name='bug5251' and created = @c1|
+
+drop procedure bug5251|
+
+#
+# BUG#5279: Stored procedure packets out of order if CHECKSUM TABLE
+#
+create procedure bug5251()
+ checksum table t1|
+
+call bug5251()|
+call bug5251()|
+drop procedure bug5251|
+
+#
+# BUG#5287: Stored procedure crash if leave outside loop
+#
+create procedure bug5287(param1 int)
+label1:
+ begin
+ declare c cursor for select 5;
+
+ loop
+ if param1 >= 0 then
+ leave label1;
+ end if;
+ end loop;
+end|
+call bug5287(1)|
+drop procedure bug5287|
+
+
+#
+# BUG#5307: Stored procedure allows statement after BEGIN ... END
+#
+create procedure bug5307()
+begin
+end; set @x = 3|
+
+call bug5307()|
+select @x|
+drop procedure bug5307|
+
+#
+# BUG#5258: Stored procedure modified date is 0000-00-00
+# (This was a design flaw)
+create procedure bug5258()
+begin
+end|
+
+create procedure bug5258_aux()
+begin
+ declare c, m char(19);
+
+ select created,modified into c,m from mysql.proc where name = 'bug5258';
+ if c = m then
+ select 'Ok';
+ else
+ select c, m;
+ end if;
+end|
+
+call bug5258_aux()|
+
+drop procedure bug5258|
+drop procedure bug5258_aux|
+
+#
+# BUG#4487: Stored procedure connection aborted if uninitialized char
+#
+create function bug4487() returns char
+begin
+ declare v char;
+ return v;
+end|
+
+select bug4487()|
+drop function bug4487|
+
+
+#
+# BUG#4941: Stored procedure crash fetching null value into variable.
+#
+--disable_warnings
+drop procedure if exists bug4941|
+--enable_warnings
+create procedure bug4941(out x int)
+begin
+ declare c cursor for select i from t2 limit 1;
+ open c;
+ fetch c into x;
+ close c;
+end|
+
+insert into t2 values (null, null, null)|
+set @x = 42|
+call bug4941(@x)|
+select @x|
+delete from t1|
+drop procedure bug4941|
+
+
+#
+# BUG#3583: query cache doesn't work for stored procedures
+#
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+create procedure bug3583()
+begin
+ declare c int;
+
+ select * from t1;
+ select count(*) into c from t1;
+ select c;
+end|
+
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+call bug3583()|
+show status like 'Qcache_hits'|
+call bug3583()|
+call bug3583()|
+show status like 'Qcache_hits'|
+
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+
+#
+# BUG#4905: Stored procedure doesn't clear for "Rows affected"
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug4905|
+--enable_warnings
+
+create table t3 (s1 int,primary key (s1))|
+
+create procedure bug4905()
+begin
+ declare v int;
+ declare continue handler for sqlstate '23000' set v = 5;
+
+ insert into t3 values (1);
+end|
+
+call bug4905()|
+select row_count()|
+call bug4905()|
+select row_count()|
+call bug4905()|
+select row_count()|
+select * from t3|
+
+drop procedure bug4905|
+drop table t3|
+
+#
+# BUG#6022: Stored procedure shutdown problem with self-calling function.
+#
+--disable_warnings
+drop function if exists bug6022|
+--enable_warnings
+
+create function bug6022(x int) returns int
+begin
+ if x < 0 then
+ return 0;
+ else
+ return bug6022(x-1);
+ end if;
+end|
+
+select bug6022(5)|
+drop function bug6022|
+
+#
+# BUG#6029: Stored procedure specific handlers should have priority
+#
+--disable_warnings
+drop procedure if exists bug6029|
+--enable_warnings
+
+create procedure bug6029()
+begin
+ declare exit handler for 1136 select '1136';
+ declare exit handler for sqlstate '23000' select 'sqlstate 23000';
+ declare continue handler for sqlexception select 'sqlexception';
+
+ insert into t3 values (1);
+ insert into t3 values (1,2);
+end|
+
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (1)|
+call bug6029()|
+delete from t3|
+call bug6029()|
+
+drop procedure bug6029|
+drop table t3|
+
+
+#
+# Some "real" examples
+#
+
+# fac
+
+--disable_warnings
+drop table if exists fac|
+--enable_warnings
+create table fac (n int unsigned not null primary key, f bigint unsigned)|
+
+create procedure ifac(n int unsigned)
+begin
+ declare i int unsigned default 1;
+
+ if n > 20 then
+ set n = 20; # bigint overflow otherwise
+ end if;
+ while i <= n do
+ begin
+ insert into test.fac values (i, fac(i));
+ set i = i + 1;
+ end;
+ end while;
+end|
+
+call ifac(20)|
+select * from fac|
+drop table fac|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like '%f%'|
+drop procedure ifac|
+drop function fac|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like '%f%'|
+
+
+# primes
+
+--disable_warnings
+drop table if exists primes|
+--enable_warnings
+
+create table primes (
+ i int unsigned not null primary key,
+ p bigint unsigned not null
+)|
+
+insert into primes values
+ ( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13),
+ ( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31),
+ (10, 37), (11, 41), (12, 43), (13, 47), (14, 53),
+ (15, 59), (16, 61), (17, 67), (18, 71), (19, 73),
+ (20, 79), (21, 83), (22, 89), (23, 97), (24, 101),
+ (25, 103), (26, 107), (27, 109), (28, 113), (29, 127),
+ (30, 131), (31, 137), (32, 139), (33, 149), (34, 151),
+ (35, 157), (36, 163), (37, 167), (38, 173), (39, 179),
+ (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)|
+
+create procedure opp(n bigint unsigned, out pp bool)
+begin
+ declare r double;
+ declare b, s bigint unsigned default 0;
+
+ set r = sqrt(n);
+
+ again:
+ loop
+ if s = 45 then
+ set b = b+200, s = 0;
+ else
+ begin
+ declare p bigint unsigned;
+
+ select t.p into p from test.primes t where t.i = s;
+ if b+p > r then
+ set pp = 1;
+ leave again;
+ end if;
+ if mod(n, b+p) = 0 then
+ set pp = 0;
+ leave again;
+ end if;
+ set s = s+1;
+ end;
+ end if;
+ end loop;
+end|
+
+create procedure ip(m int unsigned)
+begin
+ declare p bigint unsigned;
+ declare i int unsigned;
+
+ set i=45, p=201;
+
+ while i < m do
+ begin
+ declare pp bool default 0;
+
+ call opp(p, pp);
+ if pp then
+ insert into test.primes values (i, p);
+ set i = i+1;
+ end if;
+ set p = p+2;
+ end;
+ end while;
+end|
+show create procedure opp|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like '%p%'|
+
+# This isn't the fastest way in the world to compute prime numbers, so
+# don't be too ambitious. ;-)
+call ip(200)|
+# We don't want to select the entire table here, just pick a few
+# examples.
+# The expected result is:
+# i p
+# --- ----
+# 45 211
+# 100 557
+# 199 1229
+select * from primes where i=45 or i=100 or i=199|
+drop table primes|
+drop procedure opp|
+drop procedure ip|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like '%p%'|
+
+
+# Fibonacci, for recursion test. (Yet Another Numerical series :)
+
+--disable_warnings
+drop table if exists fib|
+--enable_warnings
+create table fib ( f bigint unsigned not null )|
+
+insert into fib values (1), (1)|
+
+# We deliberately do it the awkward way, fetching the last two
+# values from the table, in order to exercise various statements
+# and table accesses at each turn.
+create procedure fib(n int unsigned)
+begin
+ if n > 0 then
+ begin
+ declare x, y bigint unsigned;
+ declare c cursor for select f from fib order by f desc limit 2;
+
+ open c;
+ fetch c into y;
+ fetch c into x;
+ close c;
+ insert into fib values (x+y);
+ call fib(n-1);
+ end;
+ end if;
+end|
+
+call fib(20)|
+
+select * from fib order by f asc|
+drop table fib|
+drop procedure fib|
+
+
+#
+# Comment & suid
+#
+
+create procedure bar(x char(16), y int)
+ comment "111111111111" sql security invoker
+ insert into test.t1 values (x, y)|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'bar'|
+alter procedure bar comment "2222222222" sql security definer|
+alter procedure bar comment "3333333333"|
+alter procedure bar|
+show create procedure bar|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'bar'|
+drop procedure bar|
+delimiter ;|
+drop table t1;
+drop table t2;
+
+#
+# rexecution
+#
+create procedure p1 () select (select s1 from t1) from t1;
+create table t1 (s1 int);
+call p1();
+insert into t1 values (1);
+call p1();
+drop procedure p1;
+drop table t1;
+
+#
+# backticks
+#
+create function `foo` () returns int return 5;
+select `foo` ();
+drop function `foo`;
diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
index f841d36e837..fa5c6cb8a5b 100644
--- a/mysql-test/t/sql_mode.test
+++ b/mysql-test/t/sql_mode.test
@@ -80,3 +80,98 @@ create table t1 ( min_num dec(6,6) default .000001);
show create table t1;
drop table t1 ;
+
+#
+# test for
+# WL 1941 "NO_C_ESCAPES sql_mode"
+#
+# an sql_mode to disable \n, \r, \b, etc escapes in string literals. actually, to
+# disable special meaning of backslash completely. It's not in the SQL standard
+# and it causes some R/3 tests to fail.
+#
+
+SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='';
+show local variables like 'SQL_MODE';
+
+CREATE TABLE t1 (p int not null auto_increment, a varchar(20), primary key(p));
+INSERT t1 (a) VALUES
+('\\'),
+('\n'),
+('\b'),
+('\r'),
+('\t'),
+('\x'),
+('\a'),
+('\aa'),
+('\\a'),
+('\\aa'),
+('_'),
+('\_'),
+('\\_'),
+('\\\_'),
+('\\\\_'),
+('%'),
+('\%'),
+('\\%'),
+('\\\%'),
+('\\\\%')
+;
+
+SELECT p, hex(a) FROM t1;
+
+delete from t1 where a in ('\n','\r','\t', '\b');
+
+select
+ masks.p,
+ masks.a as mask,
+ examples.a as example
+from
+ t1 as masks
+ left join t1 as examples on examples.a LIKE masks.a
+order by masks.p, example;
+
+DROP TABLE t1;
+
+SET @@SQL_MODE='NO_BACKSLASH_ESCAPES';
+show local variables like 'SQL_MODE';
+
+CREATE TABLE t1 (p int not null auto_increment, a varchar(20), primary key(p));
+INSERT t1 (a) VALUES
+('\\'),
+('\n'),
+('\b'),
+('\r'),
+('\t'),
+('\x'),
+('\a'),
+('\aa'),
+('\\a'),
+('\\aa'),
+('_'),
+('\_'),
+('\\_'),
+('\\\_'),
+('\\\\_'),
+('%'),
+('\%'),
+('\\%'),
+('\\\%'),
+('\\\\%')
+;
+
+SELECT p, hex(a) FROM t1;
+
+delete from t1 where a in ('\n','\r','\t', '\b');
+
+select
+ masks.p,
+ masks.a as mask,
+ examples.a as example
+from
+ t1 as masks
+ left join t1 as examples on examples.a LIKE masks.a
+order by masks.p, example;
+
+DROP TABLE t1;
+
+SET @@SQL_MODE=@OLD_SQL_MODE;
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
new file mode 100644
index 00000000000..d9f4f4f2d0c
--- /dev/null
+++ b/mysql-test/t/strict.test
@@ -0,0 +1,639 @@
+# Testing of "strict" mode
+
+-- source include/have_innodb.inc
+
+set @@sql_mode='ansi,traditional';
+select @@sql_mode;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Test INSERT with DATE
+
+CREATE TABLE t1 (col1 date);
+INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29');
+--error 1292
+INSERT INTO t1 VALUES('2004-0-31');
+--error 1292
+INSERT INTO t1 VALUES('2004-01-02'),('2004-0-31');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-0');
+--error 1292
+INSERT INTO t1 VALUES('2004-09-31');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-32');
+--error 1292
+INSERT INTO t1 VALUES('2003-02-29');
+--error 1292
+INSERT INTO t1 VALUES('2004-13-15');
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00');
+# Standard says we should return SQLSTATE 22018
+--error 1292
+INSERT INTO t1 VALUES ('59');
+
+# Test the different related modes
+set @@sql_mode='STRICT_ALL_TABLES';
+INSERT INTO t1 VALUES('2004-01-03'),('2004-0-31');
+set @@sql_mode='STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
+--error 1292
+INSERT INTO t1 VALUES('2004-0-30');
+--error 1292
+INSERT INTO t1 VALUES('2004-01-04'),('2004-0-31'),('2004-01-05');
+INSERT INTO t1 VALUES('0000-00-00');
+INSERT IGNORE INTO t1 VALUES('2004-0-29');
+set @@sql_mode='STRICT_ALL_TABLES,NO_ZERO_DATE';
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00');
+INSERT IGNORE INTO t1 VALUES('0000-00-00');
+INSERT INTO t1 VALUES ('2004-0-30');
+--error 1292
+INSERT INTO t1 VALUES ('2004-2-30');
+set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES';
+INSERT INTO t1 VALUES ('2004-2-30');
+set @@sql_mode='ansi,traditional';
+INSERT IGNORE INTO t1 VALUES('2004-02-29'),('2004-13-15'),('0000-00-00');
+
+select * from t1;
+drop table t1;
+
+# Test difference in behaviour with InnoDB and MyISAM tables
+
+set @@sql_mode='strict_trans_tables';
+CREATE TABLE t1 (col1 date) engine=myisam;
+--error 1292
+INSERT INTO t1 VALUES('2004-13-31'),('2004-1-1');
+INSERT INTO t1 VALUES ('2004-1-2'), ('2004-13-31'),('2004-1-3');
+INSERT IGNORE INTO t1 VALUES('2004-13-31'),('2004-1-4');
+--error 1292
+INSERT INTO t1 VALUES ('2003-02-29');
+INSERT ignore INTO t1 VALUES('2003-02-30');
+set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES';
+INSERT ignore INTO t1 VALUES('2003-02-31');
+select * from t1;
+drop table t1;
+
+set @@sql_mode='strict_trans_tables';
+CREATE TABLE t1 (col1 date) engine=innodb;
+--error 1292
+INSERT INTO t1 VALUES('2004-13-31'),('2004-1-1');
+--error 1292
+INSERT INTO t1 VALUES ('2004-1-2'), ('2004-13-31'),('2004-1-3');
+INSERT IGNORE INTO t1 VALUES('2004-13-31'),('2004-1-4');
+--error 1292
+INSERT INTO t1 VALUES ('2003-02-29');
+INSERT ignore INTO t1 VALUES('2003-02-30');
+set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES';
+INSERT ignore INTO t1 VALUES('2003-02-31');
+select * from t1;
+drop table t1;
+set @@sql_mode='ansi,traditional';
+
+# Test INSERT with DATETIME
+
+CREATE TABLE t1 (col1 datetime);
+INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-0-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-0 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-09-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-32 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-13-15 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00 15:30:00');
+# Standard says we should return SQLSTATE 22018
+--error 1292
+INSERT INTO t1 VALUES ('59');
+select * from t1;
+drop table t1;
+
+# Test INSERT with TIMESTAMP
+
+CREATE TABLE t1 (col1 timestamp);
+INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00');
+# Standard says we should return ok, but we can't as this is out of range
+--error 1292
+INSERT INTO t1 VALUES('0000-10-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-0-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-0 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-09-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-32 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-13-15 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-02-29 25:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-02-29 15:65:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-02-29 15:31:61');
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00 00:00:00');
+INSERT IGNORE INTO t1 VALUES('0000-00-00 00:00:00');
+# Standard says we should return SQLSTATE 22018
+--error 1292
+INSERT INTO t1 VALUES ('59');
+
+set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES';
+--error 1292
+INSERT INTO t1 VALUES('2004-0-31 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-0 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-10-32 15:30:00');
+--error 1292
+INSERT INTO t1 VALUES('2004-02-30 15:30:04');
+INSERT INTO t1 VALUES('0000-00-00 00:00:00');
+set @@sql_mode='STRICT_ALL_TABLES,NO_ZERO_IN_DATE';
+INSERT INTO t1 VALUES('0000-00-00 00:00:00');
+set @@sql_mode='STRICT_ALL_TABLES,NO_ZERO_DATE';
+--error 1292
+INSERT INTO t1 VALUES('0000-00-00 00:00:00');
+set @@sql_mode='ansi,traditional';
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with TINYINT
+
+CREATE TABLE t1(col1 TINYINT, col2 TINYINT UNSIGNED);
+INSERT INTO t1 VALUES(-128,0),(0,0),(127,255),('-128','0'),('0','0'),('127','255'),(-128.0,0.0),(0.0,0.0),(127.0,255.0);
+# Test that we restored the mode checking properly after an ok query
+SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 2;
+-- error 1264
+INSERT INTO t1 (col1) VALUES(-129);
+-- error 1264
+INSERT INTO t1 (col1) VALUES(128);
+-- error 1264
+INSERT INTO t1 (col2) VALUES(-1);
+-- error 1264
+INSERT INTO t1 (col2) VALUES(256);
+-- error 1264
+INSERT INTO t1 (col1) VALUES('-129');
+-- error 1264
+INSERT INTO t1 (col1) VALUES('128');
+-- error 1264
+INSERT INTO t1 (col2) VALUES('-1');
+-- error 1264
+INSERT INTO t1 (col2) VALUES('256');
+-- error 1264
+INSERT INTO t1 (col1) VALUES(128.0);
+-- error 1264
+INSERT INTO t1 (col2) VALUES(-1.0);
+-- error 1264
+INSERT INTO t1 (col2) VALUES(256.0);
+SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 1;
+--error 1264
+UPDATE t1 SET col1 = col1 - 50 WHERE col1 < 0;
+--error 1264
+UPDATE t1 SET col2=col2 + 50 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col1=col1 / 0 WHERE col1 > 0;
+set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO';
+INSERT INTO t1 values (1/0,1/0);
+set @@sql_mode='ansi,traditional';
+SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 2;
+# Should return SQLSTATE 22018 invalid character value for cast
+--error 1366
+INSERT INTO t1 (col1) VALUES ('');
+--error 1366
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0,1/0);
+set @@sql_mode='ansi';
+INSERT INTO t1 values (1/0,1/0);
+set @@sql_mode='ansi,traditional';
+INSERT IGNORE INTO t1 VALUES('-129','-1'),('128','256');
+INSERT IGNORE INTO t1 VALUES(-129.0,-1.0),(128.0,256.0);
+UPDATE IGNORE t1 SET col2=1/NULL where col1=0;
+
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with SMALLINT
+
+CREATE TABLE t1(col1 SMALLINT, col2 SMALLINT UNSIGNED);
+INSERT INTO t1 VALUES(-32768,0),(0,0),(32767,65535),('-32768','0'),('32767','65535'),(-32768.0,0.0),(32767.0,65535.0);
+
+--error 1264
+INSERT INTO t1 (col1) VALUES(-32769);
+--error 1264
+INSERT INTO t1 (col1) VALUES(32768);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1);
+--error 1264
+INSERT INTO t1 (col2) VALUES(65536);
+--error 1264
+INSERT INTO t1 (col1) VALUES('-32769');
+--error 1264
+INSERT INTO t1 (col1) VALUES('32768');
+--error 1264
+INSERT INTO t1 (col2) VALUES('-1');
+--error 1264
+INSERT INTO t1 (col2) VALUES('65536');
+--error 1264
+INSERT INTO t1 (col1) VALUES(-32769.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(32768.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(65536.0);
+--error 1264
+UPDATE t1 SET col1 = col1 - 50 WHERE col1 < 0;
+--error 1264
+UPDATE t1 SET col2 = col2 + 50 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col1 = col1 / 0 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
+--error 1366
+INSERT INTO t1 (col1) VALUES ('');
+--error 1366
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0,1/0);
+INSERT IGNORE INTO t1 VALUES(-32769,-1),(32768,65536);
+INSERT IGNORE INTO t1 VALUES('-32769','-1'),('32768','65536');
+INSERT IGNORE INTO t1 VALUES(-32769,-1.0),(32768.0,65536.0);
+UPDATE IGNORE t1 SET col2=1/NULL where col1=0;
+
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with MEDIUMINT
+
+CREATE TABLE t1 (col1 MEDIUMINT, col2 MEDIUMINT UNSIGNED);
+INSERT INTO t1 VALUES(-8388608,0),(0,0),(8388607,16777215),('-8388608','0'),('8388607','16777215'),(-8388608.0,0.0),(8388607.0,16777215.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(-8388609);
+--error 1264
+INSERT INTO t1 (col1) VALUES(8388608);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1);
+--error 1264
+INSERT INTO t1 (col2) VALUES(16777216);
+--error 1264
+INSERT INTO t1 (col1) VALUES('-8388609');
+--error 1264
+INSERT INTO t1 (col1) VALUES('8388608');
+--error 1264
+INSERT INTO t1 (col2) VALUES('-1');
+--error 1264
+INSERT INTO t1 (col2) VALUES('16777216');
+--error 1264
+INSERT INTO t1 (col1) VALUES(-8388609.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(8388608.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(16777216.0);
+
+--error 1264
+UPDATE t1 SET col1 = col1 - 50 WHERE col1 < 0;
+--error 1264
+UPDATE t1 SET col2 = col2 + 50 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
+--error 1366
+INSERT INTO t1 (col1) VALUES ('');
+--error 1366
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0,1/0);
+INSERT IGNORE INTO t1 VALUES(-8388609,-1),(8388608,16777216);
+INSERT IGNORE INTO t1 VALUES('-8388609','-1'),('8388608','16777216');
+INSERT IGNORE INTO t1 VALUES(-8388609.0,-1.0),(8388608.0,16777216.0);
+UPDATE IGNORE t1 SET col2=1/NULL where col1=0;
+
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with INT
+
+CREATE TABLE t1 (col1 INT, col2 INT UNSIGNED);
+INSERT INTO t1 VALUES(-2147483648,0),(0,0),(2147483647,4294967295),('-2147483648','0'),('2147483647','4294967295'),(-2147483648.0,0.0),(2147483647.0,4294967295.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(-2147483649);
+--error 1264
+INSERT INTO t1 (col1) VALUES(2147643648);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1);
+--error 1264
+INSERT INTO t1 (col2) VALUES(4294967296);
+--error 1264
+INSERT INTO t1 (col1) VALUES('-2147483649');
+--error 1264
+INSERT INTO t1 (col1) VALUES('2147643648');
+--error 1264
+INSERT INTO t1 (col2) VALUES('-1');
+--error 1264
+INSERT INTO t1 (col2) VALUES('4294967296');
+--error 1264
+INSERT INTO t1 (col1) VALUES(-2147483649.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(2147643648.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(4294967296.0);
+
+--error 1264
+UPDATE t1 SET col1 = col1 - 50 WHERE col1 < 0;
+--error 1264
+UPDATE t1 SET col2 =col2 + 50 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
+--error 1264
+INSERT INTO t1 (col1) VALUES ('');
+--error 1264
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0,1/0);
+INSERT IGNORE INTO t1 values (-2147483649, -1),(2147643648,4294967296);
+INSERT IGNORE INTO t1 values ('-2147483649', '-1'),('2147643648','4294967296');
+INSERT IGNORE INTO t1 values (-2147483649.0, -1.0),(2147643648.0,4294967296.0);
+UPDATE IGNORE t1 SET col2=1/NULL where col1=0;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with BIGINT
+# Note that this doesn't behave 100 % to standard as we rotate
+# integers when it's too big/small (just like C)
+
+CREATE TABLE t1 (col1 BIGINT, col2 BIGINT UNSIGNED);
+INSERT INTO t1 VALUES(-9223372036854775808,0),(0,0),(9223372036854775807,18446744073709551615);
+INSERT INTO t1 VALUES('-9223372036854775808','0'),('9223372036854775807','18446744073709551615');
+INSERT INTO t1 VALUES(-9223372036854774000.0,0.0),(9223372036854775700.0,1844674407370954000.0);
+
+# The following should give an error, but doesn't until we fix the interface
+# for Field_longlong::store()
+
+INSERT INTO t1 (col1) VALUES(-9223372036854775809);
+INSERT INTO t1 (col1) VALUES(9223372036854775808);
+INSERT INTO t1 (col2) VALUES(-1);
+
+--error 1264
+INSERT INTO t1 (col2) VALUES(18446744073709551616);
+--error 1264
+INSERT INTO t1 (col1) VALUES('-9223372036854775809');
+--error 1264
+INSERT INTO t1 (col1) VALUES('9223372036854775808');
+--error 1264
+INSERT INTO t1 (col2) VALUES('-1');
+--error 1264
+INSERT INTO t1 (col2) VALUES('18446744073709551616');
+
+# Note that the following two double numbers are slighty bigger than max/min
+# bigint becasue of rounding errors when converting it to bigint
+--error 1264
+INSERT INTO t1 (col1) VALUES(-9223372036854785809.0);
+--error 1264
+INSERT INTO t1 (col1) VALUES(9223372036854785808.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(-1.0);
+--error 1264
+INSERT INTO t1 (col2) VALUES(18446744073709551616.0);
+
+# The following doesn't give an error as it's done in integer context
+# UPDATE t1 SET col1=col1 - 5000 WHERE col1 < 0;
+# UPDATE t1 SET col2 =col2 + 5000 WHERE col2 > 0;
+
+--error 1365
+UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
+--error 1264
+INSERT INTO t1 (col1) VALUES ('');
+--error 1264
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0,1/0);
+INSERT IGNORE INTO t1 VALUES(-9223372036854775809,-1),(9223372036854775808,18446744073709551616);
+INSERT IGNORE INTO t1 VALUES('-9223372036854775809','-1'),('9223372036854775808','18446744073709551616');
+INSERT IGNORE INTO t1 VALUES(-9223372036854785809.0,-1.0),(9223372036854785808.0,18446744073709551616.0);
+UPDATE IGNORE t1 SET col2=1/NULL where col1=0;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with NUMERIC
+
+CREATE TABLE t1 (col1 NUMERIC(4,2));
+INSERT INTO t1 VALUES (10.55),(10.5555),(0),(-10.55),(-10.5555),(11),(1e+01);
+-- Note that the +/-10.5555 is inserted as +/-10.55, not +/-10.56 !
+INSERT INTO t1 VALUES ('10.55'),('10.5555'),('-10.55'),('-10.5555'),('11'),('1e+01');
+
+-- The 2 following inserts should generate a warning, but doesn't yet
+-- because NUMERIC works like DECIMAL
+INSERT INTO t1 VALUES (101.55);
+INSERT INTO t1 VALUES (101);
+--error 1264
+INSERT INTO t1 VALUES (-101.55);
+--error 1264
+INSERT INTO t1 VALUES (1010.55);
+--error 1264
+INSERT INTO t1 VALUES (1010);
+-- The 2 following inserts should generate a warning, but doesn't yet
+-- because NUMERIC works like DECIMAL
+INSERT INTO t1 VALUES ('101.55');
+INSERT INTO t1 VALUES ('101');
+--error 1264
+INSERT INTO t1 VALUES ('-101.55');
+--error 1264
+INSERT INTO t1 VALUES ('-1010.55');
+--error 1264
+INSERT INTO t1 VALUES ('-100E+1');
+--error 1264
+INSERT INTO t1 VALUES ('-100E');
+--error 1264
+UPDATE t1 SET col1 =col1 * 50000 WHERE col1 =11;
+--error 1365
+UPDATE t1 SET col1 =col1 / 0 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col1= MOD(col1,0) WHERE col1 > 0;
+--error 1265
+INSERT INTO t1 (col1) VALUES ('');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 values (1/0);
+INSERT IGNORE INTO t1 VALUES(1000),(-1000);
+INSERT IGNORE INTO t1 VALUES('1000'),('-1000');
+INSERT IGNORE INTO t1 VALUES(1000.0),(-1000.0);
+UPDATE IGNORE t1 SET col1=1/NULL where col1=0;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with FLOAT
+
+CREATE TABLE t1 (col1 FLOAT, col2 FLOAT UNSIGNED);
+INSERT INTO t1 VALUES (-1.1E-38,0),(+3.4E+38,+3.4E+38);
+INSERT INTO t1 VALUES ('-1.1E-38',0),('+3.4E+38','+3.4E+38');
+# We don't give warnings for underflow
+INSERT INTO t1 (col1) VALUES (3E-46);
+--error 1264
+INSERT INTO t1 (col1) VALUES (+3.4E+39);
+--error 1264
+INSERT INTO t1 (col2) VALUES (-1.1E-3);
+--error 1264
+INSERT INTO t1 (col1) VALUES ('+3.4E+39');
+--error 1264
+INSERT INTO t1 (col2) VALUES ('-1.1E-3');
+--error 1264
+UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0;
+--error 1265
+INSERT INTO t1 (col1) VALUES ('');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 (col1) VALUES (1/0);
+INSERT IGNORE INTO t1 VALUES (+3.4E+39,-3.4E+39);
+INSERT IGNORE INTO t1 VALUES ('+3.4E+39','-3.4E+39');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Test INSERT with DOUBLE
+
+CREATE TABLE t1 (col1 DOUBLE PRECISION, col2 DOUBLE PRECISION UNSIGNED);
+INSERT INTO t1 VALUES (-2.2E-308,0),(+1.7E+308,+1.7E+308);
+INSERT INTO t1 VALUES ('-2.2E-308',0),('+1.7E+308','+1.7E+308');
+# We don't give warnings for underflow
+INSERT INTO t1 (col1) VALUES (-2.2E-330);
+--error 1367
+INSERT INTO t1 (col1) VALUES (+1.7E+309);
+--error 1264
+INSERT INTO t1 (col2) VALUES (-1.1E-3);
+--error 1264
+INSERT INTO t1 (col1) VALUES ('+1.8E+309');
+--error 1264
+INSERT INTO t1 (col2) VALUES ('-1.2E-3');
+--error 1264
+UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
+--error 1365
+UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
+--error 1365
+UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0;
+--error 1265
+INSERT INTO t1 (col1) VALUES ('');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('a59b');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('1a');
+INSERT IGNORE INTO t1 (col1) VALUES ('2a');
+INSERT IGNORE INTO t1 (col1) values (1/0);
+--error 1367
+INSERT IGNORE INTO t1 VALUES (+1.9E+309,-1.9E+309);
+INSERT IGNORE INTO t1 VALUES ('+2.0E+309','-2.0E+309');
+# stupid...
+--replace_result -0 0
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Testing INSERT with CHAR/VARCHAR
+
+CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(5));
+INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('hellobob');
+--error 1265
+INSERT INTO t1 (col2) VALUES ('hellobob');
+--error 1265
+UPDATE t1 SET col1 ='hellobob' WHERE col1 ='he';
+--error 1265
+UPDATE t1 SET col2 ='hellobob' WHERE col2 ='he';
+INSERT IGNORE INTO t1 VALUES ('hellobob', 'hellobob');
+UPDATE IGNORE t1 SET col2 ='hellotrudy' WHERE col2 ='he';
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Testing INSERT with ENUM
+
+CREATE TABLE t1 (col1 enum('red','blue','green'));
+INSERT INTO t1 VALUES ('red'),('blue'),('green');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('yellow');
+--error 1265
+INSERT INTO t1 (col1) VALUES ('redd');
+--error 1265
+INSERT INTO t1 VALUES ('');
+--error 1265
+UPDATE t1 SET col1 ='yellow' WHERE col1 ='green';
+INSERT IGNORE INTO t1 VALUES ('yellow');
+UPDATE IGNORE t1 SET col1 ='yellow' WHERE col1 ='blue';
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Testing of insert of NULL in not NULL column
+
+CREATE TABLE t1 (col1 INT NOT NULL, col2 CHAR(5) NOT NULL, col3 DATE NOT NULL);
+INSERT INTO t1 VALUES (100, 'hello', '2004-08-20');
+INSERT INTO t1 (col1,col2,col3) VALUES (101, 'hell2', '2004-08-21');
+--error 1048
+INSERT INTO t1 (col1,col2,col3) VALUES (NULL, '', '2004-01-01');
+--error 1048
+INSERT INTO t1 (col1,col2,col3) VALUES (102, NULL, '2004-01-01');
+--error 1048
+INSERT INTO t1 VALUES (103,'',NULL);
+--error 1263
+UPDATE t1 SET col1=NULL WHERE col1 =100;
+--error 1263
+UPDATE t1 SET col2 =NULL WHERE col2 ='hello';
+--error 1263
+UPDATE t1 SET col2 =NULL where col3 IS NOT NULL;
+INSERT IGNORE INTO t1 values (NULL,NULL,NULL);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# Testing of default values
+
+CREATE TABLE t1 (col1 INT NOT NULL default 99, col2 CHAR(6) NOT NULL);
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1, 'hello');
+INSERT INTO t1 (col2) VALUES ('hello2');
+--error 1048
+INSERT INTO t1 (col2) VALUES (NULL);
+--error 1364
+INSERT INTO t1 (col1) VALUES (2);
+--error 1364
+INSERT INTO t1 VALUES(default(col1),default(col2));
+--error 1364
+INSERT INTO t1 (col1) SELECT 1;
+--error 1263
+INSERT INTO t1 SELECT 1,NULL;
+INSERT IGNORE INTO t1 values (NULL,NULL);
+INSERT IGNORE INTO t1 (col1) values (3);
+INSERT IGNORE INTO t1 () values ();
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index e0f6fcbf515..16556c4864c 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -352,7 +352,9 @@ INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
+# After this, only data based on old t1 records should have been added.
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
-- error 1054
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
@@ -507,6 +509,9 @@ select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
drop table t1;
+#
+# DO & SET
+#
create table t1 (a int);
insert into t1 values (1);
do @a:=(SELECT a from t1);
diff --git a/mysql-test/t/sum_distinct.test b/mysql-test/t/sum_distinct.test
new file mode 100644
index 00000000000..efbb21a7b85
--- /dev/null
+++ b/mysql-test/t/sum_distinct.test
@@ -0,0 +1,188 @@
+#
+# Various tests for SUM(DISTINCT ...)
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ gender CHAR(1),
+ name VARCHAR(20)
+);
+
+# According to ANSI SQL, SUM(DISTINCT ...) should return NULL for empty
+# record set
+
+SELECT SUM(DISTINCT LENGTH(name)) s1 FROM t1;
+
+# According to ANSI SQL, SUM(DISTINCT ...) should return NULL for records sets
+# entirely consisting of NULLs
+
+INSERT INTO t1 (gender, name) VALUES (NULL, NULL);
+INSERT INTO t1 (gender, name) VALUES (NULL, NULL);
+INSERT INTO t1 (gender, name) VALUES (NULL, NULL);
+
+SELECT SUM(DISTINCT LENGTH(name)) s1 FROM t1;
+
+
+# Filling table with t1
+
+INSERT INTO t1 (gender, name) VALUES ('F', 'Helen'), ('F', 'Anastasia'),
+('F', 'Katherine'), ('F', 'Margo'), ('F', 'Magdalene'), ('F', 'Mary');
+
+CREATE TABLE t2 SELECT name FROM t1;
+
+SELECT (SELECT SUM(DISTINCT LENGTH(name)) FROM t1) FROM t2;
+
+DROP TABLE t2;
+
+INSERT INTO t1 (gender, name) VALUES ('F', 'Eva'), ('F', 'Sofia'),
+('F', 'Sara'), ('F', 'Golda'), ('F', 'Toba'), ('F', 'Victory'),
+('F', 'Faina'), ('F', 'Miriam'), ('F', 'Beki'), ('F', 'America'),
+('F', 'Susan'), ('F', 'Glory'), ('F', 'Priscilla'), ('F', 'Rosmary'),
+('F', 'Rose'), ('F', 'Margareth'), ('F', 'Elizabeth'), ('F', 'Meredith'),
+('F', 'Julie'), ('F', 'Xenia'), ('F', 'Zena'), ('F', 'Olga'),
+('F', 'Brunhilda'), ('F', 'Nataly'), ('F', 'Lara'), ('F', 'Svetlana'),
+('F', 'Grethem'), ('F', 'Irene');
+
+SELECT
+ SUM(DISTINCT LENGTH(name)) s1,
+ SUM(DISTINCT SUBSTRING(NAME, 1, 3)) s2,
+ SUM(DISTINCT LENGTH(SUBSTRING(name, 1, 4))) s3
+FROM t1;
+
+SELECT
+ SUM(DISTINCT LENGTH(g1.name)) s1,
+ SUM(DISTINCT SUBSTRING(g2.name, 1, 3)) s2,
+ SUM(DISTINCT LENGTH(SUBSTRING(g3.name, 1, 4))) s3
+FROM t1 g1, t1 g2, t1 g3;
+
+SELECT
+ SUM(DISTINCT LENGTH(g1.name)) s1,
+ SUM(DISTINCT SUBSTRING(g2.name, 1, 3)) s2,
+ SUM(DISTINCT LENGTH(SUBSTRING(g3.name, 1, 4))) s3
+FROM t1 g1, t1 g2, t1 g3 GROUP BY LENGTH(SUBSTRING(g3.name, 5, 10));
+
+# here we explicitly request summing through temporary table (so
+# Item_sum_sum_distinct::copy_or_same() is called)
+
+SELECT SQL_BUFFER_RESULT
+ SUM(DISTINCT LENGTH(name)) s1,
+ SUM(DISTINCT SUBSTRING(NAME, 1, 3)) s2,
+ SUM(DISTINCT LENGTH(SUBSTRING(name, 1, 4))) s3
+FROM t1;
+
+SELECT SQL_BUFFER_RESULT
+ SUM(DISTINCT LENGTH(g1.name)) s1,
+ SUM(DISTINCT SUBSTRING(g2.name, 1, 3)) s2,
+ SUM(DISTINCT LENGTH(SUBSTRING(g3.name, 1, 4))) s3
+FROM t1 g1, t1 g2, t1 g3 GROUP BY LENGTH(SUBSTRING(g3.name, 5, 10));
+
+# this test demonstrates that strings are automatically converted to numbers
+# before summing
+
+SET @l=1;
+UPDATE t1 SET name=CONCAT(name, @l:=@l+1);
+
+SELECT SUM(DISTINCT RIGHT(name, 1)) FROM t1;
+
+# this is a test case for ordinary t1
+
+SELECT SUM(DISTINCT id) FROM t1;
+SELECT SUM(DISTINCT id % 11) FROM t1;
+
+DROP TABLE t1;
+
+#
+# Test the case when distinct values doesn't fit in memory and
+# filesort is used (see uniques.cc:merge_walk)
+#
+
+CREATE TABLE t1 (id INTEGER);
+CREATE TABLE t2 (id INTEGER);
+
+INSERT INTO t1 (id) VALUES (1), (1), (1),(1);
+INSERT INTO t2 (id) SELECT id FROM t1;
+INSERT INTO t1 (id) SELECT id FROM t2; /* 8 */
+INSERT INTO t1 (id) SELECT id FROM t2; /* 12 */
+INSERT INTO t1 (id) SELECT id FROM t2; /* 16 */
+INSERT INTO t1 (id) SELECT id FROM t2; /* 20 */
+INSERT INTO t1 (id) SELECT id FROM t2; /* 24 */
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+1 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+2 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+4 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+8 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+16 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+32 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+64 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+128 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+256 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+512 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+1024 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+2048 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+4096 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+INSERT INTO t2 (id) SELECT id+8192 FROM t1;
+INSERT INTO t1 SELECT id FROM t2;
+DELETE FROM t2;
+#INSERT INTO t2 (id) SELECT id+16384 FROM t1;
+#INSERT INTO t1 SELECT id FROM t2;
+#DELETE FROM t2;
+#INSERT INTO t2 (id) SELECT id+32768 FROM t1;
+#INSERT INTO t1 SELECT id FROM t2;
+#DELETE FROM t2;
+#INSERT INTO t2 (id) SELECT id+65536 FROM t1;
+#INSERT INTO t1 SELECT id FROM t2;
+#DELETE FROM t2;
+INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
+
+# SELECT '++++++++++++++++++++++++++++++++++++++++++++++++++';
+
+SELECT SUM(DISTINCT id) sm FROM t1;
+SELECT SUM(DISTINCT id) sm FROM t2;
+SELECT SUM(DISTINCT id) sm FROM t1 group by id % 13;
+
+# this limit for max_heap_table_size is set to force testing the case, when
+# all distinct sum values can not fit in memory and must be stored in a
+# temporary table
+
+SET max_heap_table_size=16384;
+
+# to check that max_heap_table_size was actually set (hard limit for minimum
+# max_heap_table_size is set in mysqld.cc):
+
+SHOW variables LIKE 'max_heap_table_size';
+
+SELECT SUM(DISTINCT id) sm FROM t1;
+SELECT SUM(DISTINCT id) sm FROM t2;
+SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13;
+
+DROP TABLE t1;
+DROP TABLE t2;
diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test
index 6c44535e3b7..1122803fd8f 100644
--- a/mysql-test/t/system_mysql_db_fix.test
+++ b/mysql-test/t/system_mysql_db_fix.test
@@ -68,7 +68,7 @@ INSERT INTO user VALUES ('localhost','', '','N','N','N','N','N','N','N','N','
-- disable_query_log
-DROP TABLE db, host, user, func, tables_priv, columns_priv, help_category, help_keyword, help_relation, help_topic, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type;
+DROP TABLE db, host, user, func, tables_priv, columns_priv, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type;
-- enable_query_log
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
new file mode 100644
index 00000000000..f842d561dc1
--- /dev/null
+++ b/mysql-test/t/trigger.test
@@ -0,0 +1,209 @@
+#
+# Basic triggers test
+#
+
+--disable_warnings
+drop table if exists t1, t2;
+drop view if exists v1;
+--enable_warnings
+
+create table t1 (i int);
+
+# let us test some very simple trigger
+create trigger trg before insert on t1 for each row set @a:=1;
+set @a:=0;
+select @a;
+insert into t1 values (1);
+select @a;
+drop trigger t1.trg;
+
+# let us test simple trigger reading some values
+create trigger trg before insert on t1 for each row set @a:=new.i;
+insert into t1 values (123);
+select @a;
+drop trigger t1.trg;
+
+drop table t1;
+
+# Let us test before insert trigger
+# Such triggers can be used for setting complex default values
+create table t1 (i int not null, j int);
+delimiter |;
+create trigger trg before insert on t1 for each row
+begin
+ if isnull(new.j) then
+ set new.j:= new.i * 10;
+ end if;
+end|
+insert into t1 (i) values (1)|
+insert into t1 (i,j) values (2, 3)|
+select * from t1|
+drop trigger t1.trg|
+drop table t1|
+delimiter ;|
+
+# After insert trigger
+# Useful for aggregating data
+create table t1 (i int not null primary key);
+create trigger trg after insert on t1 for each row
+ set @a:= if(@a,concat(@a, ":", new.i), new.i);
+set @a:="";
+insert into t1 values (2),(3),(4),(5);
+select @a;
+drop trigger t1.trg;
+drop table t1;
+
+# Before update trigger
+# (In future we will achieve this via proper error handling in triggers)
+create table t1 (aid int not null primary key, balance int not null default 0);
+insert into t1 values (1, 1000), (2,3000);
+delimiter |;
+create trigger trg before update on t1 for each row
+begin
+ declare loc_err varchar(255);
+ if abs(new.balance - old.balance) > 1000 then
+ set new.balance:= old.balance;
+ set loc_err := concat("Too big change for aid = ", new.aid);
+ set @update_failed:= if(@update_failed, concat(@a, ":", loc_err), loc_err);
+ end if;
+end|
+set @update_failed:=""|
+update t1 set balance=1500|
+select @update_failed;
+select * from t1|
+drop trigger t1.trg|
+drop table t1|
+delimiter ;|
+
+# After update trigger
+create table t1 (i int);
+insert into t1 values (1),(2),(3),(4);
+create trigger trg after update on t1 for each row
+ set @total_change:=@total_change + new.i - old.i;
+set @total_change:=0;
+update t1 set i=3;
+select @total_change;
+drop trigger t1.trg;
+drop table t1;
+
+# Before delete trigger
+# This can be used for aggregation too :)
+create table t1 (i int);
+insert into t1 values (1),(2),(3),(4);
+create trigger trg before delete on t1 for each row
+ set @del_sum:= @del_sum + old.i;
+set @del_sum:= 0;
+delete from t1 where i <= 3;
+select @del_sum;
+drop trigger t1.trg;
+drop table t1;
+
+# After delete trigger.
+# Just run out of imagination.
+create table t1 (i int);
+insert into t1 values (1),(2),(3),(4);
+create trigger trg after delete on t1 for each row set @del:= 1;
+set @del:= 0;
+delete from t1 where i <> 0;
+select @del;
+drop trigger t1.trg;
+drop table t1;
+
+# Several triggers on one table
+create table t1 (i int, j int);
+
+delimiter |;
+create trigger trg1 before insert on t1 for each row
+begin
+ if new.j > 10 then
+ set new.j := 10;
+ end if;
+end|
+create trigger trg2 before update on t1 for each row
+begin
+ if old.i % 2 = 0 then
+ set new.j := -1;
+ end if;
+end|
+create trigger trg3 after update on t1 for each row
+begin
+ if new.j = -1 then
+ set @fired:= "Yes";
+ end if;
+end|
+delimiter ;|
+set @fired:="";
+insert into t1 values (1,2),(2,3),(3,14);
+select @fired;
+select * from t1;
+update t1 set j= 20;
+select @fired;
+select * from t1;
+
+drop trigger t1.trg1;
+drop trigger t1.trg2;
+drop trigger t1.trg3;
+drop table t1;
+
+
+#
+# Test of wrong column specifiers in triggers
+#
+create table t1 (i int);
+
+--error 1363
+create trigger trg before insert on t1 for each row set @a:= old.i;
+--error 1363
+create trigger trg before delete on t1 for each row set @a:= new.i;
+--error 1362
+create trigger trg before update on t1 for each row set old.i:=1;
+--error 1363
+create trigger trg before delete on t1 for each row set new.i:=1;
+--error 1362
+create trigger trg after update on t1 for each row set new.i:=1;
+# TODO: We should also test wrong field names here, we don't do it now
+# because proper error handling is not in place yet.
+
+
+#
+# Let us test various trigger creation errors
+#
+#
+--error 1146
+create trigger trg before insert on t2 for each row set @a:=1;
+
+create trigger trg before insert on t1 for each row set @a:=1;
+--error 1359
+create trigger trg after insert on t1 for each row set @a:=1;
+--error 1359
+create trigger trg2 before insert on t1 for each row set @a:=1;
+drop trigger t1.trg;
+
+--error 1360
+drop trigger t1.trg;
+
+create view v1 as select * from t1;
+--error 1361
+create trigger trg before insert on v1 for each row set @a:=1;
+drop view v1;
+
+drop table t1;
+
+create temporary table t1 (i int);
+--error 1361
+create trigger trg before insert on t1 for each row set @a:=1;
+drop table t1;
+
+
+
+#
+# Tests for various trigger-related bugs
+#
+
+# Test for bug #5887 "Triggers with string literals cause errors".
+# New .FRM parser was not handling escaped strings properly.
+create table t1 (x1col char);
+create trigger tx1 before insert on t1 for each row set new.x1col = 'x';
+insert into t1 values ('y');
+drop trigger t1.tx1;
+drop table t1;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 601724e68c8..48ca9e0ba32 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -20,6 +20,7 @@ insert into t2 select distinct i from t1;
select * from t2;
select distinct t2.i,@vv1:=if(sv1.i,1,0),@vv2:=if(sv2.i,1,0),@vv3:=if(sv3.i,1,0), @vv1+@vv2+@vv3 from t2 left join t1 as sv1 on sv1.i=t2.i and sv1.v=1 left join t1 as sv2 on sv2.i=t2.i and sv2.v=2 left join t1 as sv3 on sv3.i=t2.i and sv3.v=3;
explain select * from t1 where i=@vv1;
+select @vv1,i,v from t1 where i=@vv1;
explain select * from t1 where @vv1:=@vv1+1 and i=@vv1;
explain select @vv1:=i from t1 where i=@vv1;
explain select * from t1 where i=@vv1;
@@ -111,7 +112,7 @@ insert into t1 values (@var1);
create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
insert into t2 values (@v);
-show binlog events from 79;
+show binlog events from 95;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index fd6ab4d6405..67a05768595 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -5,8 +5,20 @@
drop table if exists t1,t2;
--enable_warnings
-set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
-select @test,@`select`,@TEST,@not_used;
+# case insensitivity tests (new in 5.0)
+set @`test`=1;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @TEST=2;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @"tEST"=3;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+set @`TeST`=4;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+select @`teST`:=5;
+select @test, @`test`, @TEST, @`TEST`, @"teSt";
+
+set @select=2,@t5=1.23456;
+select @`select`,@not_used;
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
select @test_int,@test_double,@test_string,@test_string2,@select;
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
new file mode 100644
index 00000000000..17077d1d086
--- /dev/null
+++ b/mysql-test/t/view.test
@@ -0,0 +1,1560 @@
+--disable_warnings
+drop table if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop database if exists mysqltest;
+--enable_warnings
+use test;
+
+#
+# some basic test of views and its functionality
+#
+
+# create view on unexistence table
+-- error 1146
+create view v1 (c,d) as select a,b from t1;
+
+create temporary table t1 (a int, b int);
+#view on temporary table
+-- error 1352
+create view v1 (c) as select b+1 from t1;
+drop table t1;
+
+create table t1 (a int, b int);
+insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
+
+#view with variable
+-- error 1351
+create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
+
+# simple view
+create view v1 (c) as select b+1 from t1;
+select c from v1;
+
+#tamporary table should not shade (hide) table of view
+create temporary table t1 (a int, b int);
+# this is empty
+select * from t1;
+# but this based on normal t1
+select c from v1;
+show create table v1;
+show create view v1;
+-- error 1347
+show create view t1;
+drop table t1;
+
+# try to use fields from underlaid table
+-- error 1054
+select a from v1;
+-- error 1054
+select v1.a from v1;
+-- error 1054
+select b from v1;
+-- error 1054
+select v1.b from v1;
+
+# view with different algorithms (explain out put are differ)
+explain extended select c from v1;
+create algorithm=temptable view v2 (c) as select b+1 from t1;
+show create view v2;
+select c from v2;
+explain extended select c from v2;
+
+# try to use underlaid table fields in VIEW creation process
+-- error 1054
+create view v3 (c) as select a+1 from v1;
+-- error 1054
+create view v3 (c) as select b+1 from v1;
+
+
+# VIEW on VIEW test with mixing different algorithms on different order
+create view v3 (c) as select c+1 from v1;
+select c from v3;
+explain extended select c from v3;
+create algorithm=temptable view v4 (c) as select c+1 from v2;
+select c from v4;
+explain extended select c from v4;
+create view v5 (c) as select c+1 from v2;
+select c from v5;
+explain extended select c from v5;
+create algorithm=temptable view v6 (c) as select c+1 from v1;
+select c from v6;
+explain extended select c from v6;
+
+# show table/table status test
+show tables;
+show full tables;
+--replace_column 12 # 13 #
+show table status;
+
+drop view v1,v2,v3,v4,v5,v6;
+
+#
+# alter/create view test
+#
+
+# view with subqueries of different types
+create view v1 (c,d,e,f) as select a,b,
+a in (select a+2 from t1), a = all (select a from t1) from t1;
+create view v2 as select c, d from v1;
+select * from v1;
+select * from v2;
+
+# try to create VIEW with name of existing VIEW
+-- error 1050
+create view v1 (c,d,e,f) as select a,b, a in (select a+2 from t1), a = all (select a from t1) from t1;
+
+# 'or replace' should work in this case
+create or replace view v1 (c,d,e,f) as select a,b, a in (select a+2 from t1), a = all (select a from t1) from t1;
+
+# try to ALTER unexisting VIEW
+drop view v2;
+-- error 1146
+alter view v2 as select c, d from v1;
+
+# 'or replace' on unexisting view
+create or replace view v2 as select c, d from v1;
+
+# alter view on existing view
+alter view v1 (c,d) as select a,max(b) from t1 group by a;
+
+# check that created view works
+select * from v1;
+select * from v2;
+
+# simple test of grants
+grant create view on test.* to test@localhost;
+show grants for test@localhost;
+revoke create view on test.* from test@localhost;
+show grants for test@localhost;
+
+#try to drop unexisten VIEW
+-- error 1051
+drop view v100;
+
+#try to drop table with DROP VIEW
+-- error 1347
+drop view t1;
+
+#try to drop VIEW with DROP TABLE
+-- error 1051
+drop table v1;
+
+#try to drop table with DROP VIEW
+
+drop view v1,v2;
+drop table t1;
+
+#
+# outer left join with merged views
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+
+create view v1 (a) as select a+1 from t1;
+create view v2 (a) as select a-1 from t1;
+
+select * from t1 natural left join v1;
+select * from v2 natural left join t1;
+select * from v2 natural left join v1;
+
+drop view v1, v2;
+drop table t1;
+
+
+#
+# grant create view test
+#
+connect (root,localhost,root,,test);
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int);
+create table mysqltest.t2 (a int, b int);
+
+grant select on mysqltest.t1 to mysqltest_1@localhost;
+grant create view,select on test.* to mysqltest_1@localhost;
+
+connect (user1,localhost,mysqltest_1,,test);
+connection user1;
+
+create view v1 as select * from mysqltest.t1;
+# try to modify view without DELETE privilege on it
+-- error 1142
+alter view v1 as select * from mysqltest.t1;
+-- error 1142
+create or replace view v1 as select * from mysqltest.t1;
+# no CRETE VIEW privilege
+-- error 1142
+create view mysqltest.v2 as select * from mysqltest.t1;
+# no SELECT privilege
+-- error 1142
+create view v2 as select * from mysqltest.t2;
+
+connection root;
+revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
+revoke all privileges on test.* from mysqltest_1@localhost;
+
+drop database mysqltest;
+drop view test.v1;
+
+#
+# grants per columns
+#
+# MERGE algorithm
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int);
+create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1;
+grant select (c) on mysqltest.v1 to mysqltest_1@localhost;
+
+connection user1;
+select c from mysqltest.v1;
+# there are not privilege ob column 'd'
+-- error 1143
+select d from mysqltest.v1;
+
+connection root;
+revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+drop database mysqltest;
+
+# TEMPORARY TABLE algorithm
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int);
+create algorithm=temptable view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1;
+grant select (c) on mysqltest.v1 to mysqltest_1@localhost;
+
+connection user1;
+select c from mysqltest.v1;
+# there are not privilege ob column 'd'
+-- error 1143
+select d from mysqltest.v1;
+
+connection root;
+revoke all privileges on mysqltest.v1 from mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+drop database mysqltest;
+
+#
+# EXPLAIN rights
+#
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+#prepare views and tables
+create table mysqltest.t1 (a int, b int);
+create table mysqltest.t2 (a int, b int);
+create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1;
+create algorithm=temptable view mysqltest.v2 (c,d) as select a+1,b+1 from mysqltest.t1;
+create view mysqltest.v3 (c,d) as select a+1,b+1 from mysqltest.t2;
+create algorithm=temptable view mysqltest.v4 (c,d) as select a+1,b+1 from mysqltest.t2;
+grant select on mysqltest.v1 to mysqltest_1@localhost;
+grant select on mysqltest.v2 to mysqltest_1@localhost;
+grant select on mysqltest.v3 to mysqltest_1@localhost;
+grant select on mysqltest.v4 to mysqltest_1@localhost;
+
+connection user1;
+# all selects works
+select c from mysqltest.v1;
+select c from mysqltest.v2;
+select c from mysqltest.v3;
+select c from mysqltest.v4;
+# test of show coluns
+show columns from mysqltest.v1;
+show columns from mysqltest.v2;
+# but explain/show do not
+-- error 1345
+explain select c from mysqltest.v1;
+-- error 1142
+show create view mysqltest.v1;
+-- error 1345
+explain select c from mysqltest.v2;
+-- error 1142
+show create view mysqltest.v2;
+-- error 1345
+explain select c from mysqltest.v3;
+-- error 1142
+show create view mysqltest.v3;
+-- error 1345
+explain select c from mysqltest.v4;
+-- error 1142
+show create view mysqltest.v4;
+
+# allow to see one of underlaing table
+connection root;
+grant select on mysqltest.t1 to mysqltest_1@localhost;
+connection user1;
+# EXPLAIN of view on above table works
+explain select c from mysqltest.v1;
+-- error 1142
+show create view mysqltest.v1;
+explain select c from mysqltest.v2;
+-- error 1142
+show create view mysqltest.v2;
+# but other EXPLAINs do not
+-- error 1345
+explain select c from mysqltest.v3;
+-- error 1142
+show create view mysqltest.v3;
+-- error 1345
+explain select c from mysqltest.v4;
+-- error 1142
+show create view mysqltest.v4;
+
+# allow to see any view in mysqltest database
+connection root;
+grant show view on mysqltest.* to mysqltest_1@localhost;
+connection user1;
+explain select c from mysqltest.v1;
+show create view mysqltest.v1;
+explain select c from mysqltest.v2;
+show create view mysqltest.v2;
+explain select c from mysqltest.v3;
+show create view mysqltest.v3;
+explain select c from mysqltest.v4;
+show create view mysqltest.v4;
+
+connection root;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+drop database mysqltest;
+
+#
+# QUERY CHECHE options for VIEWs
+#
+set GLOBAL query_cache_size=1355776;
+flush status;
+create table t1 (a int, b int);
+
+# queries with following views should not be in query cache
+create view v1 (c,d) as select sql_no_cache a,b from t1;
+create view v2 (c,d) as select a+rand(),b from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from v1;
+select * from v2;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from v1;
+select * from v2;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+
+drop view v1,v2;
+
+# SQL_CACHE option
+set query_cache_type=demand;
+flush status;
+# query with view will be cached, but direct acess to table will not
+create view v1 (c,d) as select sql_cache a,b from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from v1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from v1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+drop view v1;
+set query_cache_type=default;
+
+drop table t1;
+set GLOBAL query_cache_size=default;
+
+
+#
+# DISTINCT option for VIEW
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3), (1), (2), (3);
+create view v1 as select distinct a from t1;
+select * from v1;
+explain select * from v1;
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# syntax compatibility
+#
+create table t1 (a int);
+-- error 1368
+create view v1 as select distinct a from t1 WITH CHECK OPTION;
+create view v1 as select a from t1 WITH CHECK OPTION;
+create view v2 as select a from t1 WITH CASCADED CHECK OPTION;
+create view v3 as select a from t1 WITH LOCAL CHECK OPTION;
+drop view v3 RESTRICT;
+drop view v2 CASCADE;
+drop view v1;
+drop table t1;
+
+#
+# aliases
+#
+create table t1 (a int, b int);
+insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
+create view v1 (c) as select b+1 from t1;
+select test.c from v1 test;
+create algorithm=temptable view v2 (c) as select b+1 from t1;
+select test.c from v2 test;
+select test1.* from v1 test1, v2 test2 where test1.c=test2.c;
+select test2.* from v1 test1, v2 test2 where test1.c=test2.c;
+drop table t1;
+drop view v1,v2;
+
+#
+# LIMIT clasuse test
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3), (4);
+create view v1 as select a+1 from t1 order by 1 desc limit 2;
+select * from v1;
+explain select * from v1;
+drop view v1;
+drop table t1;
+
+#
+# CREATE ... SELECT view test
+#
+create table t1 (a int);
+insert into t1 values (1), (2), (3), (4);
+create view v1 as select a+1 from t1;
+create table t2 select * from v1;
+show columns from t2;
+select * from t2;
+drop view v1;
+drop table t1,t2;
+
+#
+# simple view + simple update
+#
+create table t1 (a int, b int, primary key(a));
+insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
+create view v1 (a,c) as select a, b+1 from t1;
+create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+# try to update expression
+-- error 1348
+update v1 set c=a+c;
+# try to update VIEW with forced TEMPORARY TABLE algorithm
+-- error 1288
+update v2 set a=a+c;
+# updatable field of updateable view
+update v1 set a=a+c;
+select * from v1;
+select * from t1;
+drop table t1;
+drop view v1,v2;
+
+#
+# simple view + simple multi-update
+#
+create table t1 (a int, b int, primary key(a));
+insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
+create table t2 (x int);
+insert into t2 values (10), (20);
+create view v1 (a,c) as select a, b+1 from t1;
+create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+# try to update expression
+-- error 1348
+update t2,v1 set v1.c=v1.a+v1.c where t2.x=v1.a;
+# try to update VIEW with forced TEMPORARY TABLE algorithm
+-- error 1288
+update t2,v2 set v2.a=v2.v2.a+c where t2.x=v2.a;
+# updatable field of updateable view
+update t2,v1 set v1.a=v1.a+v1.c where t2.x=v1.a;
+select * from v1;
+select * from t1;
+drop table t1,t2;
+drop view v1,v2;
+
+#
+# UPDATE privileges on VIEW columns and whole VIEW
+#
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int, primary key(a));
+insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
+create table mysqltest.t2 (x int);
+insert into mysqltest.t2 values (3), (4), (5), (6);
+create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
+create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
+create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1;
+
+grant update (a) on mysqltest.v2 to mysqltest_1@localhost;
+grant update on mysqltest.v1 to mysqltest_1@localhost;
+grant select on mysqltest.* to mysqltest_1@localhost;
+
+connection user1;
+use mysqltest;
+# update with rights on VIEW column
+update t2,v1 set v1.a=v1.a+v1.c where t2.x=v1.c;
+select * from t1;
+update v1 set a=a+c;
+select * from t1;
+# update with rights on whole VIEW
+update t2,v2 set v2.a=v2.a+v2.c where t2.x=v2.c;
+select * from t1;
+update v2 set a=a+c;
+select * from t1;
+# no rights on column
+-- error 1143
+update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
+-- error 1143
+update v2 set c=a+c;
+# no rights for view
+-- error 1143
+update t2,v3 set v3.a=v3.a+v3.c where t2.x=v3.c;
+-- error 1142
+update v3 set a=a+c;
+
+use test;
+connection root;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
+drop database mysqltest;
+
+#
+# MEREGE VIEW with WHERE clause
+#
+create table t1 (a int, b int, primary key(b));
+insert into t1 values (1,20), (2,30), (3,40), (4,50), (5,100);
+create view v1 (c) as select b from t1 where a<3;
+# simple select and explaint to be sure that it is MERGE
+select * from v1;
+explain extended select * from v1;
+# update test
+update v1 set c=c+1;
+select * from t1;
+# join of such VIEWs test
+create view v2 (c) as select b from t1 where a>=3;
+select * from v1, v2;
+drop view v1, v2;
+drop table t1;
+
+#
+# simple view + simple delete
+#
+create table t1 (a int, b int, primary key(a));
+insert into t1 values (1,2), (2,3), (3,4), (4,5), (5,10);
+create view v1 (a,c) as select a, b+1 from t1;
+create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+# try to update VIEW with forced TEMPORARY TABLE algorithm
+-- error 1288
+delete from v2 where c < 4;
+# updatable field of updateable view
+delete from v1 where c < 4;
+select * from v1;
+select * from t1;
+drop table t1;
+drop view v1,v2;
+
+#
+# simple view + simple multi-delete
+#
+create table t1 (a int, b int, primary key(a));
+insert into t1 values (1,2), (2,3), (3,4), (4,5), (5,10);
+create table t2 (x int);
+insert into t2 values (1), (2), (3), (4);
+create view v1 (a,c) as select a, b+1 from t1;
+create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+# try to update VIEW with forced TEMPORARY TABLE algorithm
+-- error 1288
+delete v2 from t2,v2 where t2.x=v2.a;
+# updatable field of updateable view
+delete v1 from t2,v1 where t2.x=v1.a;
+select * from v1;
+select * from t1;
+drop table t1,t2;
+drop view v1,v2;
+
+#
+# DELETE privileges on VIEW
+#
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int, primary key(a));
+insert into mysqltest.t1 values (1,2), (2,3), (3,4), (4,5), (5,10);
+create table mysqltest.t2 (x int);
+insert into mysqltest.t2 values (3), (4), (5), (6);
+create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
+create view mysqltest.v2 (a,c) as select a, b+1 from mysqltest.t1;
+
+grant delete on mysqltest.v1 to mysqltest_1@localhost;
+grant select on mysqltest.* to mysqltest_1@localhost;
+
+connection user1;
+use mysqltest;
+# update with rights on VIEW column
+delete from v1 where c < 4;
+select * from t1;
+delete v1 from t2,v1 where t2.x=v1.c;
+select * from t1;
+# no rights for view
+-- error 1142
+delete v2 from t2,v2 where t2.x=v2.c;
+-- error 1142
+delete from v2 where c < 4;
+
+use test;
+connection root;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
+drop database mysqltest;
+
+#
+# key presence check
+#
+create table t1 (a int, b int, c int, primary key(a,b));
+insert into t1 values (10,2,-1), (20,3,-2), (30,4,-3), (40,5,-4), (50,10,-5);
+create view v1 (x,y) as select a, b from t1;
+create view v2 (x,y) as select a, c from t1;
+set updatable_views_with_limit=NO;
+update v1 set x=x+1;
+update v2 set x=x+1;
+update v1 set x=x+1 limit 1;
+-- error 1288
+update v2 set x=x+1 limit 1;
+set updatable_views_with_limit=YES;
+update v1 set x=x+1 limit 1;
+update v2 set x=x+1 limit 1;
+set updatable_views_with_limit=DEFAULT;
+show variables like "updatable_views_with_limit";
+select * from t1;
+drop table t1;
+drop view v1,v2;
+
+#
+# simple insert
+#
+create table t1 (a int, b int, c int, primary key(a,b));
+insert into t1 values (10,2,-1), (20,3,-2);
+create view v1 (x,y,z) as select c, b, a from t1;
+create view v2 (x,y) as select b, a from t1;
+create view v3 (x,y,z) as select b, a, b from t1;
+create view v4 (x,y,z) as select c+1, b, a from t1;
+create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
+# try insert to VIEW with fields duplicate
+-- error 1288
+insert into v3 values (-60,4,30);
+# try insert to VIEW with expression in SELECT list
+-- error 1288
+insert into v4 values (-60,4,30);
+# try insert to VIEW using temporary table algorithm
+-- error 1288
+insert into v5 values (-60,4,30);
+insert into v1 values (-60,4,30);
+insert into v1 (z,y,x) values (50,6,-100);
+insert into v2 values (5,40);
+select * from t1;
+drop table t1;
+drop view v1,v2,v3,v4,v5;
+
+#
+# insert ... select
+#
+create table t1 (a int, b int, c int, primary key(a,b));
+insert into t1 values (10,2,-1), (20,3,-2);
+create table t2 (a int, b int, c int, primary key(a,b));
+insert into t2 values (30,4,-60);
+create view v1 (x,y,z) as select c, b, a from t1;
+create view v2 (x,y) as select b, a from t1;
+create view v3 (x,y,z) as select b, a, b from t1;
+create view v4 (x,y,z) as select c+1, b, a from t1;
+create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
+# try insert to VIEW with fields duplicate
+-- error 1288
+insert into v3 select c, b, a from t2;
+# try insert to VIEW with expression in SELECT list
+-- error 1288
+insert into v4 select c, b, a from t2;
+# try insert to VIEW using temporary table algorithm
+-- error 1288
+insert into v5 select c, b, a from t2;
+insert into v1 select c, b, a from t2;
+insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
+insert into v2 select b+1, a+10 from t2;
+select * from t1;
+drop table t1, t2;
+drop view v1,v2,v3,v4,v5;
+
+#
+# insert privileges on VIEW
+#
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int, primary key(a));
+insert into mysqltest.t1 values (1,2), (2,3);
+create table mysqltest.t2 (x int, y int);
+insert into mysqltest.t2 values (3,4);
+create view mysqltest.v1 (a,c) as select a, b from mysqltest.t1;
+create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
+
+grant insert on mysqltest.v1 to mysqltest_1@localhost;
+grant select on mysqltest.* to mysqltest_1@localhost;
+
+connection user1;
+use mysqltest;
+# update with rights on VIEW column
+insert into v1 values (5,6);
+select * from t1;
+insert into v1 select x,y from t2;
+select * from t1;
+# no rights for view
+-- error 1142
+insert into v2 values (5,6);
+-- error 1142
+insert into v2 select x,y from t2;
+
+use test;
+connection root;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
+drop database mysqltest;
+
+#
+# outer join based on VIEW with WHERE clause
+#
+create table t1 (a int, primary key(a));
+insert into t1 values (1), (2), (3);
+create view v1 (x) as select a from t1 where a > 1;
+select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);
+drop table t1;
+drop view v1;
+
+#
+# merging WHERE condition on VIEW on VIEW
+#
+create table t1 (a int, primary key(a));
+insert into t1 values (1), (2), (3), (200);
+create view v1 (x) as select a from t1 where a > 1;
+create view v2 (y) as select x from v1 where x < 100;
+select * from v2;
+drop table t1;
+drop view v1,v2;
+
+#
+# VIEW on non-updatable view
+#
+create table t1 (a int, primary key(a));
+insert into t1 values (1), (2), (3), (200);
+create ALGORITHM=TEMPTABLE view v1 (x) as select a from t1;
+create view v2 (y) as select x from v1;
+-- error 1288
+update v2 set y=10 where y=2;
+drop table t1;
+drop view v1,v2;
+
+#
+# auto_increment field out of VIEW
+#
+create table t1 (a int not null auto_increment, b int not null, primary key(a), unique(b));
+create view v1 (x) as select b from t1;
+insert into v1 values (1);
+select last_insert_id();
+insert into t1 (b) values (2);
+select last_insert_id();
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# test of CREATE VIEW privileges if we have limited privileges
+#
+connection root;
+--disable_warnings
+create database mysqltest;
+--enable_warnings
+
+create table mysqltest.t1 (a int, b int);
+create table mysqltest.t2 (a int, b int);
+
+grant update on mysqltest.t1 to mysqltest_1@localhost;
+grant update(b) on mysqltest.t2 to mysqltest_1@localhost;
+grant create view,update on test.* to mysqltest_1@localhost;
+
+connection user1;
+
+create view v1 as select * from mysqltest.t1;
+create view v2 as select b from mysqltest.t2;
+# There are not rights on mysqltest.v1
+-- error 1142
+create view mysqltest.v1 as select * from mysqltest.t1;
+# There are not any rights on mysqltest.t2.a
+-- error 1143
+create view v3 as select a from mysqltest.t2;
+
+# give CRETEA VIEW privileges (without any privileges for result colemn)
+connection root;
+create table mysqltest.v3 (b int);
+grant create view on mysqltest.v3 to mysqltest_1@localhost;
+drop table mysqltest.v3;
+connection user1;
+create view mysqltest.v3 as select b from mysqltest.t2;
+
+# give UPDATE privileges
+connection root;
+grant create view, update on mysqltest.v3 to mysqltest_1@localhost;
+drop view mysqltest.v3;
+connection user1;
+create view mysqltest.v3 as select b from mysqltest.t2;
+
+# give UPDATE and INSERT privilege (to get more privileges then anderlying
+# table)
+connection root;
+grant create view, update, insert on mysqltest.v3 to mysqltest_1@localhost;
+drop view mysqltest.v3;
+connection user1;
+-- error 1143
+create view mysqltest.v3 as select b from mysqltest.t2;
+
+
+# If give other privileges for VIEW then underlaying table have =>
+# creation prohibited
+connection root;
+create table mysqltest.v3 (b int);
+grant select(b) on mysqltest.v3 to mysqltest_1@localhost;
+drop table mysqltest.v3;
+connection user1;
+-- error 1142
+create view mysqltest.v3 as select b from mysqltest.t2;
+
+# Expression need select privileges
+-- error 1143
+create view v4 as select b+1 from mysqltest.t2;
+
+connection root;
+grant create view,update,select on test.* to mysqltest_1@localhost;
+connection user1;
+-- error 1143
+create view v4 as select b+1 from mysqltest.t2;
+
+connection root;
+grant update,select(b) on mysqltest.t2 to mysqltest_1@localhost;
+connection user1;
+create view v4 as select b+1 from mysqltest.t2;
+
+connection root;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
+drop database mysqltest;
+drop view v1,v2,v4;
+
+#
+# VIEW fields quoting
+#
+set sql_mode='ansi';
+create table t1 ("a*b" int);
+create view v1 as select "a*b" from t1;
+show create view v1;
+drop view v1;
+drop table t1;
+set sql_mode=default;
+
+#
+# VIEW without tables
+#
+create table t1 (t_column int);
+create view v1 as select 'a';
+select * from v1, t1;
+drop view v1;
+drop table t1;
+
+#
+# quote mark inside table name
+#
+create table `t1a``b` (col1 char(2));
+create view v1 as select * from `t1a``b`;
+select * from v1;
+describe v1;
+drop view v1;
+drop table `t1a``b`;
+
+#
+# Changing of underlaying table
+#
+create table t1 (col1 char(5),col2 char(5));
+create view v1 as select * from t1;
+drop table t1;
+create table t1 (col1 char(5),newcol2 char(5));
+-- error 1356
+insert into v1 values('a','aa');
+drop table t1;
+-- error 1356
+select * from v1;
+drop view v1;
+
+#
+# check of duplication of column names
+#
+-- error 1060
+create view v1 (a,a) as select 'a','a';
+
+#
+# SP variables inside view test
+#
+delimiter //;
+create procedure p1 () begin declare v int; create view v1 as select v; end;//
+delimiter ;//
+-- error 1351
+call p1();
+drop procedure p1;
+
+#
+# updateablity should be transitive
+#
+create table t1 (col1 int,col2 char(22));
+insert into t1 values(5,'Hello, world of views');
+create view v1 as select * from t1;
+create view v2 as select * from v1;
+update v2 set col2='Hello, view world';
+select * from t1;
+drop view v2, v1;
+drop table t1;
+
+#
+# check 'use index' on view with temporary table
+#
+create table t1 (a int, b int);
+create view v1 as select a, sum(b) from t1 group by a;
+-- error 1072
+select b from v1 use index (some_index) where b=1;
+drop view v1;
+drop table t1;
+
+#
+# using VIEW fields several times in query resolved via temporary tables
+#
+create table t1 (col1 char(5),col2 char(5));
+create view v1 (col1,col2) as select col1,col2 from t1;
+insert into v1 values('s1','p1'),('s1','p2'),('s1','p3'),('s1','p4'),('s2','p1'),('s3','p2'),('s4','p4');
+select distinct first.col2 from t1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+select distinct first.col2 from v1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+drop view v1;
+drop table t1;
+
+#
+# Test of view updatebility in prepared statement
+#
+create table t1 (a int);
+create view v1 as select a from t1;
+insert into t1 values (1);
+
+#update
+SET @v0 = '2';
+PREPARE stmt FROM 'UPDATE v1 SET a = ?';
+EXECUTE stmt USING @v0;
+DEALLOCATE PREPARE stmt;
+
+#insert without field list
+SET @v0 = '3';
+PREPARE stmt FROM 'insert into v1 values (?)';
+EXECUTE stmt USING @v0;
+DEALLOCATE PREPARE stmt;
+
+#insert with field list
+SET @v0 = '4';
+PREPARE stmt FROM 'insert into v1 (a) values (?)';
+EXECUTE stmt USING @v0;
+DEALLOCATE PREPARE stmt;
+
+select * from t1;
+
+drop view v1;
+drop table t1;
+
+#
+# error on preparation
+#
+-- error 1096
+CREATE VIEW v02 AS SELECT * FROM DUAL;
+SHOW TABLES;
+
+#
+# EXISTS with UNION VIEW
+#
+CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2);
+select * from v1;
+drop view v1;
+
+#
+# using VIEW where table is required
+#
+create table t1 (col1 int,col2 char(22));
+create view v1 as select * from t1;
+-- error 1347
+create index i1 on v1 (col1);
+drop view v1;
+drop table t1;
+
+#
+# connection_id(), pi(), current_user(), version() representation test
+#
+CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
+SHOW CREATE VIEW v1;
+drop view v1;
+
+#
+# VIEW built over UNION
+#
+create table t1 (s1 int);
+create table t2 (s2 int);
+insert into t1 values (1), (2);
+insert into t2 values (2), (3);
+create view v1 as select * from t1,t2 union all select * from t1,t2;
+select * from v1;
+drop view v1;
+drop tables t1, t2;
+
+#
+# Aggregate functions in view list
+#
+create table t1 (col1 int);
+insert into t1 values (1);
+create view v1 as select count(*) from t1;
+insert into t1 values (null);
+select * from v1;
+drop view v1;
+drop table t1;
+
+#
+# Showing VIEW with VIEWs in subquery
+#
+create table t1 (a int);
+create table t2 (a int);
+create view v1 as select a from t1;
+create view v2 as select a from t2 where a in (select a from v1);
+show create view v2;
+drop view v2, v1;
+drop table t1, t2;
+
+#
+# SHOW VIEW view with name with spaces
+#
+CREATE VIEW `v 1` AS select 5 AS `5`;
+show create view `v 1`;
+drop view `v 1`;
+
+#
+# Removing database with .frm archives
+#
+create database mysqltest;
+create table mysqltest.t1 (a int, b int);
+create view mysqltest.v1 as select a from mysqltest.t1;
+alter view mysqltest.v1 as select b from mysqltest.t1;
+alter view mysqltest.v1 as select a from mysqltest.t1;
+drop database mysqltest;
+
+#
+# VIEW with full text
+#
+CREATE TABLE t1 (c1 int not null auto_increment primary key, c2 varchar(20), fulltext(c2));
+insert into t1 (c2) VALUES ('real Beer'),('Water'),('Kossu'),('Coca-Cola'),('Vodka'),('Wine'),('almost real Beer');
+select * from t1 WHERE match (c2) against ('Beer');
+CREATE VIEW v1 AS SELECT * from t1 WHERE match (c2) against ('Beer');
+select * from v1;
+drop view v1;
+drop table t1;
+
+#
+# distinct in temporary table with a VIEW
+#
+create table t1 (a int);
+insert into t1 values (1),(1),(2),(2),(3),(3);
+create view v1 as select a from t1;
+select distinct a from v1;
+select distinct a from v1 limit 2;
+select distinct a from t1 limit 2;
+prepare stmt1 from "select distinct a from v1 limit 2";
+execute stmt1;
+execute stmt1;
+deallocate prepare stmt1;
+drop view v1;
+drop table t1;
+
+#
+# aggregate function of aggregate function
+#
+create table t1 (tg_column bigint);
+create view v1 as select count(tg_column) as vg_column from t1;
+select avg(vg_column) from v1;
+drop view v1;
+drop table t1;
+
+#
+# VIEW of VIEW with column renaming
+#
+create table t1 (col1 bigint not null, primary key (col1));
+create table t2 (col1 bigint not null, key (col1));
+create view v1 as select * from t1;
+create view v2 as select * from t2;
+insert into v1 values (1);
+insert into v2 values (1);
+create view v3 (a,b) as select v1.col1 as a, v2.col1 as b from v1, v2 where v1.col1 = v2.col1;
+select * from v3;
+show create view v3;
+drop view v3, v2, v1;
+drop table t2, t1;
+
+#
+# VIEW based on functions with complex names
+#
+create function `f``1` () returns int return 5;
+create view v1 as select test.`f``1` ();
+show create view v1;
+select * from v1;
+drop view v1;
+drop function `f``1`;
+
+#
+# tested problem when function name length close to ALIGN_SIZE
+#
+create function x () returns int return 5;
+create view v1 as select x ();
+select * from v1;
+drop view v1;
+drop function x;
+
+#
+# VIEW with collation
+#
+create table t2 (col1 char collate latin1_german2_ci);
+create view v2 as select col1 collate latin1_german1_ci from t2;
+show create view v2;
+show create view v2;
+drop view v2;
+drop table t2;
+
+#
+# order by refers on integer field
+#
+create table t1 (a int);
+insert into t1 values (1), (2);
+create view v1 as select 5 from t1 order by 1;
+select * from v1;
+drop view v1;
+drop table t1;
+
+#
+# VIEW over droped function
+#
+create function x1 () returns int return 5;
+create table t1 (s1 int);
+create view v1 as select x1() from t1;
+drop function x1;
+-- error 1305
+select * from v1;
+--replace_column 12 # 13 #
+show table status;
+--replace_column 12 # 13 #
+show table status;
+drop view v1;
+drop table t1;
+
+#
+# VIEW with floating point (long bumber) as column
+#
+create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1;
+show create view v1;
+drop view v1;
+
+#
+# VIEWs with national characters
+#
+create table tü (cü char);
+create view vü as select cü from tü;
+insert into vü values ('ü');
+select * from vü;
+drop view vü;
+drop table tü;
+
+#
+# problem with used_tables() of outer reference resolved in VIEW
+#
+create table t1 (a int, b int);
+insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
+create view v1(c) as select a+1 from t1 where b >= 4;
+select c from v1 where exists (select * from t1 where a=2 and b=c);
+drop view v1;
+drop table t1;
+
+#
+# view with cast operation
+#
+create view v1 as select cast(1 as char(3));
+show create view v1;
+select * from v1;
+drop view v1;
+
+#
+# bug handlimg from VIEWs
+#
+create view v1 as select 'a',1;
+create view v2 as select * from v1 union all select * from v1;
+create view v3 as select * from v2 where 1 = (select `1` from v2);
+create view v4 as select * from v3;
+-- error 1242
+select * from v4;
+drop view v4, v3, v2, v1;
+
+#
+# VIEW over SELECT with prohibited clauses
+#
+-- error 1350
+create view v1 as select 5 into @w;
+-- error 1350
+create view v1 as select 5 into outfile 'ttt';
+create table t1 (a int);
+-- error 1350
+create view v1 as select a from t1 procedure analyse();
+drop table t1;
+
+#
+# INSERT into VIEW with ON DUPLICATE
+#
+create table t1 (s1 int, primary key (s1));
+create view v1 as select * from t1;
+insert into v1 values (1) on duplicate key update s1 = 7;
+insert into v1 values (1) on duplicate key update s1 = 7;
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# test of updating and fetching from the same table check
+#
+create table t1 (col1 int);
+create table t2 (col1 int);
+create view v1 as select * from t1;
+create view v2 as select * from v1;
+-- error 1093
+update v2 set col1 = (select max(col1) from v1);
+#update v2,t2 set v2.col1 = (select max(col1) from v1) where v2.col1 = t2.col1;
+-- error 1093
+delete from v2 where col1 = (select max(col1) from v1);
+#delete v2 from v2,t2 where (select max(col1) from v1) > 0 and v2.col1 = t2.col1;
+-- error 1093
+insert into v2 values ((select max(col1) from v1));
+drop view v2,v1;
+drop table t1,t2;
+
+#
+# HANDLER with VIEW
+#
+create table t1 (s1 int);
+create view v1 as select * from t1;
+-- error 1347
+handler v1 open as xx;
+drop view v1;
+drop table t1;
+
+#
+# view with WHERE in nested join
+#
+create table t1(a int);
+insert into t1 values (0), (1), (2), (3);
+create table t2 (a int);
+insert into t2 select a from t1 where a > 1;
+create view v1 as select a from t1 where a > 1;
+select * from t1 left join (t2 as t, v1) on v1.a=t1.a;
+select * from t1 left join (t2 as t, t2) on t2.a=t1.a;
+drop view v1;
+drop table t1, t2;
+
+#
+# Collation with view update
+#
+create table t1 (s1 char);
+create view v1 as select s1 collate latin1_german1_ci as s1 from t1;
+insert into v1 values ('a');
+select * from v1;
+update v1 set s1='b';
+select * from v1;
+update v1,t1 set v1.s1='c' where t1.s1=v1.s1;
+select * from v1;
+prepare stmt1 from "update v1,t1 set v1.s1=? where t1.s1=v1.s1";
+set @arg='d';
+-- QQ This should not generate an error
+--error 1036
+execute stmt1 using @arg;
+select * from v1;
+set @arg='e';
+-- QQ This should not generate an error
+--error 1036
+execute stmt1 using @arg;
+select * from v1;
+deallocate prepare stmt1;
+drop view v1;
+drop table t1;
+
+#
+# test view with LOCK TABLES (work around)
+#
+create table t1 (a int);
+create table t2 (a int);
+create view v1 as select * from t1;
+lock tables t1 read, v1 read;
+select * from v1;
+-- error 1100
+select * from t2;
+drop view v1;
+drop table t1, t2;
+
+#
+# WITH CHECK OPTION insert/update test
+#
+create table t1 (a int);
+create view v1 as select * from t1 where a < 2 with check option;
+# simple insert
+insert into v1 values(1);
+-- error 1369
+insert into v1 values(3);
+# simple insert with ignore
+insert ignore into v1 values (2),(3),(0);
+select * from t1;
+# prepare data for next check
+delete from t1;
+# INSERT SELECT test
+insert into v1 SELECT 1;
+-- error 1369
+insert into v1 SELECT 3;
+# prepare data for next check
+create table t2 (a int);
+insert into t2 values (2),(3),(0);
+# INSERT SELECT with ignore test
+insert ignore into v1 SELECT a from t2;
+select * from t1;
+#simple UPDATE test
+update v1 set a=-1 where a=0;
+-- error 1369
+update v1 set a=2 where a=1;
+select * from t1;
+# prepare data for next check
+update v1 set a=0 where a=0;
+insert into t2 values (1);
+# multiupdate test
+update v1,t2 set v1.a=v1.a-1 where v1.a=t2.a;
+select * from t1;
+# prepare data for next check
+update v1 set a=a+1;
+# multiupdate with ignore test
+update ignore v1,t2 set v1.a=v1.a+1 where v1.a=t2.a;
+select * from t1;
+
+drop view v1;
+drop table t1, t2;
+
+#
+# CASCADED/LOCAL CHECK OPTION test
+#
+create table t1 (a int);
+create view v1 as select * from t1 where a < 2 with check option;
+create view v2 as select * from v1 where a > 0 with local check option;
+create view v3 as select * from v1 where a > 0 with cascaded check option;
+insert into v2 values (1);
+insert into v3 values (1);
+-- error 1369
+insert into v2 values (0);
+-- error 1369
+insert into v3 values (0);
+insert into v2 values (2);
+-- error 1369
+insert into v3 values (2);
+select * from t1;
+drop view v3,v2,v1;
+drop table t1;
+
+#
+# CHECK OPTION with INSERT ... ON DUPLICATE KEY UPDATE
+#
+create table t1 (a int, primary key (a));
+create view v1 as select * from t1 where a < 2 with check option;
+insert into v1 values (1) on duplicate key update a=2;
+-- error 1369
+insert into v1 values (1) on duplicate key update a=2;
+insert ignore into v1 values (1) on duplicate key update a=2;
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# check cyclic referencing protection on altering view
+#
+create table t1 (s1 int);
+create view v1 as select * from t1;
+create view v2 as select * from v1;
+-- error 1146
+alter view v1 as select * from v2;
+-- error 1066
+alter view v1 as select * from v1;
+-- error 1146
+create or replace view v1 as select * from v2;
+-- error 1066
+create or replace view v1 as select * from v1;
+drop view v2,v1;
+drop table t1;
+
+#
+# check altering differ options
+#
+create table t1 (a int);
+create view v1 as select * from t1;
+show create view v1;
+alter algorithm=undefined view v1 as select * from t1 with check option;
+show create view v1;
+alter algorithm=merge view v1 as select * from t1 with cascaded check option;
+show create view v1;
+alter algorithm=temptable view v1 as select * from t1;
+show create view v1;
+drop view v1;
+drop table t1;
+
+#
+# updating view with subquery in the WHERE clause
+#
+create table t1 (s1 int);
+create table t2 (s1 int);
+create view v2 as select * from t2 where s1 in (select s1 from t1);
+insert into v2 values (5);
+insert into t1 values (5);
+select * from v2;
+update v2 set s1 = 0;
+select * from v2;
+select * from t2;
+# check it with check option
+alter view v2 as select * from t2 where s1 in (select s1 from t1) with check option;
+insert into v2 values (5);
+-- error 1369
+update v2 set s1 = 1;
+insert into t1 values (1);
+update v2 set s1 = 1;
+select * from v2;
+select * from t2;
+# scheck how VIEWs with subqueries work with prepared statements
+prepare stmt1 from "select * from v2;";
+execute stmt1;
+insert into t1 values (0);
+execute stmt1;
+deallocate prepare stmt1;
+drop view v2;
+drop table t1, t2;
+
+#
+# test of substring_index with view
+#
+create table t1 (t time);
+create view v1 as select substring_index(t,':',2) as t from t1;
+insert into t1 (t) values ('12:24:10');
+select substring_index(t,':',2) from t1;
+select substring_index(t,':',2) from v1;
+drop view v1;
+drop table t1;
+
+#
+# test of cascaded check option for whiew without WHERE clause
+#
+create table t1 (s1 tinyint);
+create view v1 as select * from t1 where s1 <> 0 with local check option;
+create view v2 as select * from v1 with cascaded check option;
+-- error 1369
+insert into v2 values (0);
+drop view v2, v1;
+drop table t1;
+
+#
+# inserting single value with check option failed always get error
+#
+create table t1 (s1 int);
+create view v1 as select * from t1 where s1 < 5 with check option;
+#single value
+-- error 1369
+insert ignore into v1 values (6);
+#several values
+insert ignore into v1 values (6),(3);
+select * from t1;
+drop view v1;
+drop table t1;
+
+#
+# changing value by trigger and CHECK OPTION
+#
+create table t1 (s1 tinyint);
+create trigger t1_bi before insert on t1 for each row set new.s1 = 500;
+create view v1 as select * from t1 where s1 <> 127 with check option;
+-- error 1369
+insert into v1 values (0);
+select * from v1;
+select * from t1;
+drop trigger t1.t1_bi;
+drop view v1;
+drop table t1;
+
+#
+# CASCADED should be used for all underlaying VIEWs
+#
+create table t1 (s1 tinyint);
+create view v1 as select * from t1 where s1 <> 0;
+create view v2 as select * from v1 where s1 <> 1 with cascaded check option;
+-- error 1369
+insert into v2 values (0);
+select * from v2;
+select * from t1;
+drop view v2, v1;
+drop table t1;
+
+#
+# LOAD DATA with view and CHECK OPTION
+#
+# fixed length fields
+create table t1 (a int, b char(10));
+create view v1 as select * from t1 where a != 0 with check option;
+-- error 1369
+load data infile '../../std_data/loaddata3.dat' into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
+select * from t1;
+select * from v1;
+delete from t1;
+load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
+select * from t1;
+select * from v1;
+drop view v1;
+drop table t1;
+# variable length fields
+create table t1 (a text, b text);
+create view v1 as select * from t1 where a <> 'Field A' with check option;
+-- error 1369
+load data infile '../../std_data/loaddata2.dat' into table v1 fields terminated by ',' enclosed by '''';
+select concat('|',a,'|'), concat('|',b,'|') from t1;
+select concat('|',a,'|'), concat('|',b,'|') from v1;
+delete from t1;
+load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by '''';
+select concat('|',a,'|'), concat('|',b,'|') from t1;
+select concat('|',a,'|'), concat('|',b,'|') from v1;
+drop view v1;
+drop table t1;
+
diff --git a/mysql-test/t/view_skip_grants-master.opt b/mysql-test/t/view_skip_grants-master.opt
new file mode 100644
index 00000000000..5699a3387b8
--- /dev/null
+++ b/mysql-test/t/view_skip_grants-master.opt
@@ -0,0 +1 @@
+--skip-grant-tables
diff --git a/mysql-test/t/view_skip_grants.test b/mysql-test/t/view_skip_grants.test
new file mode 100644
index 00000000000..bfbaec44eb1
--- /dev/null
+++ b/mysql-test/t/view_skip_grants.test
@@ -0,0 +1,14 @@
+--disable_warnings
+drop table if exists t1,v1;
+drop view if exists t1,v1;
+--enable_warnings
+use test;
+
+#
+# test that we can create VIEW if privileges check switched off
+#
+create table t1 (field1 INT);
+CREATE VIEW v1 AS SELECT field1 FROM t1;
+
+drop view v1;
+drop table t1