summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhery.ramilison@oracle.com <>2011-11-17 09:00:58 +0100
committerBuild Team <MYSQL-RE_WW@oracle.com>2011-11-17 09:00:58 +0100
commit85f07c7d7de623b5c9de188e99445fb96212957d (patch)
tree1dd794717469322a1b041143778258b1fc84fbff
parent6c1fa38c50341a7558aa402ba3704926fbe5426a (diff)
parent4ee0f595650f9400887ccdc89f20860fa03417f5 (diff)
downloadmariadb-git-85f07c7d7de623b5c9de188e99445fb96212957d.tar.gz
Merge from mysql-5.5.18-release
-rw-r--r--mysql-test/r/func_if.result14
-rw-r--r--mysql-test/r/func_str.result6
-rw-r--r--mysql-test/r/group_min_max_innodb.result24
-rw-r--r--mysql-test/r/partition_innodb_plugin.result34
-rw-r--r--mysql-test/r/sp.result150
-rw-r--r--mysql-test/r/type_newdecimal.result44
-rw-r--r--mysql-test/r/view_grant.result225
-rw-r--r--mysql-test/suite/innodb/r/innodb.result16
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug12661768.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug54044.result11
-rw-r--r--mysql-test/suite/innodb/r/innodb_misc1.result887
-rw-r--r--mysql-test/suite/innodb/t/innodb.test18
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug12661768.test50
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug54044.test14
-rw-r--r--mysql-test/suite/innodb/t/innodb_misc1-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_misc1.test1184
-rw-r--r--mysql-test/suite/parts/r/partition_debug_innodb.result71
-rw-r--r--mysql-test/suite/parts/t/partition_debug_innodb.test35
-rw-r--r--mysql-test/t/func_if.test12
-rw-r--r--mysql-test/t/func_str.test5
-rw-r--r--mysql-test/t/group_min_max_innodb.test20
-rw-r--r--mysql-test/t/partition_innodb_plugin.test27
-rw-r--r--mysql-test/t/sp.test156
-rw-r--r--mysql-test/t/type_newdecimal.test21
-rw-r--r--mysql-test/t/view_grant.test366
-rw-r--r--sql/field.cc3
-rw-r--r--sql/ha_partition.cc202
-rw-r--r--sql/handler.cc8
-rw-r--r--sql/handler.h6
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc46
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_strfunc.cc15
-rw-r--r--sql/my_decimal.h38
-rw-r--r--sql/opt_range.cc12
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/sp_head.cc18
-rw-r--r--sql/sql_acl.cc145
-rw-r--r--sql/sql_cache.cc34
-rw-r--r--sql/sql_lex.cc59
-rw-r--r--sql/sql_parse.cc31
-rw-r--r--sql/sql_reload.cc32
-rw-r--r--sql/sql_repl.cc10
-rw-r--r--sql/sql_view.cc38
-rw-r--r--sql/sql_yacc.yy3
-rw-r--r--storage/innobase/handler/ha_innodb.cc9
-rw-r--r--storage/innobase/row/row0ins.c17
-rw-r--r--strings/decimal.c21
-rw-r--r--tests/mysql_client_test.c81
49 files changed, 4048 insertions, 179 deletions
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index c70589a27b7..7946d8f328c 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -196,3 +196,17 @@ c
NULL
0
DROP TABLE t1;
+#
+# Bug#12532830
+# SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
+#
+select
+sum(distinct(if('a',
+(select adddate(elt(convert(9999999999999999999999999999999999999,decimal(64,0)),count(*)),
+interval 1 day))
+, .1))) as foo;
+foo
+0.1
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 5d3ac26fe3d..abf76a533b3 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2785,6 +2785,12 @@ format(123,2,'no_NO')
123,00
DROP TABLE t1;
#
+# Bug#11764310 conv function crashes, negative argument to memcpy
+#
+SELECT CONV(1,-2147483648,-2147483648);
+CONV(1,-2147483648,-2147483648)
+NULL
+#
# Bug#12985030 SIMPLE QUERY WITH DECIMAL NUMBERS LEAKS MEMORY
#
SELECT (rpad(1.0,2048,1)) IS NOT FALSE;
diff --git a/mysql-test/r/group_min_max_innodb.result b/mysql-test/r/group_min_max_innodb.result
index 6607e1babf6..0e7841e979d 100644
--- a/mysql-test/r/group_min_max_innodb.result
+++ b/mysql-test/r/group_min_max_innodb.result
@@ -94,3 +94,27 @@ pk
drop view v1;
drop table t1;
End of 5.1 tests
+#
+# Bug#12540545 61101: ASSERTION FAILURE IN THREAD 1256741184 IN
+# FILE /BUILDDIR/BUILD/BUILD/MYSQ
+#
+CREATE TABLE t1 (a CHAR(1), b CHAR(1), PRIMARY KEY (a,b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 2 NULL 2 Using where; Using index
+SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+COUNT(DISTINCT a)
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(1) NOT NULL, b CHAR(1) NOT NULL, UNIQUE KEY (a,b))
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL a 2 NULL 2 Using where; Using index
+SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+COUNT(DISTINCT a)
+1
+DROP TABLE t1;
+End of 5.5 tests
diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result
index 43838170501..7efd2142d51 100644
--- a/mysql-test/r/partition_innodb_plugin.result
+++ b/mysql-test/r/partition_innodb_plugin.result
@@ -1,3 +1,37 @@
+#
+# Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
+# PARTITONING, ON INDEX CREATE
+# Bug#12696518: MEMORY LEAKS IN HA_PARTITION (VALGRIND TESTS ON TRUNK)
+#
+CREATE TABLE t1 (
+id bigint NOT NULL AUTO_INCREMENT,
+time date,
+id2 bigint not null,
+PRIMARY KEY (id,time)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+/*!50100 PARTITION BY RANGE(TO_DAYS(time))
+(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
+PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
+INSERT INTO t1 (time,id2) VALUES ('2011-07-24',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+CREATE UNIQUE INDEX uk_time_id2 on t1(time,id2);
+ERROR 23000: Duplicate entry '2011-07-25-1' for key 'uk_time_id2'
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `time` date NOT NULL DEFAULT '0000-00-00',
+ `id2` bigint(20) NOT NULL,
+ PRIMARY KEY (`id`,`time`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
+/*!50100 PARTITION BY RANGE (TO_DAYS(time))
+(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
+ PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+DROP TABLE t1;
call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal");
#
# Bug#55091: Server crashes on ADD PARTITION after a failed attempt
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 104ddd3353b..1644c764431 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -7437,17 +7437,17 @@ ERROR 42000: Undeclared variable: a
# Try to use data types not allowed in LIMIT
#
create procedure p1(p1 date, p2 date) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
create procedure p1(p1 integer, p2 float) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
create procedure p1(p1 integer, p2 char(1)) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
create procedure p1(p1 varchar(5), p2 char(1)) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
create procedure p1(p1 decimal, p2 decimal) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
create procedure p1(p1 double, p2 double) select * from t1 limit p1, p2;
-ERROR HY000: A variable of a non-integer type in LIMIT clause
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
#
# Finally, test the valid case.
#
@@ -7483,9 +7483,117 @@ call p1(3, 2);
c1
4
5
+# Try to create a function that
+# refers to non-existing variables.
+create function f1(p1 integer, p2 integer)
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit a, b);
+return a;
+end|
+ERROR 42000: Undeclared variable: b
+create function f1()
+returns int
+begin
+declare a, b, c int;
+set a = (select count(*) from t1 limit b, c);
+return a;
+end|
+# How do we handle NULL limit values?
+select f1();
+f1()
+NULL
+drop function f1;
+#
+# Try to use data types not allowed in LIMIT
+#
+create function f1(p1 date, p2 date)
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+create function f1(p1 integer, p2 float)
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+create function f1(p1 integer, p2 char(1))
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+create function f1(p1 varchar(5), p2 char(1))
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+create function f1(p1 decimal, p2 decimal)
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+create function f1(p1 double, p2 double)
+returns int
+begin
+declare a int;
+set a = (select count(*) from t1 limit p1, p2);
+return a;
+end|
+ERROR HY000: A variable of a non-integer based type in LIMIT clause
+#
+# Finally, test the valid case.
+#
+create function f1(p1 integer, p2 integer)
+returns int
+begin
+declare count int;
+set count= (select count(*) from (select * from t1 limit p1, p2) t_1);
+return count;
+end|
+select f1(0, 0);
+f1(0, 0)
+0
+select f1(0, -1);
+f1(0, -1)
+5
+select f1(-1, 0);
+f1(-1, 0)
+0
+select f1(-1, -1);
+f1(-1, -1)
+0
+select f1(0, 1);
+f1(0, 1)
+1
+select f1(1, 0);
+f1(1, 0)
+0
+select f1(1, 5);
+f1(1, 5)
+4
+select f1(3, 2);
+f1(3, 2)
+2
# Cleanup
drop table t1;
drop procedure p1;
+drop function f1;
#
# BUG#11766234: 59299: ASSERT (TABLE_REF->TABLE || TABLE_REF->VIEW)
# FAILS IN SET_FIELD_ITERATOR
@@ -7606,4 +7714,34 @@ b
DROP TABLE t1;
DROP PROCEDURE p1;
+#
+# Bug#12621017 - Crash if a sp variable is used in the
+# limit clause of a set statement
+#
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE foo, cnt INT UNSIGNED DEFAULT 1;
+SET foo = (SELECT MIN(c1) FROM t1 LIMIT cnt);
+END|
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE iLimit INT;
+DECLARE iVal INT;
+DECLARE cur1 CURSOR FOR
+SELECT c1 FROM t1
+LIMIT iLimit;
+SET iLimit=1;
+OPEN cur1;
+FETCH cur1 INTO iVal;
+END|
+CALL p1();
+CALL p2();
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
# End of 5.5 test
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 30c3c8f6442..cba809ce354 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1544,6 +1544,50 @@ select * from t1;
5.05 / 0.014
360.714286
DROP TABLE t1;
+#
+# Bug#12563865
+# ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
+#
+SELECT substring(('M') FROM (999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
+foo
+
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: ''
+Warning 1292 Truncated incorrect DECIMAL value: ''
+SELECT min(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+999999999999999999999999999999999999999999999999999999999999999999999999999999999
+SELECT multipolygonfromtext(('4294967294.1'),(999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
+foo
+NULL
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: ''
+SELECT convert((999999999999999999999999999999999999999999999999999999999999999999999999999999999), decimal(30,30)) AS foo;
+foo
+0.999999999999999999999999999999
+Warnings:
+Warning 1264 Out of range value for column 'foo' at row 1
+SELECT bit_xor(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+9223372036854775807
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: ''
+SELECT -(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+-999999999999999999999999999999999999999999999999999999999999999999999999999999999
+SELECT date_sub((999999999999999999999999999999999999999999999999999999999999999999999999999999999),
+interval ((SELECT date_add((0x77500000),
+interval ('Oml') second)))
+day_minute)
+AS foo;
+foo
+NULL
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: ''
+Warning 1292 Incorrect datetime value: '9223372036854775807'
+SELECT truncate(999999999999999999999999999999999999999999999999999999999999999999999999999999999, 28) AS foo;
+foo
+999999999999999999999999999999999999999999999999999999999999999999999999999999999
End of 5.0 tests
select cast(143.481 as decimal(4,1));
cast(143.481 as decimal(4,1))
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 9a0408bc174..bfd09bfa9cd 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -66,10 +66,12 @@ 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;
+create view mysqltest.v5 (c,d) as select a+1,b+1 from mysqltest.t1;
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;
+grant show view on mysqltest.v5 to mysqltest_1@localhost;
select c from mysqltest.v1;
c
select c from mysqltest.v2;
@@ -78,6 +80,8 @@ select c from mysqltest.v3;
c
select c from mysqltest.v4;
c
+select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
show columns from mysqltest.v1;
Field Type Null Key Default Extra
c bigint(12) YES NULL
@@ -102,16 +106,29 @@ explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+explain select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
+show create view mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
+grant select on mysqltest.v5 to mysqltest_1@localhost;
+show create view mysqltest.v5;
+View Create View character_set_client collation_connection
+v5 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v5` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
+explain select c from mysqltest.v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+show create view mysqltest.v1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+grant show view on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.t1 to mysqltest_1@localhost;
+revoke select on mysqltest.v5 from mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
show create view mysqltest.v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
explain select c from mysqltest.v2;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
-2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v2;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
explain select c from mysqltest.v3;
@@ -122,6 +139,8 @@ explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+explain select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
grant show view on mysqltest.* to mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -137,15 +156,12 @@ show create view mysqltest.v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
explain select c from mysqltest.v3;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
explain select c from mysqltest.v4;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
-2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
@@ -947,6 +963,197 @@ DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
+Bug #11765687/#58677:
+No privilege on table/view, but can know #rows / underlying table's name
+create database mysqltest1;
+create table mysqltest1.t1 (i int);
+create table mysqltest1.t2 (j int);
+create table mysqltest1.t3 (k int, secret int);
+create user alice@localhost;
+create user bob@localhost;
+create user cecil@localhost;
+create user dan@localhost;
+create user eugene@localhost;
+create user fiona@localhost;
+create user greg@localhost;
+create user han@localhost;
+create user inga@localhost;
+create user jamie@localhost;
+create user karl@localhost;
+create user lena@localhost;
+create user mhairi@localhost;
+create user noam@localhost;
+create user olga@localhost;
+create user pjotr@localhost;
+create user quintessa@localhost;
+grant all privileges on mysqltest1.* to alice@localhost with grant option;
+... as alice
+create view v1 as select * from t1;
+create view v2 as select * from v1, t2;
+create view v3 as select k from t3;
+grant select on mysqltest1.v1 to bob@localhost;
+grant show view on mysqltest1.v1 to cecil@localhost;
+grant select, show view on mysqltest1.v1 to dan@localhost;
+grant select on mysqltest1.t1 to dan@localhost;
+grant select on mysqltest1.* to eugene@localhost;
+grant select, show view on mysqltest1.v2 to fiona@localhost;
+grant select, show view on mysqltest1.v2 to greg@localhost;
+grant show view on mysqltest1.v1 to greg@localhost;
+grant select(k) on mysqltest1.t3 to han@localhost;
+grant select, show view on mysqltest1.v3 to han@localhost;
+grant select on mysqltest1.t1 to inga@localhost;
+grant select on mysqltest1.t2 to inga@localhost;
+grant select on mysqltest1.v1 to inga@localhost;
+grant select, show view on mysqltest1.v2 to inga@localhost;
+grant select on mysqltest1.t1 to jamie@localhost;
+grant select on mysqltest1.t2 to jamie@localhost;
+grant show view on mysqltest1.v1 to jamie@localhost;
+grant select, show view on mysqltest1.v2 to jamie@localhost;
+grant select on mysqltest1.t1 to karl@localhost;
+grant select on mysqltest1.t2 to karl@localhost;
+grant select, show view on mysqltest1.v1 to karl@localhost;
+grant select on mysqltest1.v2 to karl@localhost;
+grant select on mysqltest1.t1 to lena@localhost;
+grant select on mysqltest1.t2 to lena@localhost;
+grant select, show view on mysqltest1.v1 to lena@localhost;
+grant show view on mysqltest1.v2 to lena@localhost;
+grant select on mysqltest1.t1 to mhairi@localhost;
+grant select on mysqltest1.t2 to mhairi@localhost;
+grant select, show view on mysqltest1.v1 to mhairi@localhost;
+grant select, show view on mysqltest1.v2 to mhairi@localhost;
+grant select on mysqltest1.t1 to noam@localhost;
+grant select, show view on mysqltest1.v1 to noam@localhost;
+grant select, show view on mysqltest1.v2 to noam@localhost;
+grant select on mysqltest1.t2 to olga@localhost;
+grant select, show view on mysqltest1.v1 to olga@localhost;
+grant select, show view on mysqltest1.v2 to olga@localhost;
+grant select on mysqltest1.t1 to pjotr@localhost;
+grant select on mysqltest1.t2 to pjotr@localhost;
+grant select, show view on mysqltest1.v2 to pjotr@localhost;
+grant select, show view on mysqltest1.v1 to quintessa@localhost;
+... as bob
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as cecil
+select * from v1;
+ERROR 42000: SELECT command denied to user 'cecil'@'localhost' for table 'v1'
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'cecil'@'localhost' for table 'v1'
+... as dan
+select * from v1;
+i
+explain select * from v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
+... as eugene
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as fiona
+select * from v2;
+i j
+show create view v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`alice`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`i` AS `i`,`t2`.`j` AS `j` from (`v1` join `t2`) latin1 latin1_swedish_ci
+explain select * from t1;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 't1'
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 'v1'
+explain select * from t2;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 't2'
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as greg
+select * from v2;
+i j
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'greg'@'localhost' for table 'v1'
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as han
+select * from t3;
+ERROR 42000: SELECT command denied to user 'han'@'localhost' for table 't3'
+explain select * from t3;
+ERROR 42000: SELECT command denied to user 'han'@'localhost' for table 't3'
+select k from t3;
+k
+explain select k from t3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+select * from v3;
+k
+explain select * from v3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
+... as inga
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as jamie
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as karl
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as lena
+select * from v2;
+ERROR 42000: SELECT command denied to user 'lena'@'localhost' for table 'v2'
+explain select * from v2;
+ERROR 42000: SELECT command denied to user 'lena'@'localhost' for table 'v2'
+... as mhairi
+select * from v2;
+i j
+explain select * from v2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+... as noam
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as olga
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as pjotr
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as quintessa
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as root again at last: clean-up time!
+drop user alice@localhost;
+drop user bob@localhost;
+drop user cecil@localhost;
+drop user dan@localhost;
+drop user eugene@localhost;
+drop user fiona@localhost;
+drop user greg@localhost;
+drop user han@localhost;
+drop user inga@localhost;
+drop user jamie@localhost;
+drop user karl@localhost;
+drop user lena@localhost;
+drop user mhairi@localhost;
+drop user noam@localhost;
+drop user olga@localhost;
+drop user pjotr@localhost;
+drop user quintessa@localhost;
+drop database mysqltest1;
End of 5.0 tests.
DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 3aafd81084e..54908961b1c 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1301,6 +1301,20 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 42S22: Unknown column 't1.id' in 'where clause'
drop table t3,t2,t1;
+CREATE TABLE t1 (
+c1 VARCHAR(8), c2 VARCHAR(8),
+PRIMARY KEY (c1, c2)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+c0 INT PRIMARY KEY,
+c1 VARCHAR(8) UNIQUE,
+FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue');
+INSERT INTO t2 VALUES (10, 'old'), (20, 'other');
+UPDATE t1 SET c1 = 'other' WHERE c1 = 'old';
+ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 2 would lead to a duplicate entry
+DROP TABLE t2,t1;
create table t1(
id int primary key,
pid int,
@@ -1673,7 +1687,7 @@ variable_value - @innodb_rows_deleted_orig
71
SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
variable_value - @innodb_rows_inserted_orig
-1066
+1070
SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
variable_value - @innodb_rows_updated_orig
866
diff --git a/mysql-test/suite/innodb/r/innodb_bug12661768.result b/mysql-test/suite/innodb/r/innodb_bug12661768.result
new file mode 100644
index 00000000000..1f2401ddd47
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug12661768.result
@@ -0,0 +1,2 @@
+SET SESSION foreign_key_checks=0;
+ERROR 23000: Upholding foreign key constraints for table 'bug12661768_1', entry '3-bbb', key 2 would lead to a duplicate entry
diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result
index 90ab812f2ae..350c500cb9b 100644
--- a/mysql-test/suite/innodb/r/innodb_bug54044.result
+++ b/mysql-test/suite/innodb/r/innodb_bug54044.result
@@ -1,3 +1,12 @@
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
-ERROR HY000: Can't create table 'test.table_54044' (errno: -1)
+SHOW CREATE TABLE table_54044;
+Table Create Table
+table_54044 CREATE TEMPORARY TABLE `table_54044` (
+ `IF(NULL IS NOT NULL, NULL, NULL)` binary(0) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE table_54044;
+CREATE TABLE tmp ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL);
+ERROR HY000: Can't create table 'test.tmp' (errno: -1)
+CREATE TABLE tmp ENGINE = INNODB AS SELECT GREATEST(NULL, NULL);
+ERROR HY000: Can't create table 'test.tmp' (errno: -1)
diff --git a/mysql-test/suite/innodb/r/innodb_misc1.result b/mysql-test/suite/innodb/r/innodb_misc1.result
new file mode 100644
index 00000000000..c8bcc32dfb4
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_misc1.result
@@ -0,0 +1,887 @@
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
+create table t1 (v varchar(16384)) engine=innodb;
+drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
+CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2), (1), (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+truncate table t1;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2);
+replace into t1 (b) values (1);
+replace into t1 (b) values (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+drop table t1;
+create table t1 (rowid int not null auto_increment, val int not null,primary
+key (rowid), unique(val)) engine=innodb;
+replace into t1 (val) values ('1'),('2');
+replace into t1 (val) values ('1'),('2');
+insert into t1 (val) values ('1'),('2');
+ERROR 23000: Duplicate entry '1' for key 'val'
+select * from t1;
+rowid val
+3 1
+4 2
+drop table t1;
+create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB;
+insert into t1 (val) values (1);
+update t1 set a=2 where a=1;
+insert into t1 (val) values (1);
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+select * from t1;
+a val
+2 1
+drop table t1;
+CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB;
+INSERT INTO t1 (GRADE) VALUES (151),(252),(343);
+SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300;
+GRADE
+252
+SELECT GRADE FROM t1 WHERE GRADE= 151;
+GRADE
+151
+DROP TABLE t1;
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+f1 f2
+drop table t1,t2;
+CREATE TABLE t1 (
+id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id INTEGER NOT NULL,
+FOREIGN KEY (id) REFERENCES t1 (id)
+) ENGINE=InnoDB;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+TRUNCATE t1;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+2
+DELETE FROM t1;
+TRUNCATE t1;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+3
+DROP TABLE t2, t1;
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2
+(
+id INT NOT NULL PRIMARY KEY,
+b INT,
+FOREIGN KEY (b) REFERENCES test.t1(id)
+) ENGINE=InnoDB;
+Got one of the listed errors
+DROP TABLE t1;
+create table t1 (col1 varchar(2000), index (col1(767)))
+character set = latin1 engine = innodb;
+create table t2 (col1 char(255), index (col1))
+character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+character set = latin1 engine = innodb;
+show create table t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `col1` varchar(512) DEFAULT NULL,
+ `col2` varchar(512) DEFAULT NULL,
+ KEY `col1` (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+create table t1 (col1 varchar(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `col1` varchar(768) DEFAULT NULL,
+ KEY `col1` (`col1`(767))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4;
+create table t1 (col1 varchar(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TABLE t2
+(
+v INT,
+CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+DELETE FROM t1 WHERE id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+INSERT INTO t2 VALUES(3);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t2;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+commit;
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+commit;
+drop table t1;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+set autocommit=1;
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table 'test.t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2;
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+ERROR HY000: Can't create table 'test.t2' (errno: 150)
+set foreign_key_checks=1;
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+alter table t1 modify column a int;
+Got one of the listed errors
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+rename table t3 to t1;
+ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2,t3;
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+insert into t1 values(1);
+insert into t3 values(1);
+insert into t2 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+insert into t4 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+insert into t2 values(1);
+insert into t4 values(1);
+update t1 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t2 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t3 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+update t4 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t1;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
+truncate t3;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
+truncate t2;
+truncate t4;
+truncate t1;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
+truncate t3;
+ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
+drop table t4,t3,t2,t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+key (a,b,c,d)) engine=innodb;
+drop table t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+e varchar(255) character set utf8,
+key (a,b,c,d,e)) engine=innodb;
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+insert into t1 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t2 values (0x41),(0x4120);
+insert into t3 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A ' for key 'PRIMARY'
+insert into t3 values (0x41),(0x4100);
+insert into t4 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+hex(s1)
+41
+4100
+4120
+select hex(s1) from t2;
+hex(s1)
+4100
+4120
+select hex(s1) from t3;
+hex(s1)
+4100
+41
+select hex(s1) from t4;
+hex(s1)
+4100
+41
+drop table t1,t2,t3,t4;
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+insert into t2 values(0x42);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x12 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x12345678 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x123457 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1220
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1200
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+4200
+delete from t1 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+a hex(s1)
+3 4120
+select hex(s1) from t2;
+hex(s1)
+4120
+drop table t2,t1;
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+hex(s1)
+12
+delete from t1 where a=1;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+select a,hex(s1) from t1;
+a hex(s1)
+2 12
+select hex(s1) from t2;
+hex(s1)
+12
+drop table t2,t1;
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ KEY `t2_ibfk_0` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2,t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+set autocommit = 0;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+commit;
+commit;
+drop trigger t1t;
+drop table t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+create trigger t1t before insert on t1 for each row begin
+INSERT INTO t2 SET a = NEW.a;
+end |
+create trigger t2t before insert on t2 for each row begin
+DELETE FROM t3 WHERE a = NEW.a;
+end |
+create trigger t3t before delete on t3 for each row begin
+UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+create trigger t4t before update on t4 for each row begin
+UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
+CREATE TABLE t1 (
+field1 varchar(8) NOT NULL DEFAULT '',
+field2 varchar(8) NOT NULL DEFAULT '',
+PRIMARY KEY (field1, field2)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
+FOREIGN KEY (field1) REFERENCES t1 (field1)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('old', 'somevalu');
+INSERT INTO t1 VALUES ('other', 'anyvalue');
+INSERT INTO t2 VALUES ('old');
+INSERT INTO t2 VALUES ('other');
+UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
+ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
+DROP TABLE t2;
+DROP TABLE t1;
+create table t1 (
+c1 bigint not null,
+c2 bigint not null,
+primary key (c1),
+unique key (c2)
+) engine=innodb;
+create table t2 (
+c1 bigint not null,
+primary key (c1)
+) engine=innodb;
+alter table t1 add constraint c2_fk foreign key (c2)
+references t2(c1) on delete cascade;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`),
+ CONSTRAINT `c2_fk` FOREIGN KEY (`c2`) REFERENCES `t2` (`c1`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 drop foreign key c2_fk;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2;
+create table t1(a date) engine=innodb;
+create table t2(a date, key(a)) engine=innodb;
+insert into t1 values('2005-10-01');
+insert into t2 values('2005-10-01');
+select * from t1, t2
+where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
+a a
+2005-10-01 2005-10-01
+drop table t1, t2;
+create table t1 (id int not null, f_id int not null, f int not null,
+primary key(f_id, id)) engine=innodb;
+create table t2 (id int not null,s_id int not null,s varchar(200),
+primary key(id)) engine=innodb;
+INSERT INTO t1 VALUES (8, 1, 3);
+INSERT INTO t1 VALUES (1, 2, 1);
+INSERT INTO t2 VALUES (1, 0, '');
+INSERT INTO t2 VALUES (8, 1, '');
+commit;
+DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
+WHERE mm.id IS NULL;
+select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
+where mm.id is null lock in share mode;
+id f_id f
+drop table t1,t2;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t1 set b = 5 where b = 1;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+select * from t1 where a = 7 and b = 3 for update;
+a b
+7 3
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
+commit;
+set autocommit = 0;
+select * from t1 lock in share mode;
+a b
+1 1
+2 2
+3 1
+4 2
+5 1
+6 2
+update t1 set b = 5 where b = 1;
+set autocommit = 0;
+select * from t1 where a = 2 and b = 2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(d int not null, e int, primary key(d)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+d e
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t1 select * from t2;
+update t1 set b = (select e from t2 where a = d);
+create table t3(d int not null, e int, primary key(d)) engine=innodb
+select * from t2;
+commit;
+commit;
+drop table t1, t2, t3;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(a int not null, b int, primary key(a)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+create table t3(d int not null, b int, primary key(d)) engine=innodb;
+insert into t3 values (8,6),(12,1),(3,1);
+create table t5(a int not null, b int, primary key(a)) engine=innodb;
+insert into t5 values (1,2),(5,3),(4,2);
+create table t6(d int not null, e int, primary key(d)) engine=innodb;
+insert into t6 values (8,6),(12,1),(3,1);
+create table t8(a int not null, b int, primary key(a)) engine=innodb;
+insert into t8 values (1,2),(5,3),(4,2);
+create table t9(d int not null, e int, primary key(d)) engine=innodb;
+insert into t9 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+a b
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+insert into t1 select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+update t3 set b = (select b from t2 where a = d);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t5 (select * from t2 lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t6 set e = (select b from t2 where a = d lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t8 (select * from t2 for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t9 set e = (select b from t2 where a = d for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t1, t2, t3, t5, t6, t8, t9;
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
+CREATE TABLE t1 (
+a BIGINT(20) NOT NULL,
+PRIMARY KEY (a)
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+CREATE TABLE t2 (
+a BIGINT(20) NOT NULL,
+b VARCHAR(128) NOT NULL,
+c TEXT NOT NULL,
+PRIMARY KEY (a,b),
+KEY idx_t2_b_c (b,c(200)),
+CONSTRAINT t_fk FOREIGN KEY (a) REFERENCES t1 (a)
+ON DELETE CASCADE
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1, 'bar', 'vbar');
+INSERT INTO t2 VALUES (1, 'BAR2', 'VBAR');
+INSERT INTO t2 VALUES (1, 'bar_bar', 'bibi');
+INSERT INTO t2 VALUES (1, 'customer_over', '1');
+SELECT * FROM t2 WHERE b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT * FROM t2 WHERE BINARY b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT DISTINCT p0.a FROM t2 p0 WHERE p0.b = 'customer_over';
+a
+1
+/* Bang: Empty result set, above was expected: */
+SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+drop table t2, t1;
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
+CREATE TABLE t2 (id int PRIMARY KEY, f INT NOT NULL,
+CONSTRAINT t2_t1 FOREIGN KEY (id) REFERENCES t1 (id)
+ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (f) REFERENCES t1 (f) ON
+DELETE CASCADE ON UPDATE CASCADE;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `f` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `f` (`f`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f`) REFERENCES `t1` (`f`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2, t1;
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
+DELETE FROM t1;
+DROP TABLE t2,t1;
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+a
+DDD
+DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+id
+42
+347
+348
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+DROP TABLE t1,t2;
+SET innodb_strict_mode=ON;
+CREATE TABLE t1 (
+c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
+c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
+c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
+c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
+c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
+c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
+c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
+c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
+) ENGINE = InnoDB;
+ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
+SET innodb_strict_mode=OFF;
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1(
+id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(-10);
+SELECT * FROM t1;
+id
+-10
+INSERT INTO t1 VALUES(NULL);
+SELECT * FROM t1;
+id
+-10
+1
+DROP TABLE t1;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+SELECT * FROM t1 WHERE a=1;
+a
+1
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+SELECT * FROM t1 WHERE a=2;
+a
+2
+SELECT * FROM t1 WHERE a=2;
+a
+2
+DROP TABLE t1;
+DROP TABLE t2;
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+update t1 set j = 2;
+affected rows: 1
+info: Rows matched: 2 Changed: 1 Warnings: 0
+drop table t1;
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+from information_schema.tables
+where table_schema='test' and table_name = 't1';
+table_comment data_free_is_set
+this is a comment 1
+drop table t1;
+CREATE TABLE t1 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 VARCHAR(128) NOT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+CREATE TABLE t2 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 INT(10) UNSIGNED DEFAULT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 int default NULL,
+c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+TRUNCATE TABLE t1;
+affected rows: 0
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+affected rows: 5
+info: Records: 5 Duplicates: 0 Warnings: 0
+TRUNCATE TABLE t1;
+affected rows: 0
+DROP TABLE t1;
+Variable_name Value
+Handler_update 0
+Variable_name Value
+Handler_delete 0
+Variable_name Value
+Handler_update 1
+Variable_name Value
+Handler_delete 1
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 69876297797..0b0e746bf2f 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1046,6 +1046,24 @@ update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
drop table t3,t2,t1;
+# test ON UPDATE CASCADE
+CREATE TABLE t1 (
+ c1 VARCHAR(8), c2 VARCHAR(8),
+ PRIMARY KEY (c1, c2)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ c0 INT PRIMARY KEY,
+ c1 VARCHAR(8) UNIQUE,
+ FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue');
+INSERT INTO t2 VALUES (10, 'old'), (20, 'other');
+-- error ER_FOREIGN_DUPLICATE_KEY
+UPDATE t1 SET c1 = 'other' WHERE c1 = 'old';
+DROP TABLE t2,t1;
+
#
# test for recursion depth limit
#
diff --git a/mysql-test/suite/innodb/t/innodb_bug12661768.test b/mysql-test/suite/innodb/t/innodb_bug12661768.test
new file mode 100644
index 00000000000..01549a7e9e9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug12661768.test
@@ -0,0 +1,50 @@
+#
+# Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB AND IT IS
+# PARENT FOR OTHER ONE
+#
+
+-- source include/have_innodb.inc
+
+SET SESSION foreign_key_checks=0;
+
+# only interested that the "UPDATE IGNORE" at the end does not crash the server
+
+-- disable_query_log
+-- disable_result_log
+
+SET NAMES utf8;
+
+-- let $t1_name = bug12661768_1
+-- let $t2_name = bug12661768_2
+-- let $fk_name = ab_on_2
+-- let $key_str = 'bbb'
+
+eval DROP TABLE IF EXISTS `$t2_name`, `$t1_name`;
+
+eval CREATE TABLE `$t1_name` (
+ a INT,
+ b VARCHAR(512),
+ PRIMARY KEY (a, b)
+) ENGINE=INNODB;
+
+eval CREATE TABLE `$t2_name` (
+ id INT,
+ a INT,
+ b VARCHAR(512),
+ PRIMARY KEY (id),
+ UNIQUE KEY `$fk_name` (a, b),
+ FOREIGN KEY (a, b) REFERENCES `$t1_name` (a, b)
+ ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=INNODB;
+
+eval INSERT INTO `$t1_name` VALUES (1, $key_str);
+eval INSERT INTO `$t2_name` VALUES (100, 1, $key_str), (101, 3, $key_str);
+
+SET SESSION foreign_key_checks=1;
+
+-- enable_result_log
+
+-- error ER_FOREIGN_DUPLICATE_KEY
+eval UPDATE IGNORE `$t1_name` SET a = 3;
+
+eval DROP TABLE `$t2_name`, `$t1_name`;
diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test
index a6722ed6399..0bbd7da0065 100644
--- a/mysql-test/suite/innodb/t/innodb_bug54044.test
+++ b/mysql-test/suite/innodb/t/innodb_bug54044.test
@@ -3,9 +3,17 @@
--source include/have_innodb.inc
-# This 'create table' operation should fail because of
-# using NULL datatype
---error ER_CANT_CREATE_TABLE
+# This 'create table' operation no longer uses the NULL datatype.
+
CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB
AS SELECT IF(NULL IS NOT NULL, NULL, NULL);
+SHOW CREATE TABLE table_54044;
+DROP TABLE table_54044;
+# These 'create table' operations should fail because of
+# using NULL datatype
+
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE tmp ENGINE = INNODB AS SELECT COALESCE(NULL, NULL, NULL);
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE tmp ENGINE = INNODB AS SELECT GREATEST(NULL, NULL);
diff --git a/mysql-test/suite/innodb/t/innodb_misc1-master.opt b/mysql-test/suite/innodb/t/innodb_misc1-master.opt
new file mode 100644
index 00000000000..4901efb416c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_misc1-master.opt
@@ -0,0 +1 @@
+--binlog_cache_size=32768 --innodb_lock_wait_timeout=1
diff --git a/mysql-test/suite/innodb/t/innodb_misc1.test b/mysql-test/suite/innodb/t/innodb_misc1.test
new file mode 100644
index 00000000000..c33f4bd8074
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_misc1.test
@@ -0,0 +1,1184 @@
+-- source include/have_innodb.inc
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+# Save the original values of some variables in order to be able to
+# estimate how much they have changed during the tests. Previously this
+# test assumed that e.g. rows_deleted is 0 here and after deleting 23
+# rows it expected that rows_deleted will be 23. Now we do not make
+# assumptions about the values of the variables at the beginning, e.g.
+# rows_deleted should be 23 + "rows_deleted before the test". This allows
+# the test to be run multiple times without restarting the mysqld server.
+# See Bug#43309 Test main.innodb can't be run twice
+-- disable_query_log
+SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency;
+-- enable_query_log
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
+--enable_warnings
+
+# InnoDB specific varchar tests
+create table t1 (v varchar(16384)) engine=innodb;
+drop table t1;
+
+#
+# BUG#11039 Wrong key length in min()
+#
+
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+select min(b) from t1 where a='8';
+drop table t1;
+
+#
+# Bug #11080 & #11005 Multi-row REPLACE fails on a duplicate key error
+#
+
+CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2), (1), (3);
+select * from t1;
+truncate table t1;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2);
+replace into t1 (b) values (1);
+replace into t1 (b) values (3);
+select * from t1;
+drop table t1;
+
+create table t1 (rowid int not null auto_increment, val int not null,primary
+key (rowid), unique(val)) engine=innodb;
+replace into t1 (val) values ('1'),('2');
+replace into t1 (val) values ('1'),('2');
+--error ER_DUP_ENTRY
+insert into t1 (val) values ('1'),('2');
+select * from t1;
+drop table t1;
+
+#
+# Test that update does not change internal auto-increment value
+#
+
+create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB;
+insert into t1 (val) values (1);
+update t1 set a=2 where a=1;
+# We should get the following error because InnoDB does not update the counter
+--error ER_DUP_ENTRY
+insert into t1 (val) values (1);
+select * from t1;
+drop table t1;
+#
+# Bug #10465
+#
+
+--disable_warnings
+CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB;
+--enable_warnings
+INSERT INTO t1 (GRADE) VALUES (151),(252),(343);
+SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300;
+SELECT GRADE FROM t1 WHERE GRADE= 151;
+DROP TABLE t1;
+
+#
+# Bug #12340 multitable delete deletes only one record
+#
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+drop table t1,t2;
+
+#
+# Test that the slow TRUNCATE implementation resets autoincrement columns
+# (bug #11946)
+#
+
+CREATE TABLE t1 (
+id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+id INTEGER NOT NULL,
+FOREIGN KEY (id) REFERENCES t1 (id)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+--error ER_TRUNCATE_ILLEGAL_FK
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+
+# continued from above; test that doing a slow TRUNCATE on a table with 0
+# rows resets autoincrement columns
+DELETE FROM t1;
+--error ER_TRUNCATE_ILLEGAL_FK
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+DROP TABLE t2, t1;
+
+# Test that foreign keys in temporary tables are not accepted (bug #12084)
+CREATE TABLE t1
+(
+ id INT PRIMARY KEY
+) ENGINE=InnoDB;
+
+--error 1005,1005
+CREATE TEMPORARY TABLE t2
+(
+ id INT NOT NULL PRIMARY KEY,
+ b INT,
+ FOREIGN KEY (b) REFERENCES test.t1(id)
+) ENGINE=InnoDB;
+DROP TABLE t1;
+
+#
+# Test that index column max sizes are honored (bug #13315)
+#
+
+# prefix index
+create table t1 (col1 varchar(2000), index (col1(767)))
+ character set = latin1 engine = innodb;
+
+# normal indexes
+create table t2 (col1 char(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+ character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+ character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+ character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+ character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+ character set = latin1 engine = innodb;
+
+# multi-column indexes are allowed to be longer
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+ character set = latin1 engine = innodb;
+
+show create table t9;
+
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+
+# these should have their index length trimmed
+create table t1 (col1 varchar(768), index(col1))
+ character set = latin1 engine = innodb;
+create table t2 (col1 varbinary(768), index(col1))
+ character set = latin1 engine = innodb;
+create table t3 (col1 text, index(col1(768)))
+ character set = latin1 engine = innodb;
+create table t4 (col1 blob, index(col1(768)))
+ character set = latin1 engine = innodb;
+
+show create table t1;
+
+drop table t1, t2, t3, t4;
+
+# these should be refused
+--error 1071
+create table t1 (col1 varchar(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1071
+create table t2 (col1 varbinary(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1071
+create table t3 (col1 text, primary key(col1(768)))
+ character set = latin1 engine = innodb;
+--error 1071
+create table t4 (col1 blob, primary key(col1(768)))
+ character set = latin1 engine = innodb;
+
+#
+# Test improved foreign key error messages (bug #3443)
+#
+
+CREATE TABLE t1
+(
+ id INT PRIMARY KEY
+) ENGINE=InnoDB;
+
+CREATE TABLE t2
+(
+ v INT,
+ CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+
+--error 1452
+INSERT INTO t2 VALUES(2);
+
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+
+--error 1451
+DELETE FROM t1 WHERE id = 1;
+
+--error 1217
+DROP TABLE t1;
+
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+
+--error 1452
+INSERT INTO t2 VALUES(3);
+
+DROP TABLE t2;
+#
+# Test that checksum table uses a consistent read Bug #12669
+#
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+connection b;
+insert into t1 values(3);
+connection a;
+#
+# Here checksum should not see insert
+#
+checksum table t1;
+connection a;
+commit;
+checksum table t1;
+commit;
+drop table t1;
+#
+# autocommit = 1
+#
+connection a;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+connection b;
+set autocommit=1;
+insert into t1 values(3);
+connection a;
+#
+# Here checksum sees insert
+#
+checksum table t1;
+drop table t1;
+
+connection default;
+disconnect a;
+disconnect b;
+
+# tests for bugs #9802 and #13778
+
+# test that FKs between invalid types are not accepted
+
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+-- error 1005
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+set foreign_key_checks=1;
+drop table t2;
+
+# test that FKs between different charsets are not accepted in CREATE even
+# when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ ''
+-- error 1005
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+set foreign_key_checks=1;
+drop table t1;
+
+# test that invalid datatype conversions with ALTER are not allowed
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+-- error 1025,1025
+alter table t1 modify column a int;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that charset conversions with ALTER are allowed when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+
+# test that RENAME does not allow invalid charsets when f_k_c is 0
+
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLD_DATADIR ./ master-data/ ''
+-- error 1025
+rename table t3 to t1;
+set foreign_key_checks=1;
+drop table t2,t3;
+
+# test that foreign key errors are reported correctly (Bug #15550)
+
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+
+insert into t1 values(1);
+insert into t3 values(1);
+-- error 1452
+insert into t2 values(2);
+-- error 1452
+insert into t4 values(2);
+insert into t2 values(1);
+insert into t4 values(1);
+-- error 1451
+update t1 set a=2;
+-- error 1452
+update t2 set a=2;
+-- error 1451
+update t3 set a=2;
+-- error 1452
+update t4 set a=2;
+--error ER_TRUNCATE_ILLEGAL_FK
+truncate t1;
+--error ER_TRUNCATE_ILLEGAL_FK
+truncate t3;
+truncate t2;
+truncate t4;
+--error ER_TRUNCATE_ILLEGAL_FK
+truncate t1;
+--error ER_TRUNCATE_ILLEGAL_FK
+truncate t3;
+
+drop table t4,t3,t2,t1;
+
+
+#
+# Test that we can create a large (>1K) key
+#
+create table t1 (a varchar(255) character set utf8,
+ b varchar(255) character set utf8,
+ c varchar(255) character set utf8,
+ d varchar(255) character set utf8,
+ key (a,b,c,d)) engine=innodb;
+drop table t1;
+--error ER_TOO_LONG_KEY
+create table t1 (a varchar(255) character set utf8,
+ b varchar(255) character set utf8,
+ c varchar(255) character set utf8,
+ d varchar(255) character set utf8,
+ e varchar(255) character set utf8,
+ key (a,b,c,d,e)) engine=innodb;
+
+
+# test the padding of BINARY types and collations (Bug #14189)
+
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+
+insert into t1 values (0x41),(0x4120),(0x4100);
+-- error ER_DUP_ENTRY
+insert into t2 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120);
+-- error ER_DUP_ENTRY
+insert into t3 values (0x41),(0x4120),(0x4100);
+insert into t3 values (0x41),(0x4100);
+-- error ER_DUP_ENTRY
+insert into t4 values (0x41),(0x4120),(0x4100);
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+select hex(s1) from t2;
+select hex(s1) from t3;
+select hex(s1) from t4;
+drop table t1,t2,t3,t4;
+
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+-- error 1452
+insert into t2 values(0x42);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+-- error 1451
+update t1 set s1=0x12 where a=1;
+-- error 1451
+update t1 set s1=0x12345678 where a=1;
+-- error 1451
+update t1 set s1=0x123457 where a=1;
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+-- error 1451
+delete from t1 where a=1;
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+-- error 1451
+delete from t1;
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
+
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+delete from t1 where a=1;
+-- error 1451
+delete from t1 where a=2;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
+# Ensure that <tablename>_ibfk_0 is not mistreated as a
+# generated foreign key identifier. (Bug #16387)
+
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+DROP TABLE t2,t1;
+
+#
+# Test case for bug #16229: MySQL/InnoDB uses full explicit table locks in trigger processing
+#
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+delimiter |;
+# in 5.5+, this needs to be created before the UPDATE due to meta-data locking
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+delimiter ;|
+connection b;
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+connection a;
+set autocommit = 0;
+connection a;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+connection b;
+commit;
+connection a;
+commit;
+drop trigger t1t;
+drop table t1;
+disconnect a;
+disconnect b;
+#
+# Another trigger test
+#
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+
+delimiter |;
+create trigger t1t before insert on t1 for each row begin
+ INSERT INTO t2 SET a = NEW.a;
+end |
+
+create trigger t2t before insert on t2 for each row begin
+ DELETE FROM t3 WHERE a = NEW.a;
+end |
+
+create trigger t3t before delete on t3 for each row begin
+ UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+
+create trigger t4t before update on t4 for each row begin
+ UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+delimiter ;|
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+connection b;
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+connection a;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
+connection default;
+disconnect a;
+disconnect b;
+
+#
+# Test that cascading updates leading to duplicate keys give the correct
+# error message (bug #9680)
+#
+
+CREATE TABLE t1 (
+ field1 varchar(8) NOT NULL DEFAULT '',
+ field2 varchar(8) NOT NULL DEFAULT '',
+ PRIMARY KEY (field1, field2)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
+ FOREIGN KEY (field1) REFERENCES t1 (field1)
+ ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES ('old', 'somevalu');
+INSERT INTO t1 VALUES ('other', 'anyvalue');
+
+INSERT INTO t2 VALUES ('old');
+INSERT INTO t2 VALUES ('other');
+
+--error ER_FOREIGN_DUPLICATE_KEY
+UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
+
+DROP TABLE t2;
+DROP TABLE t1;
+
+#
+# Bug#18477 - MySQL/InnoDB Ignoring Foreign Keys in ALTER TABLE
+#
+create table t1 (
+ c1 bigint not null,
+ c2 bigint not null,
+ primary key (c1),
+ unique key (c2)
+) engine=innodb;
+#
+create table t2 (
+ c1 bigint not null,
+ primary key (c1)
+) engine=innodb;
+#
+alter table t1 add constraint c2_fk foreign key (c2)
+ references t2(c1) on delete cascade;
+show create table t1;
+#
+alter table t1 drop foreign key c2_fk;
+show create table t1;
+#
+drop table t1, t2;
+
+#
+# Bug #14360: problem with intervals
+#
+
+create table t1(a date) engine=innodb;
+create table t2(a date, key(a)) engine=innodb;
+insert into t1 values('2005-10-01');
+insert into t2 values('2005-10-01');
+select * from t1, t2
+ where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
+drop table t1, t2;
+
+create table t1 (id int not null, f_id int not null, f int not null,
+primary key(f_id, id)) engine=innodb;
+create table t2 (id int not null,s_id int not null,s varchar(200),
+primary key(id)) engine=innodb;
+INSERT INTO t1 VALUES (8, 1, 3);
+INSERT INTO t1 VALUES (1, 2, 1);
+INSERT INTO t2 VALUES (1, 0, '');
+INSERT INTO t2 VALUES (8, 1, '');
+commit;
+DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
+WHERE mm.id IS NULL;
+select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
+where mm.id is null lock in share mode;
+drop table t1,t2;
+
+#
+# Test case where X-locks on unused rows should be released in a
+# update (because READ COMMITTED isolation level)
+#
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t1 set b = 5 where b = 1;
+connection b;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+#
+# X-lock to record (7,3) should be released in a update
+#
+select * from t1 where a = 7 and b = 3 for update;
+connection a;
+commit;
+connection b;
+commit;
+drop table t1;
+connection default;
+disconnect a;
+disconnect b;
+
+#
+# Test case where no locks should be released (because we are not
+# using READ COMMITTED isolation level)
+#
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
+commit;
+set autocommit = 0;
+select * from t1 lock in share mode;
+update t1 set b = 5 where b = 1;
+connection b;
+set autocommit = 0;
+#
+# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
+#
+--error 1205
+select * from t1 where a = 2 and b = 2 for update;
+#
+# X-lock to record (1,1),(3,1),(5,1) should not be released in a update
+#
+--error 1205
+connection a;
+commit;
+connection b;
+commit;
+connection default;
+disconnect a;
+disconnect b;
+drop table t1;
+
+#
+# Consistent read should be used in following selects
+#
+# 1) INSERT INTO ... SELECT
+# 2) UPDATE ... = ( SELECT ...)
+# 3) CREATE ... SELECT
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(d int not null, e int, primary key(d)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+connection b;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t1 select * from t2;
+update t1 set b = (select e from t2 where a = d);
+create table t3(d int not null, e int, primary key(d)) engine=innodb
+select * from t2;
+commit;
+connection a;
+commit;
+connection default;
+disconnect a;
+disconnect b;
+drop table t1, t2, t3;
+
+#
+# Consistent read should not be used if
+#
+# (a) isolation level is serializable OR
+# (b) select ... lock in share mode OR
+# (c) select ... for update
+#
+# in following queries:
+#
+# 1) INSERT INTO ... SELECT
+# 2) UPDATE ... = ( SELECT ...)
+# 3) CREATE ... SELECT
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connect (c,localhost,root,,);
+connect (d,localhost,root,,);
+connect (e,localhost,root,,);
+connect (f,localhost,root,,);
+connect (g,localhost,root,,);
+connect (h,localhost,root,,);
+connect (i,localhost,root,,);
+connect (j,localhost,root,,);
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(a int not null, b int, primary key(a)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+create table t3(d int not null, b int, primary key(d)) engine=innodb;
+insert into t3 values (8,6),(12,1),(3,1);
+create table t5(a int not null, b int, primary key(a)) engine=innodb;
+insert into t5 values (1,2),(5,3),(4,2);
+create table t6(d int not null, e int, primary key(d)) engine=innodb;
+insert into t6 values (8,6),(12,1),(3,1);
+create table t8(a int not null, b int, primary key(a)) engine=innodb;
+insert into t8 values (1,2),(5,3),(4,2);
+create table t9(d int not null, e int, primary key(d)) engine=innodb;
+insert into t9 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+connection b;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+--send
+insert into t1 select * from t2;
+connection c;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+--send
+update t3 set b = (select b from t2 where a = d);
+connection d;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+--send
+create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
+connection e;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+insert into t5 (select * from t2 lock in share mode);
+connection f;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+update t6 set e = (select b from t2 where a = d lock in share mode);
+connection g;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
+connection h;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+insert into t8 (select * from t2 for update);
+connection i;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+update t9 set e = (select b from t2 where a = d for update);
+connection j;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+--send
+create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
+
+connection b;
+--error 1205
+reap;
+
+connection c;
+--error 1205
+reap;
+
+connection d;
+--error 1205
+reap;
+
+connection e;
+--error 1205
+reap;
+
+connection f;
+--error 1205
+reap;
+
+connection g;
+--error 1205
+reap;
+
+connection h;
+--error 1205
+reap;
+
+connection i;
+--error 1205
+reap;
+
+connection j;
+--error 1205
+reap;
+
+connection a;
+commit;
+
+connection default;
+disconnect a;
+disconnect b;
+disconnect c;
+disconnect d;
+disconnect e;
+disconnect f;
+disconnect g;
+disconnect h;
+disconnect i;
+disconnect j;
+drop table t1, t2, t3, t5, t6, t8, t9;
+
+# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
+--error ER_WRONG_COLUMN_NAME
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+
+#
+# Bug #17152: Wrong result with BINARY comparison on aliased column
+#
+
+CREATE TABLE t1 (
+ a BIGINT(20) NOT NULL,
+ PRIMARY KEY (a)
+ ) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+
+CREATE TABLE t2 (
+ a BIGINT(20) NOT NULL,
+ b VARCHAR(128) NOT NULL,
+ c TEXT NOT NULL,
+ PRIMARY KEY (a,b),
+ KEY idx_t2_b_c (b,c(200)),
+ CONSTRAINT t_fk FOREIGN KEY (a) REFERENCES t1 (a)
+ ON DELETE CASCADE
+ ) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1, 'bar', 'vbar');
+INSERT INTO t2 VALUES (1, 'BAR2', 'VBAR');
+INSERT INTO t2 VALUES (1, 'bar_bar', 'bibi');
+INSERT INTO t2 VALUES (1, 'customer_over', '1');
+
+SELECT * FROM t2 WHERE b = 'customer_over';
+SELECT * FROM t2 WHERE BINARY b = 'customer_over';
+SELECT DISTINCT p0.a FROM t2 p0 WHERE p0.b = 'customer_over';
+/* Bang: Empty result set, above was expected: */
+SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+
+drop table t2, t1;
+
+#
+# Test optimize on table with open transaction
+#
+
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+DROP TABLE t1;
+
+#
+# Bug #24741 (existing cascade clauses disappear when adding foreign keys)
+#
+
+CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
+
+CREATE TABLE t2 (id int PRIMARY KEY, f INT NOT NULL,
+ CONSTRAINT t2_t1 FOREIGN KEY (id) REFERENCES t1 (id)
+ ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
+
+ALTER TABLE t2 ADD FOREIGN KEY (f) REFERENCES t1 (f) ON
+DELETE CASCADE ON UPDATE CASCADE;
+
+SHOW CREATE TABLE t2;
+DROP TABLE t2, t1;
+
+#
+# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns
+# for which there is a foreign key constraint ON ... SET NULL.
+#
+
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+# mysqltest first does replace_regex, then replace_result
+--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+# Embedded server doesn't chdir to data directory
+--replace_result $MYSQLD_DATADIR ./ master-data/ ''
+--error 1025
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+DELETE FROM t1;
+DROP TABLE t2,t1;
+
+#
+# Bug #26835: table corruption after delete+insert
+#
+
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+#
+# Bug #23313 (AUTO_INCREMENT=# not reported back for InnoDB tables)
+# Bug #21404 (AUTO_INCREMENT value reset when Adding FKEY (or ALTER?))
+#
+
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t1;
+
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1,t2;
+
+#
+# Bug #21101 (Prints wrong error message if max row size is too large)
+#
+SET innodb_strict_mode=ON;
+--error 1118
+CREATE TABLE t1 (
+ c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
+ c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
+ c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
+ c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
+ c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
+ c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
+ c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
+ c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
+ ) ENGINE = InnoDB;
+SET innodb_strict_mode=OFF;
+
+#
+# Bug #31860 InnoDB assumes AUTOINC values can only be positive.
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(
+ id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY
+ ) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(-10);
+SELECT * FROM t1;
+#
+# NOTE: The server really needs to be restarted at this point
+# for the test to be useful.
+#
+# Without the fix InnoDB would trip over an assertion here.
+INSERT INTO t1 VALUES(NULL);
+# The next value should be 1 and not -9 or a -ve number
+SELECT * FROM t1;
+DROP TABLE t1;
+
+#
+# Bug #21409 Incorrect result returned when in READ-COMMITTED with
+# query_cache ON
+#
+CONNECT (c1,localhost,root,,);
+CONNECT (c2,localhost,root,,);
+CONNECTION c1;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+CONNECTION c2;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+CONNECTION c1;
+SELECT * FROM t1 WHERE a=1;
+DISCONNECT c1;
+DISCONNECT c2;
+CONNECT (c1,localhost,root,,);
+CONNECT (c2,localhost,root,,);
+CONNECTION c1;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+CONNECTION c2;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+CONNECTION c1;
+# The result set below should be the same for both selects
+SELECT * FROM t1 WHERE a=2;
+SELECT * FROM t1 WHERE a=2;
+DROP TABLE t1;
+DROP TABLE t2;
+DISCONNECT c1;
+DISCONNECT c2;
+CONNECTION default;
+
+#
+# Bug #29157 UPDATE, changed rows incorrect
+#
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+--enable_info
+update t1 set j = 2;
+--disable_info
+drop table t1;
+
+#
+# Bug #32440 InnoDB free space info does not appear in SHOW TABLE STATUS or
+# I_S
+#
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+ from information_schema.tables
+ where table_schema='test' and table_name = 't1';
+drop table t1;
+
+#
+# Bug 34920 test
+#
+CONNECTION default;
+CREATE TABLE t1 (
+ c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ c2 VARCHAR(128) NOT NULL,
+ PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+
+CREATE TABLE t2 (
+ c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ c2 INT(10) UNSIGNED DEFAULT NULL,
+ PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+DROP TABLE t2;
+DROP TABLE t1;
+# End 34920 test
+#
+# Bug #29507 TRUNCATE shows to many rows effected
+#
+CONNECTION default;
+CREATE TABLE t1 (c1 int default NULL,
+ c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--enable_info
+TRUNCATE TABLE t1;
+
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+TRUNCATE TABLE t1;
+
+--disable_info
+DROP TABLE t1;
+#
+# Bug#35537 Innodb doesn't increment handler_update and handler_delete.
+#
+-- disable_query_log
+-- disable_result_log
+
+CONNECT (c1,localhost,root,,);
+
+DROP TABLE IF EXISTS bug35537;
+CREATE TABLE bug35537 (
+ c1 int
+) ENGINE=InnoDB;
+
+INSERT INTO bug35537 VALUES (1);
+
+-- enable_result_log
+
+SHOW SESSION STATUS LIKE 'Handler_update%';
+SHOW SESSION STATUS LIKE 'Handler_delete%';
+
+UPDATE bug35537 SET c1 = 2 WHERE c1 = 1;
+DELETE FROM bug35537 WHERE c1 = 2;
+
+SHOW SESSION STATUS LIKE 'Handler_update%';
+SHOW SESSION STATUS LIKE 'Handler_delete%';
+
+DROP TABLE bug35537;
+
+DISCONNECT c1;
+CONNECTION default;
+
+SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
diff --git a/mysql-test/suite/parts/r/partition_debug_innodb.result b/mysql-test/suite/parts/r/partition_debug_innodb.result
index 49d863bca8e..bae4faf434e 100644
--- a/mysql-test/suite/parts/r/partition_debug_innodb.result
+++ b/mysql-test/suite/parts/r/partition_debug_innodb.result
@@ -1,4 +1,75 @@
DROP TABLE IF EXISTS t1;
+#
+# Bug#12696518/Bug#11766879/60106:DIFF BETWEEN # OF INDEXES IN MYSQL
+# VS INNODB, PARTITONING, ON INDEX CREATE
+#
+CREATE TABLE t1
+(a INT PRIMARY KEY,
+b VARCHAR(64))
+ENGINE = InnoDB
+PARTITION BY HASH (a) PARTITIONS 3;
+INSERT INTO t1 VALUES (0, 'first row'), (1, 'second row'), (2, 'Third row');
+INSERT INTO t1 VALUES (3, 'row id 3'), (4, '4 row'), (5, 'row5');
+INSERT INTO t1 VALUES (6, 'X 6 row'), (7, 'Seventh row'), (8, 'Last row');
+ALTER TABLE t1 ADD INDEX new_b_index (b);
+ALTER TABLE t1 DROP INDEX new_b_index;
+SET SESSION debug= "+d,ha_partition_fail_final_add_index";
+ALTER TABLE t1 ADD INDEX (b);
+ERROR HY000: Table has no partition for value 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(64) DEFAULT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (a)
+PARTITIONS 3 */
+SELECT * FROM t1;
+a b
+0 first row
+1 second row
+2 Third row
+3 row id 3
+4 4 row
+5 row5
+6 X 6 row
+7 Seventh row
+8 Last row
+FLUSH TABLES;
+CREATE INDEX new_index ON t1 (b);
+ERROR HY000: Table has no partition for value 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(64) DEFAULT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (a)
+PARTITIONS 3 */
+SELECT * FROM t1;
+a b
+0 first row
+1 second row
+2 Third row
+3 row id 3
+4 4 row
+5 row5
+6 X 6 row
+7 Seventh row
+8 Last row
+SET SESSION debug= "-d,ha_partition_fail_final_add_index";
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `b` varchar(64) DEFAULT NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (a)
+PARTITIONS 3 */
+DROP TABLE t1;
call mtr.add_suppression("InnoDB: Warning: allocated tablespace .*, old maximum was");
call mtr.add_suppression("InnoDB: Error: table .* does not exist in the InnoDB internal");
call mtr.add_suppression("InnoDB: Warning: MySQL is trying to drop table ");
diff --git a/mysql-test/suite/parts/t/partition_debug_innodb.test b/mysql-test/suite/parts/t/partition_debug_innodb.test
index c5d8df33213..b546f6d73f8 100644
--- a/mysql-test/suite/parts/t/partition_debug_innodb.test
+++ b/mysql-test/suite/parts/t/partition_debug_innodb.test
@@ -12,6 +12,41 @@ DROP TABLE IF EXISTS t1;
--let $DATADIR= `SELECT @@datadir;`
+--echo #
+--echo # Bug#12696518/Bug#11766879/60106:DIFF BETWEEN # OF INDEXES IN MYSQL
+--echo # VS INNODB, PARTITONING, ON INDEX CREATE
+--echo #
+CREATE TABLE t1
+(a INT PRIMARY KEY,
+ b VARCHAR(64))
+ENGINE = InnoDB
+PARTITION BY HASH (a) PARTITIONS 3;
+INSERT INTO t1 VALUES (0, 'first row'), (1, 'second row'), (2, 'Third row');
+INSERT INTO t1 VALUES (3, 'row id 3'), (4, '4 row'), (5, 'row5');
+INSERT INTO t1 VALUES (6, 'X 6 row'), (7, 'Seventh row'), (8, 'Last row');
+
+ALTER TABLE t1 ADD INDEX new_b_index (b);
+ALTER TABLE t1 DROP INDEX new_b_index;
+
+SET SESSION debug= "+d,ha_partition_fail_final_add_index";
+
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+ALTER TABLE t1 ADD INDEX (b);
+SHOW CREATE TABLE t1;
+--sorted_result
+SELECT * FROM t1;
+
+FLUSH TABLES;
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+CREATE INDEX new_index ON t1 (b);
+SHOW CREATE TABLE t1;
+--sorted_result
+SELECT * FROM t1;
+
+SET SESSION debug= "-d,ha_partition_fail_final_add_index";
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
# Checking with #innodb what this is...
call mtr.add_suppression("InnoDB: Warning: allocated tablespace .*, old maximum was");
# If there is a crash or failure between the ddl_log is written and the
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index 91f70bb98d7..41115a2da30 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -177,3 +177,15 @@ INSERT INTO t1 VALUES (NULL, 0), (NULL, 1);
SELECT IF(b, (SELECT a FROM t1 LIMIT 1), b) c FROM t1 GROUP BY c;
DROP TABLE t1;
+
+--echo #
+--echo # Bug#12532830
+--echo # SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
+--echo #
+
+let $nines= 9999999999999999999999999999999999999;
+eval select
+sum(distinct(if('a',
+ (select adddate(elt(convert($nines,decimal(64,0)),count(*)),
+ interval 1 day))
+ , .1))) as foo;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index bb22366a98d..083ed396527 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1437,6 +1437,11 @@ SELECT * FROM t1;
DROP TABLE t1;
--echo #
+--echo # Bug#11764310 conv function crashes, negative argument to memcpy
+--echo #
+SELECT CONV(1,-2147483648,-2147483648);
+
+--echo #
--echo # Bug#12985030 SIMPLE QUERY WITH DECIMAL NUMBERS LEAKS MEMORY
--echo #
diff --git a/mysql-test/t/group_min_max_innodb.test b/mysql-test/t/group_min_max_innodb.test
index 643b4f7d55e..7038eb2ff47 100644
--- a/mysql-test/t/group_min_max_innodb.test
+++ b/mysql-test/t/group_min_max_innodb.test
@@ -117,3 +117,23 @@ drop view v1;
drop table t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Bug#12540545 61101: ASSERTION FAILURE IN THREAD 1256741184 IN
+--echo # FILE /BUILDDIR/BUILD/BUILD/MYSQ
+--echo #
+
+CREATE TABLE t1 (a CHAR(1), b CHAR(1), PRIMARY KEY (a,b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(1) NOT NULL, b CHAR(1) NOT NULL, UNIQUE KEY (a,b))
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+EXPLAIN SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
+DROP TABLE t1;
+
+--echo End of 5.5 tests
diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test
index 6ff90f37687..5383c6a1885 100644
--- a/mysql-test/t/partition_innodb_plugin.test
+++ b/mysql-test/t/partition_innodb_plugin.test
@@ -3,6 +3,33 @@
let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--echo #
+--echo # Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
+--echo # PARTITONING, ON INDEX CREATE
+--echo # Bug#12696518: MEMORY LEAKS IN HA_PARTITION (VALGRIND TESTS ON TRUNK)
+--echo #
+CREATE TABLE t1 (
+ id bigint NOT NULL AUTO_INCREMENT,
+ time date,
+ id2 bigint not null,
+ PRIMARY KEY (id,time)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+/*!50100 PARTITION BY RANGE(TO_DAYS(time))
+(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
+ PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
+
+INSERT INTO t1 (time,id2) VALUES ('2011-07-24',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+
+--error ER_DUP_ENTRY
+CREATE UNIQUE INDEX uk_time_id2 on t1(time,id2);
+
+SELECT COUNT(*) FROM t1;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal");
--echo #
--echo # Bug#55091: Server crashes on ADD PARTITION after a failed attempt
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 07b8c065be4..3f6c50a9095 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -8755,11 +8755,117 @@ call p1(1, 0);
call p1(1, 5);
call p1(3, 2);
+delimiter |;
+--echo # Try to create a function that
+--echo # refers to non-existing variables.
+--error ER_SP_UNDECLARED_VAR
+create function f1(p1 integer, p2 integer)
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit a, b);
+ return a;
+end|
+
+create function f1()
+ returns int
+begin
+ declare a, b, c int;
+ set a = (select count(*) from t1 limit b, c);
+ return a;
+end|
+
+delimiter ;|
+--echo # How do we handle NULL limit values?
+select f1();
+
+drop function f1;
+
+delimiter |;
+--echo #
+--echo # Try to use data types not allowed in LIMIT
+--echo #
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 date, p2 date)
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 integer, p2 float)
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 integer, p2 char(1))
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 varchar(5), p2 char(1))
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 decimal, p2 decimal)
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
+create function f1(p1 double, p2 double)
+ returns int
+begin
+ declare a int;
+ set a = (select count(*) from t1 limit p1, p2);
+ return a;
+end|
+
+--echo #
+--echo # Finally, test the valid case.
+--echo #
+
+create function f1(p1 integer, p2 integer)
+returns int
+begin
+ declare count int;
+ set count= (select count(*) from (select * from t1 limit p1, p2) t_1);
+ return count;
+end|
+
+delimiter ;|
+
+select f1(0, 0);
+select f1(0, -1);
+select f1(-1, 0);
+select f1(-1, -1);
+select f1(0, 1);
+select f1(1, 0);
+select f1(1, 5);
+select f1(3, 2);
--echo # Cleanup
drop table t1;
drop procedure p1;
-
+drop function f1;
--echo #
--echo # BUG#11766234: 59299: ASSERT (TABLE_REF->TABLE || TABLE_REF->VIEW)
@@ -8881,4 +8987,52 @@ DROP TABLE t1;
DROP PROCEDURE p1;
--echo
+--echo #
+--echo # Bug#12621017 - Crash if a sp variable is used in the
+--echo # limit clause of a set statement
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+--enable_warnings
+
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+
+delimiter |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE foo, cnt INT UNSIGNED DEFAULT 1;
+ SET foo = (SELECT MIN(c1) FROM t1 LIMIT cnt);
+END|
+
+CREATE PROCEDURE p2()
+BEGIN
+
+DECLARE iLimit INT;
+DECLARE iVal INT;
+
+DECLARE cur1 CURSOR FOR
+ SELECT c1 FROM t1
+ LIMIT iLimit;
+
+SET iLimit=1;
+
+OPEN cur1;
+FETCH cur1 INTO iVal;
+
+END|
+
+delimiter ;|
+
+CALL p1();
+CALL p2();
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
--echo # End of 5.5 test
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 4f4b1962cc3..bf7e3794a19 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1244,6 +1244,27 @@ show create table t1;
select * from t1;
DROP TABLE t1;
+--echo #
+--echo # Bug#12563865
+--echo # ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
+--echo #
+
+let $nine_81=
+999999999999999999999999999999999999999999999999999999999999999999999999999999999;
+
+eval SELECT substring(('M') FROM ($nine_81)) AS foo;
+eval SELECT min($nine_81) AS foo;
+eval SELECT multipolygonfromtext(('4294967294.1'),($nine_81)) AS foo;
+eval SELECT convert(($nine_81), decimal(30,30)) AS foo;
+eval SELECT bit_xor($nine_81) AS foo;
+eval SELECT -($nine_81) AS foo;
+eval SELECT date_sub(($nine_81),
+ interval ((SELECT date_add((0x77500000),
+ interval ('Oml') second)))
+ day_minute)
+AS foo;
+eval SELECT truncate($nine_81, 28) AS foo;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 5896e25feda..663501a0a88 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -127,21 +127,26 @@ 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;
+# v5: SHOW VIEW, but no SELECT
+create view mysqltest.v5 (c,d) as select a+1,b+1 from mysqltest.t1;
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;
+grant show view on mysqltest.v5 to mysqltest_1@localhost;
connection user1;
-# all selects works
+# all SELECTs works, except v5 which lacks SELECT privs
select c from mysqltest.v1;
select c from mysqltest.v2;
select c from mysqltest.v3;
select c from mysqltest.v4;
+--error ER_TABLEACCESS_DENIED_ERROR
+select c from mysqltest.v5;
# test of show coluns
show columns from mysqltest.v1;
show columns from mysqltest.v2;
-# but explain/show do not
+# explain/show fail
--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v1;
--error ER_TABLEACCESS_DENIED_ERROR
@@ -158,15 +163,33 @@ show create view mysqltest.v3;
explain select c from mysqltest.v4;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v4;
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select c from mysqltest.v5;
+# new in 5.5: SHOW CREATE VIEW needs SELECT now (MySQL Bug#27145)
+--error ER_TABLEACCESS_DENIED_ERROR
+show create view mysqltest.v5;
+connection root;
+grant select on mysqltest.v5 to mysqltest_1@localhost;
+connection user1;
+show create view mysqltest.v5;
+# missing SELECT on underlying t1, no SHOW VIEW on v1 either.
+--error ER_VIEW_NO_EXPLAIN
+explain select c from mysqltest.v1;
+# missing SHOW VIEW
+--error ER_TABLEACCESS_DENIED_ERROR
+show create view mysqltest.v1;
# allow to see one of underlying table
connection root;
+grant show view on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.t1 to mysqltest_1@localhost;
+revoke select on mysqltest.v5 from mysqltest_1@localhost;
connection user1;
-# EXPLAIN of view on above table works
+# EXPLAIN works
explain select c from mysqltest.v1;
---error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v1;
+# missing SHOW VIEW
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v2;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v2;
@@ -179,6 +202,9 @@ show create view mysqltest.v3;
explain select c from mysqltest.v4;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v4;
+# we have SHOW VIEW on v5, and SELECT on t1 -- not enough
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select c from mysqltest.v5;
# allow to see any view in mysqltest database
connection root;
@@ -188,8 +214,12 @@ explain select c from mysqltest.v1;
show create view mysqltest.v1;
explain select c from mysqltest.v2;
show create view mysqltest.v2;
+# have SHOW VIEW | SELECT on v3, but no SELECT on t2
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v3;
show create view mysqltest.v3;
+# have SHOW VIEW | SELECT on v4, but no SELECT on t2
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v4;
show create view mysqltest.v4;
@@ -1237,6 +1267,334 @@ DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
+connection default;
+
+
+--echo Bug #11765687/#58677:
+--echo No privilege on table/view, but can know #rows / underlying table's name
+
+# As a root-like user
+connect (root,localhost,root,,test);
+connection root;
+
+create database mysqltest1;
+create table mysqltest1.t1 (i int);
+create table mysqltest1.t2 (j int);
+create table mysqltest1.t3 (k int, secret int);
+
+create user alice@localhost;
+create user bob@localhost;
+create user cecil@localhost;
+create user dan@localhost;
+create user eugene@localhost;
+create user fiona@localhost;
+create user greg@localhost;
+create user han@localhost;
+create user inga@localhost;
+create user jamie@localhost;
+create user karl@localhost;
+create user lena@localhost;
+create user mhairi@localhost;
+create user noam@localhost;
+create user olga@localhost;
+create user pjotr@localhost;
+create user quintessa@localhost;
+
+grant all privileges on mysqltest1.* to alice@localhost with grant option;
+
+#
+--echo ... as alice
+connect (test11765687,localhost,alice,,mysqltest1);
+connection test11765687;
+
+create view v1 as select * from t1;
+create view v2 as select * from v1, t2;
+create view v3 as select k from t3;
+
+grant select on mysqltest1.v1 to bob@localhost;
+
+grant show view on mysqltest1.v1 to cecil@localhost;
+
+grant select, show view on mysqltest1.v1 to dan@localhost;
+grant select on mysqltest1.t1 to dan@localhost;
+
+grant select on mysqltest1.* to eugene@localhost;
+
+grant select, show view on mysqltest1.v2 to fiona@localhost;
+
+grant select, show view on mysqltest1.v2 to greg@localhost;
+grant show view on mysqltest1.v1 to greg@localhost;
+
+grant select(k) on mysqltest1.t3 to han@localhost;
+grant select, show view on mysqltest1.v3 to han@localhost;
+
+grant select on mysqltest1.t1 to inga@localhost;
+grant select on mysqltest1.t2 to inga@localhost;
+grant select on mysqltest1.v1 to inga@localhost;
+grant select, show view on mysqltest1.v2 to inga@localhost;
+
+grant select on mysqltest1.t1 to jamie@localhost;
+grant select on mysqltest1.t2 to jamie@localhost;
+grant show view on mysqltest1.v1 to jamie@localhost;
+grant select, show view on mysqltest1.v2 to jamie@localhost;
+
+grant select on mysqltest1.t1 to karl@localhost;
+grant select on mysqltest1.t2 to karl@localhost;
+grant select, show view on mysqltest1.v1 to karl@localhost;
+grant select on mysqltest1.v2 to karl@localhost;
+
+grant select on mysqltest1.t1 to lena@localhost;
+grant select on mysqltest1.t2 to lena@localhost;
+grant select, show view on mysqltest1.v1 to lena@localhost;
+grant show view on mysqltest1.v2 to lena@localhost;
+
+grant select on mysqltest1.t1 to mhairi@localhost;
+grant select on mysqltest1.t2 to mhairi@localhost;
+grant select, show view on mysqltest1.v1 to mhairi@localhost;
+grant select, show view on mysqltest1.v2 to mhairi@localhost;
+
+grant select on mysqltest1.t1 to noam@localhost;
+grant select, show view on mysqltest1.v1 to noam@localhost;
+grant select, show view on mysqltest1.v2 to noam@localhost;
+
+grant select on mysqltest1.t2 to olga@localhost;
+grant select, show view on mysqltest1.v1 to olga@localhost;
+grant select, show view on mysqltest1.v2 to olga@localhost;
+
+grant select on mysqltest1.t1 to pjotr@localhost;
+grant select on mysqltest1.t2 to pjotr@localhost;
+grant select, show view on mysqltest1.v2 to pjotr@localhost;
+
+grant select, show view on mysqltest1.v1 to quintessa@localhost;
+
+disconnect test11765687;
+
+#
+--echo ... as bob
+connect (test11765687,localhost,bob,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail, no SHOW_VIEW
+
+disconnect test11765687;
+
+#
+--echo ... as cecil
+connect (test11765687,localhost,cecil,,mysqltest1);
+connection test11765687;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from v1; # fail, no SELECT
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v1; # fail, no SELECT
+
+disconnect test11765687;
+
+#
+--echo ... as dan
+connect (test11765687,localhost,dan,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+explain select * from v1; # Should succeed.
+
+disconnect test11765687;
+
+#
+--echo ... as eugene
+connect (test11765687,localhost,eugene,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail, no SHOW_VIEW
+
+disconnect test11765687;
+
+#
+--echo ... as fiona
+connect (test11765687,localhost,fiona,,mysqltest1);
+connection test11765687;
+
+select * from v2; # Should succeed.
+show create view v2; # Should succeed, but...
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t1; # fail, shouldn't see t1!
+--error ER_TABLEACCESS_DENIED_ERROR
+# err msg must give view name, no table names!!
+explain select * from v1; # fail, have no privs on v1!
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t2; # fail, have no privs on t2!
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2; # fail, shouldn't see t2!
+
+disconnect test11765687;
+
+#
+--echo ... as greg
+connect (test11765687,localhost,greg,,mysqltest1);
+connection test11765687;
+
+select * from v2; # Should succeed.
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v1; # fail; no SELECT on v1!
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2; # fail; no SELECT on v1!
+
+disconnect test11765687;
+
+#
+--echo ... as han
+connect (test11765687,localhost,han,,mysqltest1);
+connection test11765687;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from t3; # don't have privs on all columns,
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t3; # so EXPLAIN on "forbidden" columns should fail.
+select k from t3; # but we do have SELECT on column k though,
+explain select k from t3; # so EXPLAIN just on k should work,
+select * from v3; # and so should SELECT on view only using allowed columns
+explain select * from v3; # as should the associated EXPLAIN
+
+disconnect test11765687;
+
+#
+--echo ... as inga
+connect (test11765687,localhost,inga,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, only sel v1
+# fail: lacks show on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as jamie
+connect (test11765687,localhost,jamie,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, only show v1
+# fail: lacks sel on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as karl
+connect (test11765687,localhost,karl,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel only on v2, sel on t1/t2, sel/show v1
+# fail: lacks show on v2
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as lena
+
+connect (test11765687,localhost,lena,,mysqltest1);
+connection test11765687;
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from v2;
+# has show only on v2, sel on t1/t2, sel/show v1
+# fail: lacks sel on v2
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as mhairi
+connect (test11765687,localhost,mhairi,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, sel/show v1
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as noam
+connect (test11765687,localhost,noam,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t1, sel/show v1 (no sel on t2!)
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as olga
+connect (test11765687,localhost,olga,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t2, sel/show v1 (no sel on t1!)
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as pjotr
+connect (test11765687,localhost,pjotr,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t2, nothing on v1
+# fail: lacks show on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as quintessa
+connect (test11765687,localhost,quintessa,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail: lacks select on t1
+
+disconnect test11765687;
+
+# cleanup
+
+#
+--echo ... as root again at last: clean-up time!
+connection root;
+
+drop user alice@localhost;
+drop user bob@localhost;
+drop user cecil@localhost;
+drop user dan@localhost;
+drop user eugene@localhost;
+drop user fiona@localhost;
+drop user greg@localhost;
+drop user han@localhost;
+drop user inga@localhost;
+drop user jamie@localhost;
+drop user karl@localhost;
+drop user lena@localhost;
+drop user mhairi@localhost;
+drop user noam@localhost;
+drop user olga@localhost;
+drop user pjotr@localhost;
+drop user quintessa@localhost;
+
+drop database mysqltest1;
+
+disconnect root;
+
+connection default;
+
--echo End of 5.0 tests.
diff --git a/sql/field.cc b/sql/field.cc
index e1a24e82718..ef66c1ba9bb 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -9159,8 +9159,9 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
pack_flag= FIELDFLAG_INTERVAL;
break;
- case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
+ DBUG_ASSERT(decimals_arg <= DECIMAL_MAX_SCALE);
+ case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
pack_flag= FIELDFLAG_NUMBER |
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 82bd39220a9..fdaa1b0cda6 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -6663,49 +6663,81 @@ bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info,
/**
+ Helper class for [final_]add_index, see handler.h
+*/
+
+class ha_partition_add_index : public handler_add_index
+{
+public:
+ handler_add_index **add_array;
+ ha_partition_add_index(TABLE* table_arg, KEY* key_info_arg,
+ uint num_of_keys_arg)
+ : handler_add_index(table_arg, key_info_arg, num_of_keys_arg)
+ {}
+ ~ha_partition_add_index() {}
+};
+
+
+/**
Support of in-place add/drop index
+
+ @param table_arg Table to add index to
+ @param key_info Struct over the new keys to add
+ @param num_of_keys Number of keys to add
+ @param[out] add Data to be submitted with final_add_index
+
+ @return Operation status
+ @retval 0 Success
+ @retval != 0 Failure (error code returned, and all operations rollbacked)
*/
+
int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys,
handler_add_index **add)
{
- handler **file;
+ uint i;
int ret= 0;
+ THD *thd= ha_thd();
+ ha_partition_add_index *part_add_index;
DBUG_ENTER("ha_partition::add_index");
- *add= new handler_add_index(table, key_info, num_of_keys);
/*
There has already been a check in fix_partition_func in mysql_alter_table
before this call, which checks for unique/primary key violations of the
partitioning function. So no need for extra check here.
*/
- for (file= m_file; *file; file++)
+
+ /*
+ This will be freed at the end of the statement.
+ And destroyed at final_add_index. (Sql_alloc does not free in delete).
+ */
+ part_add_index= new (thd->mem_root)
+ ha_partition_add_index(table_arg, key_info, num_of_keys);
+ if (!part_add_index)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ part_add_index->add_array= (handler_add_index **)
+ thd->alloc(sizeof(void *) * m_tot_parts);
+ if (!part_add_index->add_array)
{
- handler_add_index *add_index;
- if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys, &add_index)))
- goto err;
- if ((ret= (*file)->final_add_index(add_index, true)))
+ delete part_add_index;
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ if ((ret= m_file[i]->add_index(table_arg, key_info, num_of_keys,
+ &part_add_index->add_array[i])))
goto err;
}
+ *add= part_add_index;
DBUG_RETURN(ret);
err:
- if (file > m_file)
+ /* Rollback all prepared partitions. i - 1 .. 0 */
+ while (i)
{
- uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
- uint old_num_of_keys= table_arg->s->keys;
- uint i;
- /* The newly created keys have the last id's */
- for (i= 0; i < num_of_keys; i++)
- key_numbers[i]= i + old_num_of_keys;
- if (!table_arg->key_info)
- table_arg->key_info= key_info;
- while (--file >= m_file)
- {
- (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
- (void) (*file)->final_drop_index(table_arg);
- }
- if (table_arg->key_info == key_info)
- table_arg->key_info= NULL;
+ i--;
+ (void) m_file[i]->final_add_index(part_add_index->add_array[i], false);
}
+ delete part_add_index;
DBUG_RETURN(ret);
}
@@ -6713,37 +6745,119 @@ err:
/**
Second phase of in-place add index.
+ @param add Info from add_index
+ @param commit Should we commit or rollback the add_index operation
+
+ @return Operation status
+ @retval 0 Success
+ @retval != 0 Failure (error code returned)
+
@note If commit is false, index changes are rolled back by dropping the
added indexes. If commit is true, nothing is done as the indexes
were already made active in ::add_index()
- */
+*/
int ha_partition::final_add_index(handler_add_index *add, bool commit)
{
+ ha_partition_add_index *part_add_index;
+ uint i;
+ int ret= 0;
+
DBUG_ENTER("ha_partition::final_add_index");
- // Rollback by dropping indexes.
- if (!commit)
- {
- TABLE *table_arg= add->table;
- uint num_of_keys= add->num_of_keys;
- handler **file;
- uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
- uint old_num_of_keys= table_arg->s->keys;
- uint i;
- /* The newly created keys have the last id's */
- for (i= 0; i < num_of_keys; i++)
- key_numbers[i]= i + old_num_of_keys;
- if (!table_arg->key_info)
- table_arg->key_info= add->key_info;
- for (file= m_file; *file; file++)
+
+ if (!add)
+ {
+ DBUG_ASSERT(!commit);
+ DBUG_RETURN(0);
+ }
+ part_add_index= static_cast<class ha_partition_add_index*>(add);
+
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ if ((ret= m_file[i]->final_add_index(part_add_index->add_array[i], commit)))
+ goto err;
+ DBUG_EXECUTE_IF("ha_partition_fail_final_add_index", {
+ /* Simulate a failure by rollback the second partition */
+ if (m_tot_parts > 1)
+ {
+ i++;
+ m_file[i]->final_add_index(part_add_index->add_array[i], false);
+ /* Set an error that is specific to ha_partition. */
+ ret= HA_ERR_NO_PARTITION_FOUND;
+ goto err;
+ }
+ });
+ }
+ delete part_add_index;
+ DBUG_RETURN(ret);
+err:
+ uint j;
+ uint *key_numbers= NULL;
+ KEY *old_key_info= NULL;
+ uint num_of_keys= 0;
+ int error;
+
+ /* How could this happen? Needed to create a covering test case :) */
+ DBUG_ASSERT(ret == HA_ERR_NO_PARTITION_FOUND);
+
+ if (i > 0)
+ {
+ num_of_keys= part_add_index->num_of_keys;
+ key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
+ if (!key_numbers)
+ {
+ sql_print_error("Failed with error handling of adding index:\n"
+ "committing index failed, and when trying to revert "
+ "already committed partitions we failed allocating\n"
+ "memory for the index for table '%s'",
+ table_share->table_name.str);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ old_key_info= table->key_info;
+ /*
+ Use the newly added key_info as table->key_info to remove them.
+ Note that this requires the subhandlers to use name lookup of the
+ index. They must use given table->key_info[key_number], they cannot
+ use their local view of the keys, since table->key_info only include
+ the indexes to be removed here.
+ */
+ for (j= 0; j < num_of_keys; j++)
+ key_numbers[j]= j;
+ table->key_info= part_add_index->key_info;
+ }
+
+ for (j= 0; j < m_tot_parts; j++)
+ {
+ if (j < i)
{
- (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
- (void) (*file)->final_drop_index(table_arg);
+ /* Remove the newly added index */
+ error= m_file[j]->prepare_drop_index(table, key_numbers, num_of_keys);
+ if (error || m_file[j]->final_drop_index(table))
+ {
+ sql_print_error("Failed with error handling of adding index:\n"
+ "committing index failed, and when trying to revert "
+ "already committed partitions we failed removing\n"
+ "the index for table '%s' partition nr %d",
+ table_share->table_name.str, j);
+ }
+ }
+ else if (j > i)
+ {
+ /* Rollback non finished partitions */
+ if (m_file[j]->final_add_index(part_add_index->add_array[j], false))
+ {
+ /* How could this happen? */
+ sql_print_error("Failed with error handling of adding index:\n"
+ "Rollback of add_index failed for table\n"
+ "'%s' partition nr %d",
+ table_share->table_name.str, j);
+ }
}
- if (table_arg->key_info == add->key_info)
- table_arg->key_info= NULL;
}
- DBUG_RETURN(0);
+ if (i > 0)
+ table->key_info= old_key_info;
+ delete part_add_index;
+ DBUG_RETURN(ret);
}
int ha_partition::prepare_drop_index(TABLE *table_arg, uint *key_num,
diff --git a/sql/handler.cc b/sql/handler.cc
index 6f7cf2c3456..b6df46ed48d 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2738,7 +2738,13 @@ void handler::print_error(int error, myf errflag)
char key[MAX_KEY_LENGTH];
String str(key,sizeof(key),system_charset_info);
/* Table is opened and defined at this point */
- key_unpack(&str,table,(uint) key_nr);
+ key_unpack(&str,table,0 /* Use 0 instead of key_nr because key_nr
+ is a key number in the child FK table, not in our 'table'. See
+ Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB
+ AND IT IS PARENT FOR OTHER ONE
+ This bug gets a better fix in MySQL 5.6, but it is too risky
+ to get that in 5.1 and 5.5 (extending the handler interface
+ and adding new error message codes */);
max_length= (MYSQL_ERRMSG_SIZE-
(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
if (str.length() >= max_length)
diff --git a/sql/handler.h b/sql/handler.h
index d1222cb56a6..cbdfc231ed5 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1163,10 +1163,12 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
/**
Index creation context.
- Created by handler::add_index() and freed by handler::final_add_index().
+ Created by handler::add_index() and destroyed by handler::final_add_index().
+ And finally freed at the end of the statement.
+ (Sql_alloc does not free in delete).
*/
-class handler_add_index
+class handler_add_index : public Sql_alloc
{
public:
/* Table where the indexes are added */
diff --git a/sql/item.h b/sql/item.h
index 5a40aaf2a93..223a519fa33 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1371,7 +1371,7 @@ class Item_splocal :public Item_sp_variable,
enum_field_types m_field_type;
public:
/*
- Is this variable a parameter in LIMIT clause.
+ If this variable is a parameter in LIMIT clause.
Used only during NAME_CONST substitution, to not append
NAME_CONST to the resulting query and thus not break
the slave.
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index e28221109d9..f30b6adcb93 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2625,37 +2625,43 @@ Item_func_if::fix_fields(THD *thd, Item **ref)
}
-void
-Item_func_if::fix_length_and_dec()
+void Item_func_if::cache_type_info(Item *source)
{
- maybe_null=args[1]->maybe_null || args[2]->maybe_null;
- decimals= max(args[1]->decimals, args[2]->decimals);
- unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+ collation.set(source->collation);
+ cached_field_type= source->field_type();
+ cached_result_type= source->result_type();
+ decimals= source->decimals;
+ max_length= source->max_length;
+ maybe_null= source->maybe_null;
+ unsigned_flag= source->unsigned_flag;
+}
- enum Item_result arg1_type=args[1]->result_type();
- enum Item_result arg2_type=args[2]->result_type();
- bool null1=args[1]->const_item() && args[1]->null_value;
- bool null2=args[2]->const_item() && args[2]->null_value;
- if (null1)
+void
+Item_func_if::fix_length_and_dec()
+{
+ // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
+ if (args[1]->type() == NULL_ITEM)
{
- cached_result_type= arg2_type;
- collation.set(args[2]->collation);
- cached_field_type= args[2]->field_type();
- max_length= args[2]->max_length;
+ cache_type_info(args[2]);
+ maybe_null= true;
+ // If both arguments are NULL, make resulting type BINARY(0).
+ if (args[2]->type() == NULL_ITEM)
+ cached_field_type= MYSQL_TYPE_STRING;
return;
}
-
- if (null2)
+ if (args[2]->type() == NULL_ITEM)
{
- cached_result_type= arg1_type;
- collation.set(args[1]->collation);
- cached_field_type= args[1]->field_type();
- max_length= args[1]->max_length;
+ cache_type_info(args[1]);
+ maybe_null= true;
return;
}
agg_result_type(&cached_result_type, args + 1, 2);
+ maybe_null= args[1]->maybe_null || args[2]->maybe_null;
+ decimals= max(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
if (cached_result_type == STRING_RESULT)
{
if (agg_arg_charsets_for_string_result(collation, args + 1, 2))
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index b6928d63ea0..a735f01fb39 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -750,6 +750,8 @@ public:
void fix_length_and_dec();
uint decimal_precision() const;
const char *func_name() const { return "if"; }
+private:
+ void cache_type_info(Item *source);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 55087879b98..a0fdb3cf811 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2952,9 +2952,12 @@ String *Item_func_conv::val_str(String *str)
from_base, &endptr, &err);
}
- ptr= longlong2str(dec, ans, to_base);
- if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
- return make_empty_result();
+ if (!(ptr= longlong2str(dec, ans, to_base)) ||
+ str->copy(ans, (uint32) (ptr - ans), default_charset()))
+ {
+ null_value= 1;
+ return NULL;
+ }
return str;
}
@@ -3113,8 +3116,10 @@ String *Item_func_hex::val_str_ascii(String *str)
if ((null_value= args[0]->null_value))
return 0;
- ptr= longlong2str(dec,ans,16);
- if (str->copy(ans,(uint32) (ptr-ans), &my_charset_numeric))
+
+ if (!(ptr= longlong2str(dec, ans, 16)) ||
+ str->copy(ans,(uint32) (ptr - ans),
+ &my_charset_numeric))
return make_empty_result(); // End of memory
return str;
}
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 548d5ea3a53..64afb9a096e 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -98,12 +98,31 @@ inline int my_decimal_int_part(uint precision, uint decimals)
class my_decimal :public decimal_t
{
+ /*
+ Several of the routines in strings/decimal.c have had buffer
+ overrun/underrun problems. These are *not* caught by valgrind.
+ To catch them, we allocate dummy fields around the buffer,
+ and test that their values do not change.
+ */
+#if !defined(DBUG_OFF)
+ int foo1;
+#endif
+
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
+#if !defined(DBUG_OFF)
+ int foo2;
+ static const int test_value= 123;
+#endif
+
public:
my_decimal(const my_decimal &rhs) : decimal_t(rhs)
{
+#if !defined(DBUG_OFF)
+ foo1= test_value;
+ foo2= test_value;
+#endif
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
buffer[i]= rhs.buffer[i];
fix_buffer_pointer();
@@ -111,6 +130,10 @@ public:
my_decimal& operator=(const my_decimal &rhs)
{
+#if !defined(DBUG_OFF)
+ foo1= test_value;
+ foo2= test_value;
+#endif
if (this == &rhs)
return *this;
decimal_t::operator=(rhs);
@@ -122,6 +145,10 @@ public:
void init()
{
+#if !defined(DBUG_OFF)
+ foo1= test_value;
+ foo2= test_value;
+#endif
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
}
@@ -130,6 +157,17 @@ public:
{
init();
}
+ ~my_decimal()
+ {
+ sanity_check();
+ }
+
+ void sanity_check()
+ {
+ DBUG_ASSERT(foo1 == test_value);
+ DBUG_ASSERT(foo2 == test_value);
+ }
+
void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal_t::sign; }
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 730024f4389..8a6607cf343 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -9318,6 +9318,11 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
except MIN and MAX. For queries with DISTINCT, aggregate functions
are allowed.
SA5. The select list in DISTINCT queries should not contain expressions.
+ SA6. Clustered index can not be used by GROUP_MIN_MAX quick select
+ for AGG_FUNC(DISTINCT ...) optimization because cursor position is
+ never stored after a unique key lookup in the clustered index and
+ furhter index_next/prev calls can not be used. So loose index scan
+ optimization can not be used in this case.
GA1. If Q has a GROUP BY clause, then GA is a prefix of I. That is, if
G_i = A_j => i = j.
GA2. If Q has a DISTINCT clause, then there is a permutation of SA that
@@ -9804,6 +9809,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
Field::itMBR : Field::itRAW))
DBUG_RETURN(NULL);
+ /*
+ Check (SA6) if clustered key is used
+ */
+ if (is_agg_distinct && index == table->s->primary_key &&
+ table->file->primary_key_is_clustered())
+ DBUG_RETURN(NULL);
+
/* The query passes all tests, so construct a new TRP object. */
read_plan= new (param->mem_root)
TRP_GROUP_MIN_MAX(have_min, have_max, is_agg_distinct,
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index ec867b43ff1..5507b633f8f 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6371,7 +6371,7 @@ ER_DATA_OUT_OF_RANGE 22003
eng "%s value is out of range in '%s'"
ER_WRONG_SPVAR_TYPE_IN_LIMIT
- eng "A variable of a non-integer type in LIMIT clause"
+ eng "A variable of a non-integer based type in LIMIT clause"
ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE
eng "Mixing self-logging and non-self-logging engines in a statement is unsafe."
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ce713504a38..eb29590b700 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1005,6 +1005,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
if ((*splocal)->limit_clause_param)
{
res|= qbuf.append_ulonglong((*splocal)->val_uint());
+ if (res)
+ break;
continue;
}
@@ -1029,19 +1031,29 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
thd->query_name_consts++;
}
- res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
- if (res)
+ if (res ||
+ qbuf.append(cur + prev_pos, query_str->length - prev_pos))
DBUG_RETURN(TRUE);
/*
Allocate additional space at the end of the new query string for the
query_cache_send_result_to_client function.
+
+ The query buffer layout is:
+ buffer :==
+ <statement> The input statement(s)
+ '\0' Terminating null char
+ <length> Length of following current database name (size_t)
+ <db_name> Name of current database
+ <flags> Flags struct
*/
- buf_len= qbuf.length() + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE + 1;
+ buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length +
+ QUERY_CACHE_FLAGS_SIZE + 1;
if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
{
memcpy(pbuf, qbuf.ptr(), qbuf.length());
pbuf[qbuf.length()]= 0;
+ memcpy(pbuf+qbuf.length()+1, (char *) &thd->db_length, sizeof(size_t));
}
else
DBUG_RETURN(TRUE);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 3f236dd672f..3438e60683f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -520,23 +520,9 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
1 + USERNAME_LENGTH + 1)
-#if defined(HAVE_OPENSSL)
-/*
- Without SSL the handshake consists of one packet. This packet
- has both client capabilities and scrambled password.
- With SSL the handshake might consist of two packets. If the first
- packet (client capabilities) has CLIENT_SSL flag set, we have to
- switch to SSL and read the second packet. The scrambled password
- is in the second packet and client_capabilities field will be ignored.
- Maybe it is better to accept flags other than CLIENT_SSL from the
- second packet?
-*/
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
-#else
-#define MIN_HANDSHAKE_SIZE 6
-#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+/** Size of the header fields of an authentication packet. */
+#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32
+#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5
static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users;
static MEM_ROOT mem, memex;
@@ -8552,37 +8538,92 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
#ifndef EMBEDDED_LIBRARY
NET *net= mpvio->net;
char *end;
-
+ bool packet_has_required_size= false;
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
- if (pkt_len < MIN_HANDSHAKE_SIZE)
- return packet_error;
-
if (mpvio->connect_errors)
reset_host_errors(mpvio->ip);
- ulong client_capabilities= uint2korr(net->read_pos);
- if (client_capabilities & CLIENT_PROTOCOL_41)
+ uint charset_code= 0;
+ end= (char *)net->read_pos;
+ /*
+ In order to safely scan a head for '\0' string terminators
+ we must keep track of how many bytes remain in the allocated
+ buffer or we might read past the end of the buffer.
+ */
+ size_t bytes_remaining_in_packet= pkt_len;
+
+ /*
+ Peek ahead on the client capability packet and determine which version of
+ the protocol should be used.
+ */
+ if (bytes_remaining_in_packet < 2)
+ return packet_error;
+
+ mpvio->client_capabilities= uint2korr(end);
+
+ /*
+ JConnector only sends server capabilities before starting SSL
+ negotiation. The below code is patch for this.
+ */
+ if (bytes_remaining_in_packet == 4 &&
+ mpvio->client_capabilities & CLIENT_SSL)
{
- client_capabilities|= ((ulong) uint2korr(net->read_pos + 2)) << 16;
- mpvio->max_client_packet_length= uint4korr(net->read_pos + 4);
- DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
- if (mpvio->charset_adapter->init_client_charset((uint) net->read_pos[8]))
+ mpvio->client_capabilities= uint4korr(end);
+ mpvio->max_client_packet_length= 0xfffff;
+ charset_code= default_charset_info->number;
+ if (mpvio->charset_adapter->init_client_charset(charset_code))
return packet_error;
- end= (char*) net->read_pos + 32;
+ goto skip_to_ssl;
}
+
+ if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
+ packet_has_required_size= bytes_remaining_in_packet >=
+ AUTH_PACKET_HEADER_SIZE_PROTO_41;
else
+ packet_has_required_size= bytes_remaining_in_packet >=
+ AUTH_PACKET_HEADER_SIZE_PROTO_40;
+
+ if (!packet_has_required_size)
+ return packet_error;
+
+ if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
{
- mpvio->max_client_packet_length= uint3korr(net->read_pos + 2);
- end= (char*) net->read_pos + 5;
+ mpvio->client_capabilities= uint4korr(end);
+ mpvio->max_client_packet_length= uint4korr(end + 4);
+ charset_code= (uint)(uchar)*(end + 8);
+ /*
+ Skip 23 remaining filler bytes which have no particular meaning.
+ */
+ end+= AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ }
+ else
+ {
+ mpvio->client_capabilities= uint2korr(end);
+ mpvio->max_client_packet_length= uint3korr(end + 2);
+ end+= AUTH_PACKET_HEADER_SIZE_PROTO_40;
+ bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_40;
+ /**
+ Old clients didn't have their own charset. Instead the assumption
+ was that they used what ever the server used.
+ */
+ charset_code= default_charset_info->number;
}
- /* Disable those bits which are not supported by the client. */
- mpvio->client_capabilities&= client_capabilities;
-
+ DBUG_PRINT("info", ("client_character_set: %u", charset_code));
+ if (mpvio->charset_adapter->init_client_charset(charset_code))
+ return packet_error;
+skip_to_ssl:
#if defined(HAVE_OPENSSL)
DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities));
+
+ /*
+ If client requested SSL then we must stop parsing, try to switch to SSL,
+ and wait for the client to send a new handshake packet.
+ The client isn't expected to send any more bytes until SSL is initialized.
+ */
if (mpvio->client_capabilities & CLIENT_SSL)
{
unsigned long errptr;
@@ -8599,18 +8640,42 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
}
DBUG_PRINT("info", ("Reading user information over SSL layer"));
- pkt_len= my_net_read(net);
- if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE)
+ if ((pkt_len= my_net_read(net)) == packet_error)
{
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
pkt_len));
return packet_error;
}
- }
-#endif
+ /*
+ A new packet was read and the statistics reflecting the remaining bytes
+ in the packet must be updated.
+ */
+ bytes_remaining_in_packet= pkt_len;
- if (end > (char *)net->read_pos + pkt_len)
- return packet_error;
+ /*
+ After the SSL handshake is performed the client resends the handshake
+ packet but because of legacy reasons we chose not to parse the packet
+ fields a second time and instead only assert the length of the packet.
+ */
+ if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
+ {
+ packet_has_required_size= bytes_remaining_in_packet >=
+ AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ }
+ else
+ {
+ packet_has_required_size= bytes_remaining_in_packet >=
+ AUTH_PACKET_HEADER_SIZE_PROTO_40;
+ end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_40;
+ bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40;
+ }
+
+ if (!packet_has_required_size)
+ return packet_error;
+ }
+#endif /* HAVE_OPENSSL */
if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
@@ -8634,7 +8699,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
we must keep track of how many bytes remain in the allocated
buffer or we might read past the end of the buffer.
*/
- size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
+ bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
size_t user_len;
char *user= get_string(&end, &bytes_remaining_in_packet, &user_len);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 47628f1c590..56ce6607c85 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1278,8 +1278,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Key is query + database + flag */
if (thd->db_length)
{
- memcpy(thd->query() + thd->query_length() + 1, thd->db,
- thd->db_length);
+ memcpy(thd->query() + thd->query_length() + 1 + sizeof(size_t),
+ thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u",
thd->db, (unsigned) thd->db_length));
}
@@ -1288,7 +1288,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
DBUG_PRINT("qcache", ("No active database"));
}
tot_length= thd->query_length() + thd->db_length + 1 +
- QUERY_CACHE_FLAGS_SIZE;
+ sizeof(size_t) + QUERY_CACHE_FLAGS_SIZE;
/*
We should only copy structure (don't use it location directly)
because of alignment issue
@@ -1506,7 +1506,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err;
}
}
+ {
+ /*
+ We have allocated buffer space (in alloc_query) to hold the
+ SQL statement(s) + the current database name + a flags struct.
+ If the database name has changed during execution, which might
+ happen if there are multiple statements, we need to make
+ sure the new current database has a name with the same length
+ as the previous one.
+ */
+ size_t db_len;
+ memcpy((char *) &db_len, (sql + query_length + 1), sizeof(size_t));
+ if (thd->db_length != db_len)
+ {
+ /*
+ We should probably reallocate the buffer in this case,
+ but for now we just leave it uncached
+ */
+ DBUG_PRINT("qcache",
+ ("Current database has changed since start of query"));
+ goto err;
+ }
+ }
/*
Try to obtain an exclusive lock on the query cache. If the cache is
disabled or if a full cache flush is in progress, the attempt to
@@ -1522,10 +1544,12 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_block *query_block;
- tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
+ tot_length= query_length + 1 + sizeof(size_t) +
+ thd->db_length + QUERY_CACHE_FLAGS_SIZE;
+
if (thd->db_length)
{
- memcpy(sql+query_length+1, thd->db, thd->db_length);
+ memcpy(sql + query_length + 1 + sizeof(size_t), thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: '%s' length: %u",
thd->db, (unsigned)thd->db_length));
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index df27362633f..869a5916339 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2606,7 +2606,47 @@ void st_select_lex_unit::set_limit(st_select_lex *sl)
ulonglong val;
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
- val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
+ if (sl->select_limit)
+ {
+ Item *item = sl->select_limit;
+ /*
+ fix_fields() has not been called for sl->select_limit. That's due to the
+ historical reasons -- this item could be only of type Item_int, and
+ Item_int does not require fix_fields(). Thus, fix_fields() was never
+ called for sl->select_limit.
+
+ Some time ago, Item_splocal was also allowed for LIMIT / OFFSET clauses.
+ However, the fix_fields() behavior was not updated, which led to a crash
+ in some cases.
+
+ There is no single place where to call fix_fields() for LIMIT / OFFSET
+ items during the fix-fields-phase. Thus, for the sake of readability,
+ it was decided to do it here, on the evaluation phase (which is a
+ violation of design, but we chose the lesser of two evils).
+
+ We can call fix_fields() here, because sl->select_limit can be of two
+ types only: Item_int and Item_splocal. Item_int::fix_fields() is trivial,
+ and Item_splocal::fix_fields() (or rather Item_sp_variable::fix_fields())
+ has the following specific:
+ 1) it does not affect other items;
+ 2) it does not fail.
+
+ Nevertheless DBUG_ASSERT was added to catch future changes in
+ fix_fields() implementation. Also added runtime check against a result
+ of fix_fields() in order to handle error condition in non-debug build.
+ */
+ bool fix_fields_successful= true;
+ if (!item->fixed)
+ {
+ fix_fields_successful= !item->fix_fields(thd, NULL);
+
+ DBUG_ASSERT(fix_fields_successful);
+ }
+ val= fix_fields_successful ? item->val_uint() : HA_POS_ERROR;
+ }
+ else
+ val= HA_POS_ERROR;
+
select_limit_val= (ha_rows)val;
#ifndef BIG_TABLES
/*
@@ -2616,7 +2656,22 @@ void st_select_lex_unit::set_limit(st_select_lex *sl)
if (val != (ulonglong)select_limit_val)
select_limit_val= HA_POS_ERROR;
#endif
- val= sl->offset_limit ? sl->offset_limit->val_uint() : ULL(0);
+ if (sl->offset_limit)
+ {
+ Item *item = sl->offset_limit;
+ // see comment for sl->select_limit branch.
+ bool fix_fields_successful= true;
+ if (!item->fixed)
+ {
+ fix_fields_successful= !item->fix_fields(thd, NULL);
+
+ DBUG_ASSERT(fix_fields_successful);
+ }
+ val= fix_fields_successful ? item->val_uint() : HA_POS_ERROR;
+ }
+ else
+ val= ULL(0);
+
offset_limit_cnt= (ha_rows)val;
#ifndef BIG_TABLES
/* Check for truncation. */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e3da697ec78..32ccb8f2c5f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -536,6 +536,8 @@ static void handle_bootstrap_impl(THD *thd)
query= (char *) thd->memdup_w_gap(buff, length + 1,
thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE);
+ size_t db_len= 0;
+ memcpy(query + length + 1, (char *) &db_len, sizeof(size_t));
thd->set_query_and_id(query, length, thd->charset(), next_query_id());
DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING)
@@ -1218,6 +1220,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_REFRESH:
{
int not_used;
+
+ /*
+ Initialize thd->lex since it's used in many base functions, such as
+ open_tables(). Otherwise, it remains unitialized and may cause crash
+ during execution of COM_REFRESH.
+ */
+ lex_start(thd);
+
status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
ulong options= (ulong) (uchar) packet[0];
if (trans_commit_implicit(thd))
@@ -1629,13 +1639,30 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
pos--;
packet_length--;
}
- /* We must allocate some extra memory for query cache */
+ /* We must allocate some extra memory for query cache
+
+ The query buffer layout is:
+ buffer :==
+ <statement> The input statement(s)
+ '\0' Terminating null char (1 byte)
+ <length> Length of following current database name (size_t)
+ <db_name> Name of current database
+ <flags> Flags struct
+ */
if (! (query= (char*) thd->memdup_w_gap(packet,
packet_length,
- 1 + thd->db_length +
+ 1 + sizeof(size_t) + thd->db_length +
QUERY_CACHE_FLAGS_SIZE)))
return TRUE;
query[packet_length]= '\0';
+ /*
+ Space to hold the name of the current database is allocated. We
+ also store this length, in case current database is changed during
+ execution. We might need to reallocate the 'query' buffer
+ */
+ char *len_pos = (query + packet_length + 1);
+ memcpy(len_pos, (char *) &thd->db_length, sizeof(size_t));
+
thd->set_query(query, packet_length);
/* Reclaim some memory */
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 089077bb89c..b0665a9ea6b 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -118,7 +118,14 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
if (options & REFRESH_ERROR_LOG)
if (flush_error_log())
+ {
+ /*
+ When flush_error_log() failed, my_error() has not been called.
+ So, we have to do it here to keep the protocol.
+ */
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
result= 1;
+ }
if ((options & REFRESH_SLOW_LOG) && opt_slow_log)
logger.flush_slow_log();
@@ -200,7 +207,13 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
if (close_cached_tables(thd, tables,
((options & REFRESH_FAST) ? FALSE : TRUE),
thd->variables.lock_wait_timeout))
+ {
+ /*
+ NOTE: my_error() has been already called by reopen_tables() within
+ close_cached_tables().
+ */
result= 1;
+ }
if (thd->global_read_lock.make_global_read_lock_block_commit(thd)) // Killed
{
@@ -256,7 +269,13 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
((options & REFRESH_FAST) ? FALSE : TRUE),
(thd ? thd->variables.lock_wait_timeout :
LONG_TIMEOUT)))
+ {
+ /*
+ NOTE: my_error() has been already called by reopen_tables() within
+ close_cached_tables().
+ */
result= 1;
+ }
}
my_dbopt_cleanup();
}
@@ -273,7 +292,8 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
tmp_write_to_binlog= 0;
if (reset_master(thd))
{
- result=1;
+ /* NOTE: my_error() has been already called by reset_master(). */
+ result= 1;
}
}
#endif
@@ -281,7 +301,10 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
if (options & REFRESH_DES_KEY_FILE)
{
if (des_key_file && load_des_key_file(des_key_file))
- result= 1;
+ {
+ /* NOTE: my_error() has been already called by load_des_key_file(). */
+ result= 1;
+ }
}
#endif
#ifdef HAVE_REPLICATION
@@ -290,7 +313,10 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
tmp_write_to_binlog= 0;
mysql_mutex_lock(&LOCK_active_mi);
if (reset_slave(thd, active_mi))
- result=1;
+ {
+ /* NOTE: my_error() has been already called by reset_slave(). */
+ result= 1;
+ }
mysql_mutex_unlock(&LOCK_active_mi);
}
#endif
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index ef7d35ecfaa..00c85d8eb43 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -731,7 +731,15 @@ impossible position";
/Alfranio
*/
if (binlog_can_be_corrupted)
- sql_print_information("The binlog may be corrupted.");
+ {
+ /*
+ Don't try to print out warning messages because this generates
+ erroneous messages in the error log and causes performance
+ problems.
+
+ /Alfranio
+ */
+ }
pos = my_b_tell(&log);
if (RUN_HOOK(binlog_transmit, before_send_event,
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 6051aa028c7..1d26d2b113c 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1281,9 +1281,41 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
if (!table->prelocking_placeholder &&
(old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
{
- if (check_table_access(thd, SELECT_ACL, view_tables, FALSE,
- UINT_MAX, TRUE) &&
- check_table_access(thd, SHOW_VIEW_ACL, table, FALSE, UINT_MAX, TRUE))
+ /*
+ The user we run EXPLAIN as (either the connected user who issued
+ the EXPLAIN statement, or the definer of a SUID stored routine
+ which contains the EXPLAIN) should have both SHOW_VIEW_ACL and
+ SELECT_ACL on the view being opened as well as on all underlying
+ views since EXPLAIN will disclose their structure. This user also
+ should have SELECT_ACL on all underlying tables of the view since
+ this EXPLAIN will disclose information about the number of rows in it.
+
+ To perform this privilege check we create auxiliary TABLE_LIST object
+ for the view in order a) to avoid trashing "table->grant" member for
+ original table list element, which contents can be important at later
+ stage for column-level privilege checking b) get TABLE_LIST object
+ with "security_ctx" member set to 0, i.e. forcing check_table_access()
+ to use active user's security context.
+
+ There is no need for creating similar copies of TABLE_LIST elements
+ for underlying tables since they just have been constructed and thus
+ have TABLE_LIST::security_ctx == 0 and fresh TABLE_LIST::grant member.
+
+ Finally at this point making sure we have SHOW_VIEW_ACL on the views
+ will suffice as we implicitly require SELECT_ACL anyway.
+ */
+
+ TABLE_LIST view_no_suid;
+ bzero(static_cast<void *>(&view_no_suid), sizeof(TABLE_LIST));
+ view_no_suid.db= table->db;
+ view_no_suid.table_name= table->table_name;
+
+ DBUG_ASSERT(view_tables == NULL || view_tables->security_ctx == NULL);
+
+ if (check_table_access(thd, SELECT_ACL, view_tables,
+ FALSE, UINT_MAX, TRUE) ||
+ check_table_access(thd, SHOW_VIEW_ACL, &view_no_suid,
+ FALSE, UINT_MAX, TRUE))
{
my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
goto err;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 145c6c86714..87c3ae5b129 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9965,7 +9965,8 @@ limit_option:
}
splocal->limit_clause_param= TRUE;
$$= splocal;
- } | param_marker
+ }
+ | param_marker
{
((Item_param *) $1)->limit_clause_param= TRUE;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 045447873a9..4e01f7e1cf4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5240,14 +5240,15 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dict_col_copy_type(prebuilt->table->cols + i,
- dfield_get_type(&dfield));
-
if (n_len != UNIV_SQL_NULL) {
+ dict_col_copy_type(prebuilt->table->cols + i,
+ dfield_get_type(&dfield));
+
buf = row_mysql_store_col_in_innobase_format(
&dfield,
(byte*)buf,
@@ -5255,7 +5256,7 @@ calc_row_difference(
new_mysql_row_col,
col_pack_len,
dict_table_is_comp(prebuilt->table));
- dfield_copy_data(&ufield->new_val, &dfield);
+ dfield_copy(&ufield->new_val, &dfield);
} else {
dfield_set_null(&ufield->new_val);
}
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 89caf94ff46..6e311ce2e80 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -437,11 +437,9 @@ row_ins_cascade_calc_update_vec(
dict_table_t* table = foreign->foreign_table;
dict_index_t* index = foreign->foreign_index;
upd_t* update;
- upd_field_t* ufield;
dict_table_t* parent_table;
dict_index_t* parent_index;
upd_t* parent_update;
- upd_field_t* parent_ufield;
ulint n_fields_updated;
ulint parent_field_no;
ulint i;
@@ -477,13 +475,15 @@ row_ins_cascade_calc_update_vec(
dict_index_get_nth_col_no(parent_index, i));
for (j = 0; j < parent_update->n_fields; j++) {
- parent_ufield = parent_update->fields + j;
+ const upd_field_t* parent_ufield
+ = &parent_update->fields[j];
if (parent_ufield->field_no == parent_field_no) {
ulint min_size;
const dict_col_t* col;
ulint ufield_len;
+ upd_field_t* ufield;
col = dict_index_get_nth_col(index, i);
@@ -496,6 +496,8 @@ row_ins_cascade_calc_update_vec(
ufield->field_no
= dict_table_get_nth_col_pos(
table, dict_col_get_no(col));
+
+ ufield->orig_len = 0;
ufield->exp = NULL;
ufield->new_val = parent_ufield->new_val;
@@ -983,10 +985,9 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
- if ((node->is_delete
- && (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL))
- || (!node->is_delete
- && (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
+ if (node->is_delete
+ ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
+ : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
/* Build the appropriate update vector which sets
foreign->n_fields first fields in rec to SQL NULL */
@@ -995,6 +996,8 @@ row_ins_foreign_check_on_constraint(
update->info_bits = 0;
update->n_fields = foreign->n_fields;
+ UNIV_MEM_INVALID(update->fields,
+ update->n_fields * sizeof *update->fields);
for (i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
diff --git a/strings/decimal.c b/strings/decimal.c
index 954b04ea446..3a170728546 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1474,9 +1474,8 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
{
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
- intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
- intg1=ROUND_UP(from->intg +
- (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
+ intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
+
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
int first_dig;
@@ -1491,6 +1490,12 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
default: DBUG_ASSERT(0);
}
+ /*
+ For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
+ For internal testing here (ifdef MAIN) we always use len == 100/4
+ */
+ DBUG_ASSERT(from->len == to->len);
+
if (unlikely(frac0+intg0 > len))
{
frac0=len-intg0;
@@ -1504,17 +1509,17 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
return E_DEC_OK;
}
- if (to != from || intg1>intg0)
+ if (to != from)
{
dec1 *p0= buf0+intg0+max(frac1, frac0);
- dec1 *p1= buf1+intg1+max(frac1, frac0);
+ dec1 *p1= buf1+intg0+max(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
while (buf0 < p0)
*(--p1) = *(--p0);
- if (unlikely(intg1 > intg0))
- to->buf[0]= 0;
- intg0= intg1;
buf0=to->buf;
buf1=to->buf;
to->sign=from->sign;
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 4050f18c674..540ee574c28 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -19693,6 +19693,86 @@ static void test_bug11754979()
/*
+ Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
+*/
+static void test_bug13001491()
+{
+ int rc;
+ char query[MAX_TEST_QUERY_LENGTH];
+ MYSQL *c;
+
+ myheader("test_bug13001491");
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ c= mysql_client_init(NULL);
+
+ DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
+ current_db, opt_port, opt_unix_socket,
+ CLIENT_MULTI_STATEMENTS |
+ CLIENT_MULTI_RESULTS));
+
+ rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(c,
+ "CREATE PROCEDURE p1() "
+ "BEGIN "
+ " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
+ " SELECT COUNT(*) "
+ " FROM INFORMATION_SCHEMA.PROCESSLIST "
+ " GROUP BY user "
+ " ORDER BY NULL "
+ " INTO @a; "
+ "END");
+ myquery(rc);
+
+ rc= mysql_query(c, "CALL p1()");
+ myquery(rc);
+
+ mysql_free_result(mysql_store_result(c));
+
+ /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
+ rc= mysql_refresh(c, REFRESH_GRANT |
+ REFRESH_TABLES | REFRESH_HOSTS |
+ REFRESH_STATUS | REFRESH_THREADS);
+ myquery(rc);
+
+ /*
+ Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
+ fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
+ location.
+ */
+ mysql_refresh(c, REFRESH_LOG);
+
+ rc= mysql_query(c, "DROP PROCEDURE p1");
+ myquery(rc);
+
+ mysql_close(c);
+ c= NULL;
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "DROP USER mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+}
+
+
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -20038,6 +20118,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug11766854", test_bug11766854 },
{ "test_bug12337762", test_bug12337762 },
{ "test_bug11754979", test_bug11754979 },
+ { "test_bug13001491", test_bug13001491 },
{ 0, 0 }
};