diff options
author | Joerg Bruehe <joerg.bruehe@oracle.com> | 2012-05-07 22:20:42 +0200 |
---|---|---|
committer | Joerg Bruehe <joerg.bruehe@oracle.com> | 2012-05-07 22:20:42 +0200 |
commit | ad1e123f478e170cdbed5fd0e6a58277e61326ad (patch) | |
tree | fd4bc4e87a0385cd676cd34fe9ba93dd57358f2e | |
parent | 066dc9a281ee8932827f7e6180dd0fa1bfe5d922 (diff) | |
parent | 582b7283472a43af5d7fb51386df055ea9d44a96 (diff) | |
download | mariadb-git-ad1e123f478e170cdbed5fd0e6a58277e61326ad.tar.gz |
Merge 5.5.24 back into main 5.5.
This is a weave merge, but without any conflicts.
In 14 source files, the copyright year needed to be updated to 2012.
47 files changed, 755 insertions, 95 deletions
diff --git a/include/my_base.h b/include/my_base.h index d9f08a3c467..c10a325763e 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -1,5 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. - reserved +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,8 +10,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + /* This file includes constants used with all databases */ @@ -449,7 +449,8 @@ enum ha_base_keytype { #define HA_ERR_INDEX_COL_TOO_LONG 178 /* Index column length exceeds limit */ #define HA_ERR_INDEX_CORRUPT 179 /* Index corrupted */ #define HA_ERR_UNDO_REC_TOO_BIG 180 /* Undo log record too big */ -#define HA_ERR_LAST 180 /* Copy of last error nr */ +#define HA_ERR_TABLE_IN_FK_CHECK 181 /* Table being used in foreign key check */ +#define HA_ERR_LAST 181 /* Copy of last error nr */ /* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/include/violite.h b/include/violite.h index ba057028ed2..b35295caf5e 100644 --- a/include/violite.h +++ b/include/violite.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + along with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /* * Vio Lite. @@ -59,6 +59,9 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map, #define HANDLE void * #endif /* __WIN__ */ +/* backport from 5.6 where it is part of PSI, not vio_*() */ +int mysql_socket_shutdown(my_socket mysql_socket, int how); + void vio_delete(Vio* vio); int vio_close(Vio* vio); void vio_reset(Vio* vio, enum enum_vio_type type, diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/blackhole.result new file mode 100644 index 00000000000..317070ca08e --- /dev/null +++ b/mysql-test/r/blackhole.result @@ -0,0 +1,11 @@ +# +# Bug #11880012: INDEX_SUBQUERY, BLACKHOLE, +# HANG IN PREPARING WITH 100% CPU USAGE +# +CREATE TABLE t1(a INT NOT NULL); +INSERT INTO t1 VALUES (1), (2), (3); +CREATE TABLE t2 (a INT UNSIGNED, b INT, UNIQUE KEY (a, b)) ENGINE=BLACKHOLE; +SELECT 1 FROM t1 WHERE a = ANY (SELECT a FROM t2); +1 +DROP TABLE t1, t2; +End of 5.5 tests diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 89cbda9847c..736ef12968a 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -468,4 +468,13 @@ NULL Warnings: Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated SET @@GLOBAL.max_allowed_packet=default; +# +# Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET) +# +CREATE TABLE t1 (a VARCHAR(50)); +SELECT a FROM t1 +WHERE CAST(a as BINARY)=x'62736D697468' +AND CAST(a AS BINARY)=x'65736D697468'; +a +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index e6a1b492b39..3e1848b950f 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -146,3 +146,17 @@ ERROR 22003: BIGINT value is out of range in '(-(73) * -(2465717823867977728))' # # End Bug#57882 # +CREATE TABLE t1 (a INT); +CREATE TABLE t2(a INT PRIMARY KEY, b INT); +SELECT '' AS b FROM t1 GROUP BY VALUES(b); +ERROR 42S22: Unknown column '' in 'VALUES() function' +REPLACE t2(b) SELECT '' AS b FROM t1 GROUP BY VALUES(b); +ERROR 42S22: Unknown column '' in 'VALUES() function' +UPDATE t2 SET a=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +ERROR 42S22: Unknown column '' in 'VALUES() function' +INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE +b=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +ERROR 42S22: Unknown column '' in 'VALUES() function' +INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE +b=(SELECT VALUES(a)+2 FROM t1); +DROP TABLE t1, t2; diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index bcfc95bd905..46a36ad8276 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1077,6 +1077,19 @@ SPATIAL INDEX i1 (col1, col2) ERROR HY000: Incorrect arguments to SPATIAL INDEX DROP TABLE t0, t1, t2; # +# BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS +# +SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); +ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))) +NULL +# +# BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN +# GEOMETRY FUNCTION ARGUMENTS +# +SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); +ERROR 22007: Illegal non geometric '' value found during parsing +End of 5.1 tests +# # Bug#11908153: CRASH AND/OR VALGRIND ERRORS IN FIELD_BLOB::GET_KEY_IMAGE # CREATE TABLE g1 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 449dd6f2488..29725a6ba96 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5162,3 +5162,12 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#13721076 CRASH WITH TIME TYPE/TIMESTAMP() AND WARNINGS IN SUBQUERY +# +CREATE TABLE t1(a TIME NOT NULL); +INSERT INTO t1 VALUES ('00:00:32'); +SELECT 1 FROM t1 WHERE a > +(SELECT timestamp(a) AS a FROM t1); +1 +DROP TABLE t1; diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index ab623ad6a28..40e167e87db 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -254,3 +254,63 @@ SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a); a b 2011-05-13 0 DROP TABLE t1; +# +# Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE +# +CREATE TABLE t1 (a INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB; +SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); +1 +1 +EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where +2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY,d d 2 func 1 Using where +3 DEPENDENT SUBQUERY t2 index NULL d 2 NULL 1 Using where; Using index +DROP TABLE t2; +CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB; +INSERT INTO t2 VALUES (1, 1); +SELECT 1 FROM t1 +WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c); +1 +DROP TABLE t1, t2; +# +# Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE +# INDEX +# +CREATE TABLE t1 ( +id int +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (11); +CREATE TABLE t2 ( +t1_id int, +position int, +KEY t1_id (t1_id), +KEY t1_id_position (t1_id,position) +) ENGINE=InnoDB; +EXPLAIN SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY t2 ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 Using where +SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; +maxkey +NULL +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 589186184c3..b0859658077 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -485,4 +485,10 @@ f1 f2 1 4 DROP TRIGGER trg1; DROP TABLE t1; +# +# Bug #12408412: GROUP_CONCAT + ORDER BY + INPUT/OUTPUT +# SAME USER VARIABLE = CRASH +# +SET @bug12408412=1; +SELECT GROUP_CONCAT(@bug12408412 ORDER BY 1) INTO @bug12408412; End of 5.5 tests diff --git a/mysql-test/suite/innodb/r/innodb_bug13635833.result b/mysql-test/suite/innodb/r/innodb_bug13635833.result new file mode 100644 index 00000000000..6a505bc94f2 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug13635833.result @@ -0,0 +1,45 @@ +SET DEBUG_SYNC='reset'; +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); +alter table t2 add constraint c1 foreign key (f1) +references t1(f1) on update cascade; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + KEY `k1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) DEFAULT NULL, + `f2` int(11) DEFAULT NULL, + KEY `f1` (`f1`), + KEY `f2` (`f2`), + CONSTRAINT `c1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f2` int(11) DEFAULT NULL, + KEY `f2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET DEBUG_SYNC='innodb_rename_table_ready SIGNAL update_can_proceed + WAIT_FOR dict_unfreeze'; +alter table t2 add constraint z1 foreign key (f2) +references t3(f2) on update cascade; +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; +update ignore t1 set f1 = 20; +ERROR HY000: Error on rename of './test/t2' to '#sql2-temporary' (errno: 181) +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; +drop table t2; +drop table t1; +drop table t3; +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/innodb/t/innodb_bug13635833.test b/mysql-test/suite/innodb/t/innodb_bug13635833.test new file mode 100644 index 00000000000..47185b9d526 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug13635833.test @@ -0,0 +1,64 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/not_embedded.inc + +SET DEBUG_SYNC='reset'; + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; + +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); + +alter table t2 add constraint c1 foreign key (f1) + references t1(f1) on update cascade; + +show create table t1; +show create table t2; +show create table t3; + +SET DEBUG_SYNC='innodb_rename_table_ready SIGNAL update_can_proceed + WAIT_FOR dict_unfreeze'; + +--send +alter table t2 add constraint z1 foreign key (f2) + references t3(f2) on update cascade; + +connect (thr2,localhost,root,,); +connection thr2; + +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; + +--send +update ignore t1 set f1 = 20; + +connection default; +--replace_regex /'[^']*test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/ +--error ER_ERROR_ON_RENAME +reap; + +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; + +connection thr2; +reap; +disconnect thr2; +--source include/wait_until_disconnected.inc + +connection default; + +drop table t2; +drop table t1; +drop table t3; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/rpl/r/rpl_row_merge_engine.result b/mysql-test/suite/rpl/r/rpl_row_merge_engine.result new file mode 100644 index 00000000000..c61167e84e0 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_merge_engine.result @@ -0,0 +1,16 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1 (a int) ENGINE=MyISAM; +CREATE TABLE t2 (a int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (4), (5), (6); +CREATE TABLE IF NOT EXISTS t1_merge LIKE t1; +ALTER TABLE t1_merge ENGINE=MERGE UNION (t2, t1); +include/diff_tables.inc [master:test.t1, slave:test.t1] +include/diff_tables.inc [master:test.t2, slave:test.t2] +UPDATE t1_merge SET a=10 WHERE a=1; +DELETE FROM t1_merge WHERE a=10; +include/diff_tables.inc [master:test.t1, slave:test.t1] +include/diff_tables.inc [master:test.t2, slave:test.t2] +DROP TABLE t1_merge, t1, t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_merge_engine.test b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test new file mode 100644 index 00000000000..5add8dc1cda --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test @@ -0,0 +1,50 @@ +# +# BUG#47103 +# +# This test case checks whether the slave crashes or not when there is +# a merge table in use. +# +# Description +# =========== +# +# The test case creates two regular MyISAM tables on the master and +# one MERGE table. Then it populates the MyISAM tables, updates and +# deletes their contents through the merge table. Finally, the slave +# is synchronized with the master and (after the fix) it won't crash. +# +--source include/master-slave.inc +--source include/have_binlog_format_row.inc +--connection master + +CREATE TABLE t1 (a int) ENGINE=MyISAM; +CREATE TABLE t2 (a int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1), (2), (3); +INSERT INTO t2 VALUES (4), (5), (6); +CREATE TABLE IF NOT EXISTS t1_merge LIKE t1; +ALTER TABLE t1_merge ENGINE=MERGE UNION (t2, t1); + +--sync_slave_with_master + +--let diff_tables=master:test.t1, slave:test.t1 +--source include/diff_tables.inc + +--let diff_tables=master:test.t2, slave:test.t2 +--source include/diff_tables.inc + +--connection master +UPDATE t1_merge SET a=10 WHERE a=1; +DELETE FROM t1_merge WHERE a=10; + +--sync_slave_with_master +--connection master + +--let diff_tables=master:test.t1, slave:test.t1 +--source include/diff_tables.inc + +--let diff_tables=master:test.t2, slave:test.t2 +--source include/diff_tables.inc + +DROP TABLE t1_merge, t1, t2; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test new file mode 100644 index 00000000000..1451f7606e0 --- /dev/null +++ b/mysql-test/t/blackhole.test @@ -0,0 +1,21 @@ +# +# Tests for the BLACKHOLE storage engine +# + +--source include/have_blackhole.inc + +--echo # +--echo # Bug #11880012: INDEX_SUBQUERY, BLACKHOLE, +--echo # HANG IN PREPARING WITH 100% CPU USAGE +--echo # + +CREATE TABLE t1(a INT NOT NULL); +INSERT INTO t1 VALUES (1), (2), (3); +CREATE TABLE t2 (a INT UNSIGNED, b INT, UNIQUE KEY (a, b)) ENGINE=BLACKHOLE; + +SELECT 1 FROM t1 WHERE a = ANY (SELECT a FROM t2); + +DROP TABLE t1, t2; + +--echo End of 5.5 tests + diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index a922cc9aaf7..3ba684a9b25 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -295,4 +295,16 @@ connection default; disconnect newconn; SET @@GLOBAL.max_allowed_packet=default; +--echo # +--echo # Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET) +--echo # + +CREATE TABLE t1 (a VARCHAR(50)); + +SELECT a FROM t1 +WHERE CAST(a as BINARY)=x'62736D697468' + AND CAST(a AS BINARY)=x'65736D697468'; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 82822c87e89..82204e1bfac 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -171,3 +171,21 @@ SELECT UPDATEXML(-73 * -2465717823867977728,@@global.auto_increment_increment,nu --echo # --echo # End Bug#57882 --echo # + +# +# Bug #13031606 VALUES() IN A SELECT STATEMENT CRASHES SERVER +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2(a INT PRIMARY KEY, b INT); +--error ER_BAD_FIELD_ERROR +SELECT '' AS b FROM t1 GROUP BY VALUES(b); +--error ER_BAD_FIELD_ERROR +REPLACE t2(b) SELECT '' AS b FROM t1 GROUP BY VALUES(b); +--error ER_BAD_FIELD_ERROR +UPDATE t2 SET a=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +--error ER_BAD_FIELD_ERROR +INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE + b=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE + b=(SELECT VALUES(a)+2 FROM t1); +DROP TABLE t1, t2; diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index e75ae732979..d10192aa3c5 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -820,6 +820,24 @@ CREATE TABLE t3 ( # cleanup DROP TABLE t0, t1, t2; + +--echo # +--echo # BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS +--echo # +SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); + +--echo # +--echo # BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN +--echo # GEOMETRY FUNCTION ARGUMENTS +--echo # +--replace_regex /non geometric .* value/non geometric '' value/ +--error ER_ILLEGAL_VALUE_FOR_TYPE +SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); + + +--echo End of 5.1 tests + + --echo # --echo # Bug#11908153: CRASH AND/OR VALGRIND ERRORS IN FIELD_BLOB::GET_KEY_IMAGE --echo # diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3e4fc8484aa..fa63340a718 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4122,4 +4122,14 @@ SELECT 1 FROM DROP TABLE t1; +--echo # +--echo # Bug#13721076 CRASH WITH TIME TYPE/TIMESTAMP() AND WARNINGS IN SUBQUERY +--echo # + +CREATE TABLE t1(a TIME NOT NULL); +INSERT INTO t1 VALUES ('00:00:32'); +SELECT 1 FROM t1 WHERE a > +(SELECT timestamp(a) AS a FROM t1); + +DROP TABLE t1; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 73491417e0c..ffefc3a2800 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -247,3 +247,61 @@ CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb; INSERT INTO t1 VALUES ('2011-05-13', 0); SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a); DROP TABLE t1; + + +--echo # +--echo # Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE +--echo # + +CREATE TABLE t1 (a INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB; + +SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); + +EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); + +DROP TABLE t2; + +CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB; +INSERT INTO t2 VALUES (1, 1); + +SELECT 1 FROM t1 +WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c); + +DROP TABLE t1, t2; + +--echo # +--echo # Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE +--echo # INDEX +--echo # +CREATE TABLE t1 ( +id int +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (11); + +CREATE TABLE t2 ( +t1_id int, +position int, +KEY t1_id (t1_id), +KEY t1_id_position (t1_id,position) +) ENGINE=InnoDB; + +let $query=SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; + +eval EXPLAIN $query; +eval $query; + +DROP TABLE t1,t2; + +--echo End of 5.1 tests + diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 6a64343b609..fa23d118634 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -404,4 +404,13 @@ SELECT f1, f2 FROM t1 ORDER BY f2; DROP TRIGGER trg1; DROP TABLE t1; + +--echo # +--echo # Bug #12408412: GROUP_CONCAT + ORDER BY + INPUT/OUTPUT +--echo # SAME USER VARIABLE = CRASH +--echo # + +SET @bug12408412=1; +SELECT GROUP_CONCAT(@bug12408412 ORDER BY 1) INTO @bug12408412; + --echo End of 5.5 tests diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h index 3533b633960..1c2f02f26cb 100644 --- a/mysys/my_handler_errors.h +++ b/mysys/my_handler_errors.h @@ -1,7 +1,7 @@ #ifndef MYSYS_MY_HANDLER_ERRORS_INCLUDED #define MYSYS_MY_HANDLER_ERRORS_INCLUDED -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /* Errors a handler can give you @@ -83,7 +83,8 @@ static const char *handler_error_messages[]= "Too many active concurrent transactions", "Index column length exceeds limit", "Index corrupted", - "Undo record too big" + "Undo record too big", + "Table is being used in foreign key check" }; extern void my_handler_error_register(void); diff --git a/sql/field.cc b/sql/field.cc index 59eb83da5fa..4fcf5b33dc1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -8257,7 +8257,19 @@ String *Field_set::val_str(String *val_buffer, ulonglong tmp=(ulonglong) Field_enum::val_int(); uint bitnr=0; - val_buffer->set("", 0, field_charset); + if (tmp == 0) + { + /* + Some callers expect *val_buffer to contain the result, + so we assign to it, rather than doing 'return &empty_set_string. + */ + *val_buffer= empty_set_string; + return val_buffer; + } + + val_buffer->set_charset(field_charset); + val_buffer->length(0); + while (tmp && bitnr < (uint) typelib->count) { if (tmp & 1) diff --git a/sql/field.h b/sql/field.h index b4adb764b22..d9f0b892adb 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1,7 +1,7 @@ #ifndef FIELD_INCLUDED #define FIELD_INCLUDED -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1985,7 +1985,8 @@ public: :Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, packlength_arg, - typelib_arg,charset_arg) + typelib_arg,charset_arg), + empty_set_string("", 0, charset_arg) { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } @@ -1996,8 +1997,11 @@ public: virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; + uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_SET; } bool has_charset(void) const { return TRUE; } +private: + const String empty_set_string; }; @@ -2192,6 +2196,8 @@ public: { return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0; } +private: + const String empty_set_string; }; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 594449174bc..17b0d34557a 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -317,10 +317,11 @@ static void do_save_blob(Copy_field *copy) static void do_field_string(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; - copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset()); - copy->from_field->val_str(©->tmp); - copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(), - copy->tmp.charset()); + String res(buff, sizeof(buff), copy->from_field->charset()); + res.length(0U); + + copy->from_field->val_str(&res); + copy->to_field->store(res.c_ptr_quick(), res.length(), res.charset()); } @@ -563,7 +564,7 @@ void Copy_field::set(uchar *to,Field *from) /* To do: - If 'save\ is set to true and the 'from' is a blob field, do_copy is set to + If 'save' is set to true and the 'from' is a blob field, do_copy is set to do_save_blob rather than do_conv_blob. The only differences between them appears to be: diff --git a/sql/handler.cc b/sql/handler.cc index c3c70109daa..b2cb7f1cf9a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /** @file handler.cc @@ -437,6 +437,7 @@ int ha_init_errors(void) SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER_DEFAULT(ER_TOO_MANY_CONCURRENT_TRXS)); SETMSG(HA_ERR_INDEX_COL_TOO_LONG, ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG)); SETMSG(HA_ERR_INDEX_CORRUPT, ER_DEFAULT(ER_INDEX_CORRUPT)); + SETMSG(HA_ERR_TABLE_IN_FK_CHECK, ER_DEFAULT(ER_TABLE_IN_FK_CHECK)); /* Register the error messages for use with my_error(). */ return my_error_register(get_handler_errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -2964,6 +2965,9 @@ void handler::print_error(int error, myf errflag) case HA_ERR_UNDO_REC_TOO_BIG: textno= ER_UNDO_RECORD_TOO_BIG; break; + case HA_ERR_TABLE_IN_FK_CHECK: + textno= ER_TABLE_IN_FK_CHECK; + break; default: { /* The error was "unknown" to this function. diff --git a/sql/item.cc b/sql/item.cc index 69821df986a..22b5adc4597 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7078,20 +7078,12 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) } if (arg->type() == REF_ITEM) + arg= static_cast<Item_ref *>(arg)->ref[0]; + if (arg->type() != FIELD_ITEM) { - Item_ref *ref= (Item_ref *)arg; - if (ref->ref[0]->type() != FIELD_ITEM) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); - return TRUE; - } - arg= ref->ref[0]; + my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); + return TRUE; } - /* - According to our SQL grammar, VALUES() function can reference - only to a column. - */ - DBUG_ASSERT(arg->type() == FIELD_ITEM); Item_field *field_arg= (Item_field *)arg; @@ -7655,6 +7647,33 @@ bool Item_cache_datetime::cache_value() str_value.copy(*res); null_value= example->null_value; unsigned_flag= example->unsigned_flag; + + if (!null_value) + { + switch(field_type()) + { + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: + { + MYSQL_TIME ltime; + int was_cut; + const timestamp_type tt= + str_to_datetime(str_value.charset(), + str_value.ptr(), + str_value.length(), + <ime, + TIME_DATETIME_ONLY, + &was_cut); + if (tt != MYSQL_TIMESTAMP_DATETIME || was_cut) + null_value= true; + else + my_datetime_to_str(<ime, const_cast<char*>(str_value.ptr())); + } + default: + {} + } + } + return TRUE; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a6bcdbd8645..97b8dbbe113 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -182,6 +182,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) (*ref)= substitution; substitution->name= name; + substitution->name_length= name_length; if (have_to_be_excluded) engine->exclude(); substitution= 0; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ddb00874b62..6fc85a01668 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2694,7 +2694,7 @@ longlong Item_datetime_typecast::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (get_arg0_date(<ime,1)) + if (get_arg0_date(<ime, TIME_FUZZY_DATE)) { null_value= 1; return 0; diff --git a/sql/log_event.cc b/sql/log_event.cc index 1f49155bf7f..76ff852107b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -7697,9 +7697,24 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p", rli->tables_to_lock)); + + /** + When using RBR and MyISAM MERGE tables the base tables that make + up the MERGE table can be appended to the list of tables to lock. + + Thus, we just check compatibility for those that tables that have + a correspondent table map event (ie, those that are actually going + to be accessed while applying the event). That's why the loop stops + at rli->tables_to_lock_count . + + NOTE: The base tables are added here are removed when + close_thread_tables is called. + */ RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global)) + for (uint i= 0 ; ptr && (i < rli->tables_to_lock_count); + ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) { + DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), ptr->table, &conv_table)) @@ -7737,10 +7752,10 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) Rows_log_event, we can invalidate the query cache for the associated table. */ - for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global) - { + TABLE_LIST *ptr= rli->tables_to_lock; + for (uint i=0 ; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++) const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table); - } + #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); #endif @@ -8522,9 +8537,9 @@ check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list) res= FILTERED_OUT; else { - for(RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock); - ptr; - ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local)) + RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock); + for(uint i=0 ; ptr && (i< rli->tables_to_lock_count); + ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++) { if (ptr->table_id == table_list->table_id) { diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 4aa8c0959b1..d68c474d00a 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -126,8 +126,10 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info { RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global)) + for (uint i= 0 ; ptr&& (i< rli->tables_to_lock_count); + ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) { + DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), ptr->table, &conv_table)) @@ -158,10 +160,9 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info Old_rows_log_event, we can invalidate the query cache for the associated table. */ - for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global) - { + TABLE_LIST *ptr= rli->tables_to_lock; + for (uint i=0; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++) const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table); - } #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); #endif @@ -1539,7 +1540,8 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) { RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global)) + for (uint i= 0 ; ptr&& (i< rli->tables_to_lock_count); + ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) { TABLE *conv_table; if (ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli), diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 63656460f42..a37a9701fe7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1045,7 +1045,7 @@ static void close_connections(void) { if (ip_sock != INVALID_SOCKET) { - (void) shutdown(ip_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(ip_sock, SHUT_RDWR); (void) closesocket(ip_sock); ip_sock= INVALID_SOCKET; } @@ -1077,7 +1077,7 @@ static void close_connections(void) #ifdef HAVE_SYS_UN_H if (unix_sock != INVALID_SOCKET) { - (void) shutdown(unix_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR); (void) closesocket(unix_sock); (void) unlink(mysqld_unix_port); unix_sock= INVALID_SOCKET; @@ -1184,14 +1184,14 @@ static void close_server_sock() { ip_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on TCP/IP socket")); - (void) shutdown(tmp_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(tmp_sock, SHUT_RDWR); } tmp_sock=unix_sock; if (tmp_sock != INVALID_SOCKET) { unix_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on unix socket")); - (void) shutdown(tmp_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(tmp_sock, SHUT_RDWR); (void) unlink(mysqld_unix_port); } DBUG_VOID_RETURN; @@ -5266,7 +5266,7 @@ void handle_connections_sockets() if (req.sink) ((void (*)(int))req.sink)(req.fd); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5282,7 +5282,7 @@ void handle_connections_sockets() (SOCKET_SIZE_TYPE *)&dummyLen) < 0 ) { sql_perror("Error on new connection socket"); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5294,7 +5294,7 @@ void handle_connections_sockets() if (!(thd= new THD)) { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5313,7 +5313,7 @@ void handle_connections_sockets() vio_delete(vio_tmp); else { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); } delete thd; diff --git a/sql/password.c b/sql/password.c index ca194204360..afa514a6c53 100644 --- a/sql/password.c +++ b/sql/password.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -531,7 +531,7 @@ check_scramble(const uchar *scramble_arg, const char *message, mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, hash_stage2_reassured); - return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); + return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE)); } diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 607bd092b73..2d302011b44 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1264,6 +1264,23 @@ void Relay_log_info::cleanup_context(THD *thd, bool error) void Relay_log_info::clear_tables_to_lock() { + DBUG_ENTER("Relay_log_info::clear_tables_to_lock()"); +#ifndef DBUG_OFF + /** + When replicating in RBR and MyISAM Merge tables are involved + open_and_lock_tables (called in do_apply_event) appends the + base tables to the list of tables_to_lock. Then these are + removed from the list in close_thread_tables (which is called + before we reach this point). + + This assertion just confirms that we get no surprises at this + point. + */ + uint i=0; + for (TABLE_LIST *ptr= tables_to_lock ; ptr ; ptr= ptr->next_global, i++) ; + DBUG_ASSERT(i == tables_to_lock_count); +#endif + while (tables_to_lock) { uchar* to_free= reinterpret_cast<uchar*>(tables_to_lock); @@ -1288,10 +1305,12 @@ void Relay_log_info::clear_tables_to_lock() my_free(to_free); } DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0); + DBUG_VOID_RETURN; } void Relay_log_info::slave_close_thread_tables(THD *thd) { + DBUG_ENTER("Relay_log_info::slave_close_thread_tables(THD *thd)"); thd->stmt_da->can_overwrite_status= TRUE; thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); thd->stmt_da->can_overwrite_status= FALSE; @@ -1313,5 +1332,6 @@ void Relay_log_info::slave_close_thread_tables(THD *thd) thd->mdl_context.release_statement_locks(); clear_tables_to_lock(); + DBUG_VOID_RETURN; } #endif diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index c8cacd22303..263dd0ffeb7 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6497,6 +6497,9 @@ ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC ER_BINLOG_UNSAFE_INSERT_TWO_KEYS eng "INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe" +ER_TABLE_IN_FK_CHECK + eng "Table is being used in foreign key check." + ER_UNSUPPORTED_ENGINE eng "Storage engine '%s' does not support system tables. [%s.%s]" diff --git a/sql/spatial.cc b/sql/spatial.cc index ee701d82657..894f2a1dae5 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -609,7 +609,8 @@ int Gis_line_string::is_closed(int *closed) const return 0; } data+= 4; - if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + if (n_points == 0 || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; /* Get first point */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6660f848653..bdcb85218c3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2861,13 +2861,42 @@ bool select_exists_subselect::send_data(List<Item> &items) int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { unit= u; + List_iterator_fast<my_var> var_li(var_list); + List_iterator_fast<Item> it(list); + Item *item; + my_var *mv; + Item_func_set_user_var **suv; if (var_list.elements != list.elements) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0)); return 1; - } + } + + /* + Iterate over the destination variables and mark them as being + updated in this query. + We need to do this at JOIN::prepare time to ensure proper + const detection of Item_func_get_user_var that is determined + by the presence of Item_func_set_user_vars + */ + + suv= set_var_items= (Item_func_set_user_var **) + sql_alloc(sizeof(Item_func_set_user_var *) * list.elements); + + while ((mv= var_li++) && (item= it++)) + { + if (!mv->local) + { + *suv= new Item_func_set_user_var(mv->s, item); + (*suv)->fix_fields(thd, 0); + } + else + *suv= NULL; + suv++; + } + return 0; } @@ -3184,6 +3213,7 @@ bool select_dumpvar::send_data(List<Item> &items) List_iterator<Item> it(items); Item *item; my_var *mv; + Item_func_set_user_var **suv; DBUG_ENTER("select_dumpvar::send_data"); if (unit->offset_limit_cnt) @@ -3196,20 +3226,19 @@ bool select_dumpvar::send_data(List<Item> &items) my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); DBUG_RETURN(1); } - while ((mv= var_li++) && (item= it++)) + for (suv= set_var_items; ((mv= var_li++) && (item= it++)); suv++) { if (mv->local) { + DBUG_ASSERT(!*suv); if (thd->spcont->set_variable(thd, mv->offset, &item)) DBUG_RETURN(1); } else { - Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item); - if (suv->fix_fields(thd, 0)) - DBUG_RETURN (1); - suv->save_item_result(item); - if (suv->update()) + DBUG_ASSERT(*suv); + (*suv)->save_item_result(item); + if ((*suv)->update()) DBUG_RETURN (1); } } diff --git a/sql/sql_class.h b/sql/sql_class.h index f107bfe4a69..bffa490ebe3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3533,6 +3533,7 @@ public: class select_dumpvar :public select_result_interceptor { ha_rows row_count; + Item_func_set_user_var **set_var_items; public: List<my_var> var_list; select_dumpvar() { var_list.empty(); row_count= 0;} diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 423c59d34cc..3c709e3c0ea 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -5890,6 +5890,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } keyuse++; } while (keyuse->table == table && keyuse->key == key); + DBUG_ASSERT(length > 0 && keyparts != 0); } /* not ftkey */ /* set up fieldref */ @@ -13698,6 +13699,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, DBUG_ENTER("test_if_skip_sort_order"); LINT_INIT(ref_key_parts); + /* Check that we are always called with first non-const table */ + DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables); + /* Keys disabled by ALTER TABLE ... DISABLE KEYS should have already been taken into account. @@ -13779,7 +13783,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, while (keyuse->key != new_ref_key && keyuse->table == tab->table) keyuse++; if (create_ref_for_key(tab->join, tab, keyuse, - tab->join->const_table_map)) + (tab->join->const_table_map | + OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); pick_table_access_method(tab); diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index c12d5afbfa5..5fea81fd269 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -151,6 +151,7 @@ int ha_blackhole::rnd_next(uchar *buf) else rc= HA_ERR_END_OF_FILE; MYSQL_READ_ROW_DONE(rc); + table->status= rc ? STATUS_NOT_FOUND : 0; DBUG_RETURN(rc); } @@ -241,6 +242,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, else rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= rc ? STATUS_NOT_FOUND : 0; DBUG_RETURN(rc); } @@ -258,6 +260,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, else rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= rc ? STATUS_NOT_FOUND : 0; DBUG_RETURN(rc); } @@ -274,6 +277,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, else rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= rc ? STATUS_NOT_FOUND : 0; DBUG_RETURN(rc); } @@ -285,6 +289,7 @@ int ha_blackhole::index_next(uchar * buf) MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(rc); } @@ -296,6 +301,7 @@ int ha_blackhole::index_prev(uchar * buf) MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(rc); } @@ -307,8 +313,8 @@ int ha_blackhole::index_first(uchar * buf) MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(rc); - DBUG_RETURN(HA_ERR_END_OF_FILE); } @@ -319,6 +325,7 @@ int ha_blackhole::index_last(uchar * buf) MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); rc= HA_ERR_END_OF_FILE; MYSQL_INDEX_READ_ROW_DONE(rc); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(rc); } diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index ce4988c1bfd..5be94a10374 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -55,6 +55,8 @@ UNIV_INTERN dict_index_t* dict_ind_compact; #include "m_ctype.h" /* my_isspace() */ #include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/ #include "row0upd.h" +#include "m_string.h" +#include "my_sys.h" #include <ctype.h> @@ -2329,6 +2331,8 @@ dict_foreign_free( /*==============*/ dict_foreign_t* foreign) /*!< in, own: foreign key struct */ { + ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0); + mem_heap_free(foreign->heap); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6ef2b7b3a0d..b00b5f08ca0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -998,6 +998,9 @@ convert_error_code_to_mysql( case DB_OUT_OF_FILE_SPACE: return(HA_ERR_RECORD_FILE_FULL); + case DB_TABLE_IN_FK_CHECK: + return(HA_ERR_TABLE_IN_FK_CHECK); + case DB_TABLE_IS_BEING_USED: return(HA_ERR_WRONG_COMMAND); @@ -5852,6 +5855,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); ut_a(prebuilt->trx == thd_to_trx(user_thd)); + ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); ha_statistic_increment(&SSV::ha_read_key_count); @@ -7593,6 +7597,8 @@ innobase_rename_table( normalize_table_name(norm_to, to); normalize_table_name(norm_from, from); + DEBUG_SYNC_C("innodb_rename_table_ready"); + /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index e0952f0709d..95ccef16be0 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -112,6 +112,8 @@ enum db_err { limit */ DB_INDEX_CORRUPT, /* we have corrupted index */ DB_UNDO_RECORD_TOO_BIG, /* the undo log record is too big */ + DB_TABLE_IN_FK_CHECK, /* table is being used in foreign + key check */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 71c75469ee9..3394fc576cb 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -303,11 +303,17 @@ management to ensure correct alignment for doubles etc. */ /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 -/* The maximum length of a table name. This is the MySQL limit and is -defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the -number does not include a terminating '\0'. InnoDB probably can handle -longer names internally */ -#define MAX_TABLE_NAME_LEN 192 +/** This is the "mbmaxlen" for my_charset_filename (defined in +strings/ctype-utf8.c), which is used to encode File and Database names. */ +#define FILENAME_CHARSET_MAXNAMLEN 5 + +/** The maximum length of an encode table name in bytes. The max +table and database names are NAME_CHAR_LEN (64) characters. After the +encoding, the max length would be NAME_CHAR_LEN (64) * +FILENAME_CHARSET_MAXNAMLEN (5) = 320 bytes. The number does not include a +terminating '\0'. InnoDB can handle longer names internally */ +#define MAX_TABLE_NAME_LEN 320 + /* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is the MySQL's NAME_LEN, see check_and_convert_db_name(). */ diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index d02d0e986aa..2b77c6f929d 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -49,6 +49,8 @@ Created 4/20/1996 Heikki Tuuri #include "data0data.h" #include "usr0sess.h" #include "buf0lru.h" +#include "m_string.h" +#include "my_sys.h" #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 @@ -1085,6 +1087,9 @@ row_ins_foreign_check_on_constraint( release the latch. */ row_mysql_unfreeze_data_dictionary(thr_get_trx(thr)); + + DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze"); + row_mysql_freeze_data_dictionary(thr_get_trx(thr)); mtr_start(mtr); diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 8ea09b5c6ee..20e8c13ea70 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -51,6 +51,9 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "fil0fil.h" #include "ibuf0ibuf.h" +#include "m_string.h" +#include "my_sys.h" + /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; @@ -1443,6 +1446,8 @@ row_update_for_mysql( return(DB_ERROR); } + DEBUG_SYNC_C("innodb_row_update_for_mysql_begin"); + trx->op_info = "updating or deleting"; row_mysql_delay_if_needed(); @@ -3828,6 +3833,7 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; + int retry; ut_a(old_name != NULL); ut_a(new_name != NULL); @@ -3910,6 +3916,25 @@ row_rename_table_for_mysql( } } + /* Is a foreign key check running on this table? */ + for (retry = 0; retry < 100 + && table->n_foreign_key_checks_running > 0; ++retry) { + row_mysql_unlock_data_dictionary(trx); + os_thread_yield(); + row_mysql_lock_data_dictionary(trx); + } + + if (table->n_foreign_key_checks_running > 0) { + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: in ALTER TABLE ", stderr); + ut_print_name(stderr, trx, TRUE, old_name); + fprintf(stderr, "\n" + "InnoDB: a FOREIGN KEY check is running.\n" + "InnoDB: Cannot rename table.\n"); + err = DB_TABLE_IN_FK_CHECK; + goto funct_exit; + } + /* We use the private SQL parser of Innobase to generate the query graphs needed in updating the dictionary data from system tables. */ diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index f6dfb3ba0b3..117a777cb98 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, Oracle Corpn. All Rights Reserved. +Copyright (c) 2011, 2012, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -718,6 +718,8 @@ ut_strerr( return("Undo record too big"); case DB_END_OF_INDEX: return("End of index"); + case DB_TABLE_IN_FK_CHECK: + return("Table is being used in foreign key check"); /* do not add default: in order to produce a warning if new code is added to the enum but not added here */ } diff --git a/vio/viosocket.c b/vio/viosocket.c index 6031cf6a795..56aa84df5fc 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,6 +23,11 @@ the file descriptior. */ +#ifdef __WIN__ + #include <winsock2.h> + #include <MSWSock.h> + #pragma comment(lib, "ws2_32.lib") +#endif #include "vio_priv.h" #ifdef FIONREAD_IN_SYS_FILIO @@ -277,6 +282,37 @@ vio_was_interrupted(Vio *vio __attribute__((unused))) } +int +mysql_socket_shutdown(my_socket mysql_socket, int how) +{ + int result; + +#ifdef __WIN__ + static LPFN_DISCONNECTEX DisconnectEx = NULL; + if (DisconnectEx == NULL) + { + DWORD dwBytesReturned; + GUID guidDisconnectEx = WSAID_DISCONNECTEX; + WSAIoctl(mysql_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, + &guidDisconnectEx, sizeof(GUID), + &DisconnectEx, sizeof(DisconnectEx), + &dwBytesReturned, NULL, NULL); + } +#endif + + /* Non instrumented code */ +#ifdef __WIN__ + if (DisconnectEx) + result= (DisconnectEx(mysql_socket, (LPOVERLAPPED) NULL, + (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1; + else +#endif + result= shutdown(mysql_socket, how); + + return result; +} + + int vio_close(Vio * vio) { int r=0; @@ -289,7 +325,7 @@ int vio_close(Vio * vio) vio->type == VIO_TYPE_SSL); DBUG_ASSERT(vio->sd >= 0); - if (shutdown(vio->sd, SHUT_RDWR)) + if (mysql_socket_shutdown(vio->sd, SHUT_RDWR)) r= -1; if (closesocket(vio->sd)) r= -1; |