#At file:///usr/local/devel/bzrroot/server/mysql-5.1-innodb/ based on revid:vasil.dimov@stripped
3456 Vasil Dimov 2010-05-11 [merge]
Merge mysql-5.1 into mysql-5.1-innodb
added:
mysql-test/r/bug46261.result
mysql-test/suite/sys_vars/r/secure_file_priv.result
mysql-test/suite/sys_vars/t/secure_file_priv-master.opt
mysql-test/suite/sys_vars/t/secure_file_priv.test
mysql-test/t/bug46261-master.opt
mysql-test/t/bug46261.test
modified:
configure.in
dbug/dbug.c
include/my_global.h
include/mysql/plugin.h
include/mysql/plugin.h.pp
include/mysql_com.h
mysql-test/include/mtr_warnings.sql
mysql-test/r/ctype_ucs.result
mysql-test/r/error_simulation.result
mysql-test/r/explain.result
mysql-test/r/grant.result
mysql-test/r/innodb_mysql.result
mysql-test/r/join.result
mysql-test/r/loaddata.result*
mysql-test/r/ps.result
mysql-test/r/row.result
mysql-test/r/trigger.result
mysql-test/r/variables_debug.result
mysql-test/r/view.result
mysql-test/suite/engines/README
mysql-test/suite/engines/funcs/t/disabled.def
mysql-test/suite/engines/iuds/r/insert_year.result
mysql-test/suite/engines/iuds/r/update_delete_calendar.result
mysql-test/suite/engines/iuds/t/disabled.def
mysql-test/suite/engines/iuds/t/insert_number.test
mysql-test/suite/engines/iuds/t/update_delete_calendar.test
mysql-test/suite/rpl/r/rpl_do_grant.result
mysql-test/suite/rpl/t/rpl_do_grant.test
mysql-test/t/ctype_ucs.test
mysql-test/t/error_simulation.test
mysql-test/t/explain.test
mysql-test/t/grant.test
mysql-test/t/innodb_mysql.test
mysql-test/t/join.test
mysql-test/t/loaddata.test
mysql-test/t/ps.test
mysql-test/t/row.test
mysql-test/t/trigger.test
mysql-test/t/variables_debug.test
mysql-test/t/view.test
mysys/mf_loadpath.c
mysys/my_file.c
mysys/my_getwd.c
scripts/mysqld_safe.sh
scripts/mysqlhotcopy.sh
sql/CMakeLists.txt
sql/field.cc
sql/ha_ndbcluster.cc
sql/handler.cc
sql/handler.h
sql/item.cc
sql/item.h
sql/item_cmpfunc.h
sql/item_strfunc.cc
sql/item_subselect.cc
sql/item_subselect.h
sql/mysql_priv.h
sql/mysqld.cc
sql/net_serv.cc
sql/partition_info.cc
sql/slave.cc
sql/sp_head.cc
sql/sp_head.h
sql/sql_acl.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_connect.cc
sql/sql_lex.cc
sql/sql_load.cc
sql/sql_parse.cc
sql/sql_plugin.cc
sql/sql_repl.cc
sql/sql_select.cc
sql/sql_table.cc
sql/sql_update.cc
sql/sql_yacc.yy
sql/table.cc
tests/mysql_client_test.c
=== modified file 'configure.in'
--- a/configure.in 2010-04-12 10:12:20 +0000
+++ b/configure.in 2010-05-05 17:58:16 +0000
@@ -12,7 +12,7 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
-AC_INIT([MySQL Server], [5.1.47], [], [mysql])
+AC_INIT([MySQL Server], [5.1.48], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
=== modified file 'dbug/dbug.c'
--- a/dbug/dbug.c 2009-07-16 12:43:17 +0000
+++ b/dbug/dbug.c 2010-04-16 07:30:53 +0000
@@ -455,6 +455,13 @@ static void DbugParse(CODE_STATE *cs, co
rel= control[0] == '+' || control[0] == '-';
if ((!rel || (!stack->out_file && !stack->next)))
{
+ /*
+ We need to free what's already in init_settings, because unlike
+ the thread related stack frames there's a chance that something
+ is in these variables already.
+ */
+ if (stack == &init_settings)
+ FreeState(cs, stack, 0);
stack->flags= 0;
stack->delay= 0;
stack->maxdepth= 0;
@@ -1510,7 +1517,10 @@ void _db_end_()
while ((discard= cs->stack))
{
if (discard == &init_settings)
+ {
+ FreeState (cs, discard, 0);
break;
+ }
cs->stack= discard->next;
FreeState(cs, discard, 1);
}
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2009-12-17 11:45:13 +0000
+++ b/include/my_global.h 2010-04-09 11:47:18 +0000
@@ -751,7 +751,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#endif
#define MY_NFILE 64 /* This is only used to save filenames */
#ifndef OS_FILE_LIMIT
-#define OS_FILE_LIMIT 65535
+#define OS_FILE_LIMIT UINT_MAX
#endif
/* #define EXT_IN_LIBNAME */
=== modified file 'include/mysql/plugin.h'
--- a/include/mysql/plugin.h 2010-03-16 13:15:19 +0000
+++ b/include/mysql/plugin.h 2010-04-14 09:53:59 +0000
@@ -801,30 +801,37 @@ void mysql_query_cache_invalidate4(MYSQL
const char *key, unsigned int key_length,
int using_trx);
-#ifdef __cplusplus
-}
-#endif
-#ifdef __cplusplus
/**
Provide a handler data getter to simplify coding
*/
-inline
-void *
-thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton)
-{
- return *thd_ha_data(thd, hton);
-}
+void *thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
+
/**
Provide a handler data setter to simplify coding
+
+ @details
+ Set ha_data pointer (storage engine per-connection information).
+
+ To avoid unclean deactivation (uninstall) of storage engine plugin
+ in the middle of transaction, additional storage engine plugin
+ lock is acquired.
+
+ If ha_data is not null and storage engine plugin was not locked
+ by thd_set_ha_data() in this connection before, storage engine
+ plugin gets locked.
+
+ If ha_data is null and storage engine plugin was locked by
+ thd_set_ha_data() in this connection before, storage engine
+ plugin lock gets released.
+
+ If handlerton::close_connection() didn't reset ha_data, server does
+ it immediately after calling handlerton::close_connection().
*/
-inline
-void
-thd_set_ha_data(const MYSQL_THD thd, const struct handlerton *hton,
- const void *ha_data)
-{
- *thd_ha_data(thd, hton)= (void*) ha_data;
+void thd_set_ha_data(MYSQL_THD thd, const struct handlerton *hton,
+ const void *ha_data);
+#ifdef __cplusplus
}
#endif
=== modified file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp 2008-06-17 12:27:04 +0000
+++ b/include/mysql/plugin.h.pp 2010-04-14 09:53:59 +0000
@@ -137,3 +137,6 @@ void thd_get_xid(const void* thd, MYSQL_
void mysql_query_cache_invalidate4(void* thd,
const char *key, unsigned int key_length,
int using_trx);
+void *thd_get_ha_data(const void* thd, const struct handlerton *hton);
+void thd_set_ha_data(void* thd, const struct handlerton *hton,
+ const void *ha_data);
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2008-05-20 16:36:26 +0000
+++ b/include/mysql_com.h 2010-04-29 23:18:19 +0000
@@ -277,6 +277,16 @@ typedef struct st_net {
/** Client library sqlstate buffer. Set along with the error message. */
char sqlstate[SQLSTATE_LENGTH+1];
void *extension;
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ /*
+ Controls whether a big packet should be skipped.
+
+ Initially set to FALSE by default. Unauthenticated sessions must have
+ this set to FALSE so that the server can't be tricked to read packets
+ indefinitely.
+ */
+ my_bool skip_big_packet;
+#endif
} NET;
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql 2010-02-03 07:49:20 +0000
+++ b/mysql-test/include/mtr_warnings.sql 2010-04-09 17:57:11 +0000
@@ -182,6 +182,8 @@ INSERT INTO global_suppressions VALUES
("==[0-9]*== For more details"),
/* This comes with innodb plugin tests */
("==[0-9]*== Warning: set address range perms: large range"),
+ /* valgrind-3.5.0 dumps this */
+ ("==[0-9]*== Command: "),
/* valgrind warnings: invalid file descriptor -1 in syscall
write()/read(). Bug #50414 */
=== added file 'mysql-test/r/bug46261.result'
--- a/mysql-test/r/bug46261.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/bug46261.result 2010-04-22 13:52:00 +0000
@@ -0,0 +1,8 @@
+#
+# Bug#46261 Plugins can be installed with --skip-grant-tables
+#
+INSTALL PLUGIN example SONAME 'ha_example.so';
+ERROR HY000: The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
+UNINSTALL PLUGIN example;
+ERROR HY000: The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
+End of 5.1 tests
=== modified file 'mysql-test/r/ctype_ucs.result'
--- a/mysql-test/r/ctype_ucs.result 2009-12-14 15:11:47 +0000
+++ b/mysql-test/r/ctype_ucs.result 2010-04-06 07:26:59 +0000
@@ -1230,4 +1230,12 @@ SELECT HEX(DAYNAME(19700101));
HEX(DAYNAME(19700101))
0427043504420432043504400433
SET character_set_connection=latin1;
+#
+# Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+#
+CREATE TABLE t1 (a CHAR(1) CHARSET ascii, b CHAR(1) CHARSET latin1);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.0 tests
=== modified file 'mysql-test/r/error_simulation.result'
--- a/mysql-test/r/error_simulation.result 2008-04-03 08:27:56 +0000
+++ b/mysql-test/r/error_simulation.result 2010-04-25 11:06:40 +0000
@@ -18,3 +18,26 @@ SELECT MAX(a) FROM t1 GROUP BY a,b;
ERROR 23000: Can't write; duplicate key in table 'tmp_table'
set tmp_table_size=default;
DROP TABLE t1;
+#
+# Bug #50946: fast index creation still seems to copy the table
+#
+CREATE TABLE t1 (a INT(100) NOT NULL);
+INSERT INTO t1 VALUES (1), (0), (2);
+SET SESSION debug='+d,alter_table_only_index_change';
+ALTER TABLE t1 ADD INDEX a(a);
+SET SESSION debug=DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(100) NOT NULL,
+ KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a
+0
+1
+2
+DROP TABLE t1;
+#
+# End of 5.1 tests
+#
=== modified file 'mysql-test/r/explain.result'
--- a/mysql-test/r/explain.result 2010-03-09 10:36:26 +0000
+++ b/mysql-test/r/explain.result 2010-04-30 11:10:48 +0000
@@ -226,4 +226,16 @@ Warnings:
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
Note 1003 select (select 1 from `test`.`t2` where (`test`.`t2`.`d` = NULL)) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1`
DROP TABLE t1, t2;
+#
+# Bug #48419: another explain crash..
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b BLOB, KEY b(b(100)));
+INSERT INTO t2 VALUES ('1'), ('2'), ('3');
+FLUSH TABLES;
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1, t2;
End of 5.1 tests.
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2009-10-27 10:09:36 +0000
+++ b/mysql-test/r/grant.result 2010-05-04 14:03:28 +0000
@@ -1413,3 +1413,19 @@ DROP USER 'user1';
DROP USER 'user1'@'localhost';
DROP USER 'user2';
DROP DATABASE db1;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+GRANT SELECT ON db1.* to 'testbug'@localhost;
+USE db2;
+CREATE TABLE t1 (a INT);
+USE test;
+SELECT * FROM `../db2/tb2`;
+ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist
+SELECT * FROM `../db2`.tb2;
+ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2'
+SELECT * FROM `#mysql50#/../db2/tb2`;
+ERROR 42S02: Table 'db1.#mysql50#/../db2/tb2' doesn't exist
+DROP USER 'testbug'@localhost;
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2010-03-17 14:18:46 +0000
+++ b/mysql-test/r/innodb_mysql.result 2010-04-28 12:55:54 +0000
@@ -2350,4 +2350,32 @@ Null
Index_type BTREE
Comment
DROP TABLE t1;
+#
+# Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when
+# JOINed during an UPDATE
+#
+CREATE TABLE t1 (d INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b INT,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB;
+set up our data elements
+INSERT INTO t1 (d) VALUES (1);
+INSERT INTO t2 (a,b) VALUES (1,1);
+SELECT SECOND(c) INTO @bug47453 FROM t2;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+SELECT SLEEP(1);
+SLEEP(1)
+0
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+#should be 0
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+DROP TABLE t1, t2;
End of 5.1 tests
=== modified file 'mysql-test/r/join.result'
--- a/mysql-test/r/join.result 2010-03-26 07:46:18 +0000
+++ b/mysql-test/r/join.result 2010-04-26 20:46:52 +0000
@@ -1146,6 +1146,16 @@ ROW(t1.b, 1111.11) <=> ROW('','');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1;
+#
+# Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
+#
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
+INSERT INTO t1 VALUES (0,0), (1,1);
+SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
+a b a b
+0 0 0 0
+1 1 1 1
+DROP TABLE t1;
End of 5.0 tests.
CREATE TABLE t1 (f1 int);
CREATE TABLE t2 (f1 int);
@@ -1174,14 +1184,4 @@ NULL
NULL
1
DROP TABLE t1, t2, mm1;
-#
-# Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
-#
-CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
-INSERT INTO t1 VALUES (0,0), (1,1);
-SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
-a b a b
-0 0 0 0
-1 1 1 1
-DROP TABLE t1;
End of 5.1 tests
=== modified file 'mysql-test/r/loaddata.result' (properties changed: +x to -x)
--- a/mysql-test/r/loaddata.result 2010-03-30 12:10:25 +0000
+++ b/mysql-test/r/loaddata.result 2010-05-03 16:14:39 +0000
@@ -202,12 +202,6 @@ select * from t1;
a b c
10 NULL Ten
15 NULL Fifteen
-show variables like "secure_file_pri%";
-Variable_name Value
-secure_file_priv MYSQLTEST_VARDIR/
-select @@secure_file_priv;
-@@secure_file_priv
-MYSQLTEST_VARDIR/
set @@secure_file_priv= 0;
ERROR HY000: Variable 'secure_file_priv' is a read only variable
truncate table t1;
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result 2010-03-09 10:36:26 +0000
+++ b/mysql-test/r/ps.result 2010-04-30 11:27:17 +0000
@@ -155,24 +155,24 @@ execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
deallocate prepare stmt1;
@@ -2988,4 +2988,17 @@ select @plaintext;
bcd
deallocate prepare encode;
deallocate prepare decode;
+#
+# Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+#
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+PREPARE stmt FROM "SELECT 1 FROM t1 WHERE
+ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234))";
+EXECUTE stmt;
+1
+EXECUTE stmt;
+1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
End of 5.1 tests.
=== modified file 'mysql-test/r/row.result'
--- a/mysql-test/r/row.result 2009-02-19 13:59:00 +0000
+++ b/mysql-test/r/row.result 2010-04-16 11:42:34 +0000
@@ -457,3 +457,12 @@ abc 1 abc 1
select host,user from mysql.user where (host,user) = ('localhost','test');
host user
drop table t1,t2;
+#
+# Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+#
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+SELECT 1 FROM t1 WHERE ROW(a, b) >=
+ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
+1
+DROP TABLE t1;
=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result 2010-03-29 02:32:30 +0000
+++ b/mysql-test/r/trigger.result 2010-04-01 13:15:22 +0000
@@ -2128,4 +2128,27 @@ Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null
DROP TRIGGER t1_bu;
DROP TABLE t1,t2;
+#
+# Bug#50755: Crash if stored routine def contains version comments
+#
+DROP DATABASE IF EXISTS db1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1, t2;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (b INT);
+CREATE TABLE t2 (a INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
+# Used to crash
+SHOW TRIGGERS IN db1;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+Warnings:
+Warning 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1
+INSERT INTO t2 VALUES (1);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1
+SELECT * FROM t1;
+b
+# Work around Bug#45235
+DROP DATABASE db1;
+USE test;
End of 5.1 tests.
=== modified file 'mysql-test/r/variables_debug.result'
--- a/mysql-test/r/variables_debug.result 2008-02-26 15:03:59 +0000
+++ b/mysql-test/r/variables_debug.result 2010-04-16 07:30:53 +0000
@@ -10,3 +10,16 @@ set debug= '-P';
select @@debug;
@@debug
T
+#
+# Bug #52629: memory leak from sys_var_thd_dbug in
+# binlog.binlog_write_error
+#
+SET GLOBAL debug='d,injecting_fault_writing';
+SELECT @@global.debug;
+@@global.debug
+d,injecting_fault_writing
+SET GLOBAL debug='';
+SELECT @@global.debug;
+@@global.debug
+
+End of 5.1 tests
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2010-03-09 10:36:26 +0000
+++ b/mysql-test/r/view.result 2010-04-06 07:26:59 +0000
@@ -3874,6 +3874,14 @@ CREATE VIEW v1 AS SELECT 1 FROM t1 WHERE
ROW(1,1) >= ROW(1, (SELECT 1 FROM t1 WHERE f1 >= ANY ( SELECT '1' )));
DROP VIEW v1;
DROP TABLE t1;
+#
+# Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+#
+CREATE TABLE t1 (a CHAR(1) CHARSET latin1, b CHAR(1) CHARSET utf8);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
# -----------------------------------------------------------------
# -- End of 5.1 tests.
# -----------------------------------------------------------------
=== modified file 'mysql-test/suite/engines/README'
--- a/mysql-test/suite/engines/README 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/README 2010-05-04 21:24:36 +0000
@@ -50,22 +50,22 @@ The following suites are included:
Known Issues
------------
-1) The 'funcs' and 'iuds' suites currently runs only against MySQL 5.1 server.
- Running them against MySQL 5.5 will generate errors.
-
-2) The folowing tests in the 'iuds' suite:
+1) The folowing tests in the 'iuds' suite:
- delete_decimal
- insert_decimal
- update_decimal
will return a 'Warning 1264 - Out of range value...' warning if run in a 32-bit environment.
Add the '--force' option to prevent the test run from aborting.
-3) The following tests in the 'funcs' suite will fail when run against the innodb_plugin:
+2) The following tests in the 'funcs' suite will fail when run against the innodb_plugin:
- crash_manycolumns_string (bug 50495)
- ix_unique_lob (bug 52056, masked by an 'Out of memory error' on some 32-bit platforms)
- ix_unique_string_length (bug 52056, masked by an 'Out of memory error' on some 32-bit platforms)
Add the '--force' option to prevent the test run from aborting.
-4) Some of the rpl_xxx tests in the 'funcs' suite require a secific binlog_forat setting and will be
+3) Some of the rpl_xxx tests in the 'funcs' suite require a secific binlog_forat setting and will be
skipped otherwise.
+4) Some of the rpl_xxx tests in the 'funcs' suite will report a 'Statement unsafe for replication' warning
+ when run againsr a server configured to use statement based replication.
+
=== modified file 'mysql-test/suite/engines/funcs/t/disabled.def'
--- a/mysql-test/suite/engines/funcs/t/disabled.def 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/funcs/t/disabled.def 2010-04-06 18:06:34 +0000
@@ -1,3 +1,7 @@
# List of disabled tests
# test name : comment
-#rpl_redirect : Fails due to bug#49978
+rpl_redirect : Fails due to bug#49978
+crash_manycolumns_string : Bug#50495 'Row size too large' for plugin, but works for built-in innodb
+ix_unique_lob : Bug#52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value
+ix_unique_string_length : Bug#52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value
+
=== modified file 'mysql-test/suite/engines/iuds/r/insert_year.result'
--- a/mysql-test/suite/engines/iuds/r/insert_year.result 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/iuds/r/insert_year.result 2010-04-06 18:06:34 +0000
@@ -986,7 +986,7 @@ c1 c2 c3 c4
2155 2155 1998-12-26 1998-12-26 11:30:45
SELECT count(*) as total_rows, min(c2) as min_value, max(c2) FROM t2;
total_rows min_value max(c2)
-20 1901 2155
+20 0 2155
SELECT * FROM t2 WHERE c3 = '1998-12-11';
c1 c2 c3 c4
1990 1990 1998-12-11 1998-12-11 11:30:45
@@ -1400,7 +1400,7 @@ c1 c2 c3 c4
2155 2155 1998-12-26 1998-12-26 11:30:45
SELECT count(*) as total_rows, min(c2) as min_value, max(c2) FROM t2;
total_rows min_value max(c2)
-20 1901 2155
+20 0 2155
SELECT * FROM t2 WHERE c3 = '1998-12-11';
c1 c2 c3 c4
1990 1990 1998-12-11 1998-12-11 11:30:45
=== modified file 'mysql-test/suite/engines/iuds/r/update_delete_calendar.result'
--- a/mysql-test/suite/engines/iuds/r/update_delete_calendar.result 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/iuds/r/update_delete_calendar.result 2010-04-06 18:06:34 +0000
@@ -791,9 +791,6 @@ Warning 1292 Truncated incorrect datetim
SELECT count(*) FROM t1 WHERE c2='2001-01-11 23:59:60' /* returns 0 */;
count(*)
0
-Warnings:
-Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60' for column 'c2' at row 1
SELECT * FROM t1 WHERE c1='0000-00-00 00:00:00' OR c2='0000-00-00 00:00:00';
c1 c2 c3
0000-00-00 00:00:00 0000-00-00 00:00:00 6
=== modified file 'mysql-test/suite/engines/iuds/t/disabled.def'
--- a/mysql-test/suite/engines/iuds/t/disabled.def 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/iuds/t/disabled.def 2010-04-07 18:28:28 +0000
@@ -0,0 +1 @@
+insert_calendar : Bug #52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value
=== modified file 'mysql-test/suite/engines/iuds/t/insert_number.test'
--- a/mysql-test/suite/engines/iuds/t/insert_number.test 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/iuds/t/insert_number.test 2010-04-06 18:06:34 +0000
@@ -7812,10 +7812,15 @@ SELECT * FROM t2 ORDER BY c1,c6 LIMIT 2;
SELECT * FROM t2 ORDER BY c1,c6 DESC LIMIT 2;
## ref type access
+
+# Bug#52283 : Remove the following --disable_warnings
+# command when the bug is fixed
+--disable_warnings
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6;
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6 LIMIT 2;
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6 DESC;
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6 DESC LIMIT 2;
+--enable_warnings
## Range access, ordered ##
SELECT * FROM t2 WHERE c1 <> 18446744073709551616 ORDER BY c1,c6;
=== modified file 'mysql-test/suite/engines/iuds/t/update_delete_calendar.test'
--- a/mysql-test/suite/engines/iuds/t/update_delete_calendar.test 2010-03-18 06:42:07 +0000
+++ b/mysql-test/suite/engines/iuds/t/update_delete_calendar.test 2010-04-06 18:06:34 +0000
@@ -300,7 +300,12 @@ INSERT INTO t1 VALUES('2001-01-09','2001
UPDATE t1 SET c1='2001-01-09 24:59:59',c2='2009-01-10 23:60:59' WHERE c1='2001-01-09';
UPDATE t1 SET c2='2001-01-11 23:59:60' WHERE c1='2001-01-11';
SELECT count(*) FROM t1 WHERE c1='2001-01-09 24:59:59' AND c2='2009-01-10 23:60:59';
+
+# Bug#52283 : Remove the following --disable_warnings
+# command when the bug is fixed
+--disable_warnings
SELECT count(*) FROM t1 WHERE c2='2001-01-11 23:59:60' /* returns 0 */;
+--enable_warnings
--sorted_result
SELECT * FROM t1 WHERE c1='0000-00-00 00:00:00' OR c2='0000-00-00 00:00:00';
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result 2009-12-06 23:12:11 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result 2010-03-22 09:51:16 +0000
@@ -242,4 +242,18 @@ GRANT ALL PRIVILEGES ON *.* TO 'root'@'l
DROP TABLE t1;
DROP PROCEDURE p1;
DROP USER 'user49119'@'localhost';
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+grant all on *.* to foo@"1.2.3.4";
+revoke all privileges, grant option from "foo";
+ERROR HY000: Can't revoke all privileges for one or more of the requested users
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; grant all on *.* to foo@"1.2.3.4"
+master-bin.000001 # Query # # use `test`; revoke all privileges, grant option from "foo"
+DROP USER foo@"1.2.3.4";
"End of test"
=== modified file 'mysql-test/suite/rpl/t/rpl_do_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test 2009-12-06 23:12:11 +0000
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test 2010-03-22 09:51:16 +0000
@@ -316,4 +316,33 @@ DROP USER 'user49119'@'localhost';
-- sync_slave_with_master
+#
+# Bug #51987 revoke privileges logs wrong error code
+#
+
+-- connection master
+-- source include/master-slave-reset.inc
+-- connection master
+
+grant all on *.* to foo@"1.2.3.4";
+-- error ER_REVOKE_GRANTS
+revoke all privileges, grant option from "foo";
+
+## assertion: revoke is logged
+-- source include/show_binlog_events.inc
+
+-- sync_slave_with_master
+
+## assertion: slave replicates revoke and does not fail because master
+## logged revoke with correct expected error code
+-- let $err= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1)
+ if ($err)
+{
+ -- die UNEXPECTED ERROR AT SLAVE: $err
+}
+
+-- connection master
+DROP USER foo@"1.2.3.4";
+-- sync_slave_with_master
+
--echo "End of test"
=== added file 'mysql-test/suite/sys_vars/r/secure_file_priv.result'
--- a/mysql-test/suite/sys_vars/r/secure_file_priv.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/secure_file_priv.result 2010-04-16 14:10:47 +0000
@@ -0,0 +1,22 @@
+#
+# Bug50373 --secure-file-priv=""
+#
+CREATE TABLE t1 (c1 VARCHAR(50));
+INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five");
+SHOW VARIABLES LIKE 'secure_file_priv';
+Variable_name Value
+secure_file_priv
+c1
+one
+two
+three
+four
+five
+loaded_file
+one
+two
+three
+four
+five
+
+DROP TABLE t1;
=== added file 'mysql-test/suite/sys_vars/t/secure_file_priv-master.opt'
--- a/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt 2010-04-16 14:10:47 +0000
@@ -0,0 +1 @@
+--secure_file_priv=''
=== added file 'mysql-test/suite/sys_vars/t/secure_file_priv.test'
--- a/mysql-test/suite/sys_vars/t/secure_file_priv.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test 2010-04-16 14:10:47 +0000
@@ -0,0 +1,21 @@
+--echo #
+--echo # Bug50373 --secure-file-priv=""
+--echo #
+CREATE TABLE t1 (c1 VARCHAR(50));
+INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five");
+SHOW VARIABLES LIKE 'secure_file_priv';
+--disable_query_log
+# Atempt to create a file where we normally aren't allowed to create one.
+# Doing this in a portable manner is difficult but we should be able to
+# count on the depth of the directory hierarchy used. Three steps up from
+# the datadir is the 'mysql_test' directory.
+--let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')`;
+--eval SELECT * FROM t1 INTO OUTFILE '$PROTECTED_FILE';
+DELETE FROM t1;
+--eval LOAD DATA INFILE '$PROTECTED_FILE' INTO TABLE t1;
+SELECT * FROM t1;
+--eval SELECT load_file('$PROTECTED_FILE') AS loaded_file;
+--enable_query_log
+remove_file $PROTECTED_FILE;
+DROP TABLE t1;
+
=== added file 'mysql-test/t/bug46261-master.opt'
--- a/mysql-test/t/bug46261-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/bug46261-master.opt 2010-04-22 13:52:00 +0000
@@ -0,0 +1 @@
+--skip-grant-tables $EXAMPLE_PLUGIN_OPT
=== added file 'mysql-test/t/bug46261.test'
--- a/mysql-test/t/bug46261.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/bug46261.test 2010-04-22 13:52:00 +0000
@@ -0,0 +1,16 @@
+--source include/not_embedded.inc
+--source include/have_example_plugin.inc
+
+--echo #
+--echo # Bug#46261 Plugins can be installed with --skip-grant-tables
+--echo #
+
+--replace_regex /\.dll/.so/
+--error ER_OPTION_PREVENTS_STATEMENT
+eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+
+--replace_regex /\.dll/.so/
+--error ER_OPTION_PREVENTS_STATEMENT
+eval UNINSTALL PLUGIN example;
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/ctype_ucs.test'
--- a/mysql-test/t/ctype_ucs.test 2009-12-14 15:11:47 +0000
+++ b/mysql-test/t/ctype_ucs.test 2010-04-06 07:26:59 +0000
@@ -732,4 +732,13 @@ SELECT HEX(MONTHNAME(19700101));
SELECT HEX(DAYNAME(19700101));
SET character_set_connection=latin1;
+--echo #
+--echo # Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+--echo #
+CREATE TABLE t1 (a CHAR(1) CHARSET ascii, b CHAR(1) CHARSET latin1);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
=== modified file 'mysql-test/t/error_simulation.test'
--- a/mysql-test/t/error_simulation.test 2008-04-03 08:27:56 +0000
+++ b/mysql-test/t/error_simulation.test 2010-04-25 11:06:40 +0000
@@ -33,3 +33,19 @@ set tmp_table_size=default;
DROP TABLE t1;
+--echo #
+--echo # Bug #50946: fast index creation still seems to copy the table
+--echo #
+CREATE TABLE t1 (a INT(100) NOT NULL);
+INSERT INTO t1 VALUES (1), (0), (2);
+SET SESSION debug='+d,alter_table_only_index_change';
+ALTER TABLE t1 ADD INDEX a(a);
+SET SESSION debug=DEFAULT;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of 5.1 tests
+--echo #
=== modified file 'mysql-test/t/explain.test'
--- a/mysql-test/t/explain.test 2010-03-05 16:44:37 +0000
+++ b/mysql-test/t/explain.test 2010-04-30 11:10:48 +0000
@@ -198,4 +198,19 @@ INSERT INTO t2 VALUES (NULL), (0);
EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1;
DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #48419: another explain crash..
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b BLOB, KEY b(b(100)));
+INSERT INTO t2 VALUES ('1'), ('2'), ('3');
+
+FLUSH TABLES;
+
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
+
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2009-06-15 15:53:45 +0000
+++ b/mysql-test/t/grant.test 2010-05-04 14:03:28 +0000
@@ -1525,5 +1525,30 @@ DROP USER 'user1'@'localhost';
DROP USER 'user2';
DROP DATABASE db1;
+
+#
+# Bug #53371: COM_FIELD_LIST can be abused to bypass table level grants.
+#
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+GRANT SELECT ON db1.* to 'testbug'@localhost;
+USE db2;
+CREATE TABLE t1 (a INT);
+USE test;
+connect (con1,localhost,testbug,,db1);
+--error ER_NO_SUCH_TABLE
+SELECT * FROM `../db2/tb2`;
+--error ER_TABLEACCESS_DENIED_ERROR
+SELECT * FROM `../db2`.tb2;
+--error ER_NO_SUCH_TABLE
+SELECT * FROM `#mysql50#/../db2/tb2`;
+connection default;
+disconnect con1;
+DROP USER 'testbug'@localhost;
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
=== modified file 'mysql-test/t/innodb_mysql.test'
--- a/mysql-test/t/innodb_mysql.test 2010-03-17 14:18:46 +0000
+++ b/mysql-test/t/innodb_mysql.test 2010-04-28 12:55:54 +0000
@@ -589,4 +589,34 @@ ALTER TABLE t1 DROP INDEX k, ADD UNIQUE
DROP TABLE t1;
+
+--echo #
+--echo # Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when
+--echo # JOINed during an UPDATE
+--echo #
+
+CREATE TABLE t1 (d INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b INT,
+ c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+ ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB;
+
+--echo set up our data elements
+INSERT INTO t1 (d) VALUES (1);
+INSERT INTO t2 (a,b) VALUES (1,1);
+SELECT SECOND(c) INTO @bug47453 FROM t2;
+
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+
+SELECT SLEEP(1);
+
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+
+--echo #should be 0
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+
+DROP TABLE t1, t2;
+
+
--echo End of 5.1 tests
=== modified file 'mysql-test/t/join.test'
--- a/mysql-test/t/join.test 2010-03-26 07:46:18 +0000
+++ b/mysql-test/t/join.test 2010-04-26 20:46:52 +0000
@@ -807,6 +807,17 @@ WHERE ROW(t1.a, 1111.11) = ROW(1111.11,
ROW(t1.b, 1111.11) <=> ROW('','');
DROP TABLE t1;
+--echo #
+--echo # Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
+INSERT INTO t1 VALUES (0,0), (1,1);
+
+SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests.
@@ -840,15 +851,4 @@ ENGINE=MERGE UNION=(t1,t2);
SELECT t1.a FROM mm1,t1;
DROP TABLE t1, t2, mm1;
---echo #
---echo # Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
---echo #
-
-CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
-INSERT INTO t1 VALUES (0,0), (1,1);
-
-SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
-
-DROP TABLE t1;
-
--echo End of 5.1 tests
=== modified file 'mysql-test/t/loaddata.test'
--- a/mysql-test/t/loaddata.test 2010-03-30 12:10:25 +0000
+++ b/mysql-test/t/loaddata.test 2010-05-03 16:14:39 +0000
@@ -153,10 +153,16 @@ select * from t1;
#
# It should not be possible to load from a file outside of vardir
---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-show variables like "secure_file_pri%";
---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-select @@secure_file_priv;
+## The following lines were disabled because of patch for
+## bug 50373. MYSQLTEST_VARDIR doesn't rewrite symlinks
+## to real paths, but this is done for secure_file_priv.
+## Because of this the result can't be replaced if the
+## test suite runs with the --mem option which creates
+## symlinks to the ramdisk.
+#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+#show variables like "secure_file_pri%";
+#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+#select @@secure_file_priv;
--error 1238
set @@secure_file_priv= 0;
=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test 2010-02-26 13:16:46 +0000
+++ b/mysql-test/t/ps.test 2010-04-16 11:42:34 +0000
@@ -3065,4 +3065,18 @@ select @plaintext;
deallocate prepare encode;
deallocate prepare decode;
+--echo #
+--echo # Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+--echo #
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+PREPARE stmt FROM "SELECT 1 FROM t1 WHERE
+ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234))";
+--disable_warnings
+EXECUTE stmt;
+EXECUTE stmt;
+--enable_warnings
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/row.test'
--- a/mysql-test/t/row.test 2009-02-19 13:20:44 +0000
+++ b/mysql-test/t/row.test 2010-04-16 11:42:34 +0000
@@ -255,3 +255,14 @@ select * from t1,t2 where (a,b) = (c,d);
select host,user from mysql.user where (host,user) = ('localhost','test');
drop table t1,t2;
+
+--echo #
+--echo # Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+--echo #
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+--disable_warnings
+SELECT 1 FROM t1 WHERE ROW(a, b) >=
+ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
+--enable_warnings
+DROP TABLE t1;
=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test 2010-03-29 02:32:30 +0000
+++ b/mysql-test/t/trigger.test 2010-04-01 13:15:22 +0000
@@ -2439,4 +2439,35 @@ UPDATE t1 SET id=NULL;
DROP TRIGGER t1_bu;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug#50755: Crash if stored routine def contains version comments
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE DATABASE db1;
+USE db1;
+
+CREATE TABLE t1 (b INT);
+CREATE TABLE t2 (a INT);
+
+CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
+--echo # Used to crash
+SHOW TRIGGERS IN db1;
+--error ER_PARSE_ERROR
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1;
+
+--echo # Work around Bug#45235
+let $MYSQLD_DATADIR = `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/db1/t2.TRG
+--remove_file $MYSQLD_DATADIR/db1/trg1.TRN
+
+DROP DATABASE db1;
+USE test;
+
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/variables_debug.test'
--- a/mysql-test/t/variables_debug.test 2008-02-26 15:03:59 +0000
+++ b/mysql-test/t/variables_debug.test 2010-04-16 07:30:53 +0000
@@ -10,3 +10,16 @@ set debug= '+P';
select @@debug;
set debug= '-P';
select @@debug;
+
+--echo #
+--echo # Bug #52629: memory leak from sys_var_thd_dbug in
+--echo # binlog.binlog_write_error
+--echo #
+
+SET GLOBAL debug='d,injecting_fault_writing';
+SELECT @@global.debug;
+SET GLOBAL debug='';
+SELECT @@global.debug;
+
+
+--echo End of 5.1 tests
=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test 2010-02-12 09:44:20 +0000
+++ b/mysql-test/t/view.test 2010-04-06 07:26:59 +0000
@@ -3916,6 +3916,15 @@ ROW(1,1) >= ROW(1, (SELECT 1 FROM t1 WHE
DROP VIEW v1;
DROP TABLE t1;
+--echo #
+--echo # Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+--echo #
+CREATE TABLE t1 (a CHAR(1) CHARSET latin1, b CHAR(1) CHARSET utf8);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests.
--echo # -----------------------------------------------------------------
=== modified file 'mysys/mf_loadpath.c'
--- a/mysys/mf_loadpath.c 2007-05-10 09:59:39 +0000
+++ b/mysys/mf_loadpath.c 2010-05-05 08:54:52 +0000
@@ -34,7 +34,7 @@ char * my_load_path(char * to, const cha
if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
test_if_hard_path(path))
- VOID(strmov(buff,path));
+ VOID(strnmov(buff, path, FN_REFLEN));
else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) ||
(is_prefix(path,FN_PARENTDIR)) ||
! own_path_prefix)
@@ -42,13 +42,14 @@ char * my_load_path(char * to, const cha
if (is_cur)
is_cur=2; /* Remove current dir */
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
- VOID(strcat(buff,path+is_cur));
+ VOID(strncat(buff, path+is_cur, FN_REFLEN));
else
- VOID(strmov(buff,path)); /* Return org file name */
+ VOID(strnmov(buff, path, FN_REFLEN)); /* Return org file name */
}
else
- VOID(strxmov(buff,own_path_prefix,path,NullS));
- strmov(to,buff);
+ VOID(strxnmov(buff, FN_REFLEN, own_path_prefix,path, NullS));
+ strnmov(to, buff, FN_REFLEN);
+ to[FN_REFLEN-1]= '\0';
DBUG_PRINT("exit",("to: %s",to));
DBUG_RETURN(to);
} /* my_load_path */
=== modified file 'mysys/my_file.c'
--- a/mysys/my_file.c 2006-12-23 19:20:40 +0000
+++ b/mysys/my_file.c 2010-04-09 11:47:18 +0000
@@ -72,7 +72,7 @@ static uint set_max_open_files(uint max_
}
#else
-static int set_max_open_files(uint max_file_limit)
+static uint set_max_open_files(uint max_file_limit)
{
/* We don't know the limit. Return best guess */
return min(max_file_limit, OS_FILE_LIMIT);
=== modified file 'mysys/my_getwd.c'
--- a/mysys/my_getwd.c 2009-02-13 16:41:47 +0000
+++ b/mysys/my_getwd.c 2010-05-05 08:54:52 +0000
@@ -50,11 +50,16 @@ int my_getwd(char * buf, size_t size, my
DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d",
(long) buf, (uint) size, MyFlags));
+ if (size < 1)
+ return(-1);
+
if (curr_dir[0]) /* Current pos is saved here */
VOID(strmake(buf,&curr_dir[0],size-1));
else
{
#if defined(HAVE_GETCWD)
+ if (size < 2)
+ return(-1);
if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME)
{
my_errno=errno;
@@ -68,6 +73,8 @@ int my_getwd(char * buf, size_t size, my
strmake(buf,pathname,size-1);
}
#elif defined(VMS)
+ if (size < 2)
+ return(-1);
if (!getcwd(buf,size-2,1) && MyFlags & MY_WME)
{
my_errno=errno;
=== modified file 'scripts/mysqld_safe.sh'
--- a/scripts/mysqld_safe.sh 2009-08-19 15:16:30 +0000
+++ b/scripts/mysqld_safe.sh 2010-04-09 11:47:18 +0000
@@ -183,6 +183,7 @@ parse_arguments() {
;;
--nice=*) niceness="$val" ;;
--open-files-limit=*) open_files="$val" ;;
+ --open_files_limit=*) open_files="$val" ;;
--skip-kill-mysqld*) KILL_MYSQLD=0 ;;
--syslog) want_syslog=1 ;;
--skip-syslog) want_syslog=0 ;;
@@ -397,10 +398,14 @@ then
if test -n "$open_files"
then
ulimit -n $open_files
- append_arg_to_args "--open-files-limit=$open_files"
fi
fi
+if test -n "$open_files"
+then
+ append_arg_to_args "--open-files-limit=$open_files"
+fi
+
safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}}
# Make sure that directory for $safe_mysql_unix_port exists
mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
=== modified file 'scripts/mysqlhotcopy.sh'
--- a/scripts/mysqlhotcopy.sh 2009-04-28 16:16:17 +0000
+++ b/scripts/mysqlhotcopy.sh 2010-04-12 08:56:28 +0000
@@ -267,6 +267,14 @@ foreach my $rdb ( @db_desc ) {
my $db = $rdb->{src};
my @dbh_tables = get_list_of_tables( $db );
+ ## filter out certain system non-lockable tables.
+ ## keep in sync with mysqldump.
+ if ($db =~ m/^mysql$/i)
+ {
+ @dbh_tables = grep
+ { !/^(apply_status|schema|general_log|slow_log)$/ } @dbh_tables
+ }
+
## generate regex for tables/files
my $t_regex;
my $negated;
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2009-09-29 15:38:40 +0000
+++ b/sql/CMakeLists.txt 2010-04-26 21:59:50 +0000
@@ -49,7 +49,7 @@ SET (SQL_SOURCE
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
item_create.cc item_func.cc item_geofunc.cc item_row.cc
item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc
- key.cc log.cc lock.cc message.rc
+ key.cc log.cc lock.cc
log_event.cc rpl_record.cc rpl_reporting.cc
log_event_old.cc rpl_record_old.cc
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
@@ -89,7 +89,7 @@ ADD_LIBRARY(sql ${SQL_SOURCE})
IF (NOT EXISTS cmake_dummy.cc)
FILE (WRITE cmake_dummy.cc "")
ENDIF (NOT EXISTS cmake_dummy.cc)
-ADD_EXECUTABLE(mysqld cmake_dummy.cc)
+ADD_EXECUTABLE(mysqld cmake_dummy.cc message.rc)
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2010-03-17 18:15:41 +0000
+++ b/sql/field.cc 2010-04-25 11:06:40 +0000
@@ -8878,14 +8878,20 @@ bool Field_num::eq_def(Field *field)
}
+/**
+ Check whether two numeric fields can be considered 'equal' for table
+ alteration purposes. Fields are equal if they are of the same type
+ and retain the same pack length.
+*/
+
uint Field_num::is_equal(Create_field *new_field)
{
return ((new_field->sql_type == real_type()) &&
- ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags &
- UNSIGNED_FLAG)) &&
+ ((new_field->flags & UNSIGNED_FLAG) ==
+ (uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) ==
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
- (new_field->length <= max_display_length()));
+ (new_field->pack_length == pack_length()));
}
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2009-10-16 10:29:42 +0000
+++ b/sql/ha_ndbcluster.cc 2010-04-19 13:48:37 +0000
@@ -7316,13 +7316,6 @@ static int ndbcluster_init(void *p)
if (ndbcluster_inited)
DBUG_RETURN(FALSE);
- /*
- Below we create new THD's. They'll need LOCK_plugin, but it's taken now by
- plugin initialization code. Release it to avoid deadlocks. It's safe, as
- there're no threads that may concurrently access plugin control structures.
- */
- pthread_mutex_unlock(&LOCK_plugin);
-
pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_ndb_util_thread, MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_ndb_util_thread, NULL);
@@ -7463,8 +7456,6 @@ static int ndbcluster_init(void *p)
goto ndbcluster_init_error;
}
- pthread_mutex_lock(&LOCK_plugin);
-
ndbcluster_inited= 1;
DBUG_RETURN(FALSE);
@@ -7477,8 +7468,6 @@ ndbcluster_init_error:
g_ndb_cluster_connection= NULL;
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
- pthread_mutex_lock(&LOCK_plugin);
-
DBUG_RETURN(TRUE);
}
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2009-12-01 09:19:51 +0000
+++ b/sql/handler.cc 2010-04-14 09:53:59 +0000
@@ -159,7 +159,7 @@ redo:
}
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton)
{
if (hton)
{
@@ -601,9 +601,13 @@ static my_bool closecon_handlerton(THD *
there's no need to rollback here as all transactions must
be rolled back already
*/
- if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
- thd_get_ha_data(thd, hton))
- hton->close_connection(hton, thd);
+ if (hton->state == SHOW_OPTION_YES && thd_get_ha_data(thd, hton))
+ {
+ if (hton->close_connection)
+ hton->close_connection(hton, thd);
+ /* make sure ha_data is reset and ha_data_lock is released */
+ thd_set_ha_data(thd, hton, NULL);
+ }
return FALSE;
}
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2009-10-12 12:46:00 +0000
+++ b/sql/handler.h 2010-04-14 09:53:59 +0000
@@ -1956,7 +1956,7 @@ extern ulong total_ha, total_ha_2pc;
/* lookups */
handlerton *ha_default_handlerton(THD *thd);
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
handlerton *db_type);
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-04-01 20:05:36 +0000
+++ b/sql/item.cc 2010-05-05 08:54:52 +0000
@@ -1713,7 +1713,16 @@ bool agg_item_set_converter(DTCollation
if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
- conv= new Item_func_conv_charset(*arg, coll.collation, 1);
+ {
+ /*
+ We should disable const subselect item evaluation because
+ subselect transformation does not happen in view_prepare_mode
+ and thus val_...() methods can not be called for const items.
+ */
+ bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM &&
+ thd->lex->view_prepare_mode) ? FALSE : TRUE;
+ conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const);
+ }
if (!conv)
{
@@ -5357,13 +5366,25 @@ inline uint char_val(char X)
X-'a'+10);
}
+Item_hex_string::Item_hex_string()
+{
+ hex_string_init("", 0);
+}
Item_hex_string::Item_hex_string(const char *str, uint str_length)
{
+ hex_string_init(str, str_length);
+}
+
+void Item_hex_string::hex_string_init(const char *str, uint str_length)
+{
max_length=(str_length+1)/2;
char *ptr=(char*) sql_alloc(max_length+1);
if (!ptr)
+ {
+ str_value.set("", 0, &my_charset_bin);
return;
+ }
str_value.set(ptr,max_length,&my_charset_bin);
char *end=ptr+max_length;
if (max_length*2 != str_length)
=== modified file 'sql/item.h'
--- a/sql/item.h 2010-03-16 09:20:07 +0000
+++ b/sql/item.h 2010-05-05 08:54:52 +0000
@@ -2123,7 +2123,7 @@ public:
class Item_hex_string: public Item_basic_constant
{
public:
- Item_hex_string() {}
+ Item_hex_string();
Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; }
double val_real()
@@ -2143,6 +2143,8 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+private:
+ void hex_string_init(const char *str, uint str_length);
};
=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h 2010-04-12 10:12:20 +0000
+++ b/sql/item_cmpfunc.h 2010-04-16 11:42:34 +0000
@@ -54,9 +54,9 @@ public:
/* Allow owner function to use string buffers. */
String value1, value2;
- Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(TRUE),
+ Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
- Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
+ Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
@@ -112,6 +112,11 @@ public:
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
+ void cleanup()
+ {
+ delete [] comparators;
+ comparators= 0;
+ }
friend class Item_func;
};
@@ -365,6 +370,11 @@ public:
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
void top_level_item() { abort_on_null= TRUE; }
+ void cleanup()
+ {
+ Item_int_func::cleanup();
+ cmp.cleanup();
+ }
friend class Arg_comparator;
};
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2010-04-02 20:30:22 +0000
+++ b/sql/item_strfunc.cc 2010-05-03 16:14:39 +0000
@@ -2959,8 +2959,7 @@ String *Item_load_file::val_str(String *
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
/* Read only allowed from within dir specified by secure_file_priv */
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
goto err;
if (!my_stat(path, &stat_info, MYF(0)))
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-03-09 12:51:56 +0000
+++ b/sql/item_subselect.cc 2010-04-06 07:26:59 +0000
@@ -122,6 +122,21 @@ void Item_subselect::cleanup()
DBUG_VOID_RETURN;
}
+
+/*
+ We cannot use generic Item::safe_charset_converter() because
+ Subselect transformation does not happen in view_prepare_mode
+ and thus we can not evaluate val_...() for const items.
+*/
+
+Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ Item_func_conv_charset *conv=
+ new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1);
+ return conv->safe ? conv : NULL;
+}
+
+
void Item_singlerow_subselect::cleanup()
{
DBUG_ENTER("Item_singlerow_subselect::cleanup");
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2009-11-17 14:06:46 +0000
+++ b/sql/item_subselect.h 2010-04-06 07:26:59 +0000
@@ -126,6 +126,7 @@ public:
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
/**
Get the SELECT_LEX structure associated with this Item.
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-31 13:12:37 +0000
+++ b/sql/mysql_priv.h 2010-05-04 14:03:28 +0000
@@ -1832,6 +1832,12 @@ void sql_perror(const char *message);
bool fn_format_relative_to_data_home(char * to, const char *name,
const char *dir, const char *extension);
+/**
+ Test a file path to determine if the path is compatible with the secure file
+ path restriction.
+*/
+bool is_secure_file_path(char *path);
+
#ifdef MYSQL_SERVER
File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg);
@@ -2263,7 +2269,7 @@ void update_create_info_from_table(HA_CR
int rename_file_ext(const char * from,const char * to,const char * ext);
bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name);
-bool check_table_name(const char *name, uint length);
+bool check_table_name(const char *name, uint length, bool check_for_path_chars);
char *get_field(MEM_ROOT *mem, Field *field);
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-03-31 13:12:37 +0000
+++ b/sql/mysqld.cc 2010-05-05 08:54:52 +0000
@@ -8776,6 +8776,48 @@ fn_format_relative_to_data_home(char * t
}
+/**
+ Test a file path to determine if the path is compatible with the secure file
+ path restriction.
+
+ @param path null terminated character string
+
+ @return
+ @retval TRUE The path is secure
+ @retval FALSE The path isn't secure
+*/
+
+bool is_secure_file_path(char *path)
+{
+ char buff1[FN_REFLEN], buff2[FN_REFLEN];
+ /*
+ All paths are secure if opt_secure_file_path is 0
+ */
+ if (!opt_secure_file_priv)
+ return TRUE;
+
+ if (strlen(path) >= FN_REFLEN)
+ return FALSE;
+
+ if (my_realpath(buff1, path, 0))
+ {
+ /*
+ The supplied file path might have been a file and not a directory.
+ */
+ int length= (int)dirname_length(path);
+ if (length >= FN_REFLEN)
+ return FALSE;
+ memcpy(buff2, path, length);
+ buff2[length]= '\0';
+ if (length == 0 || my_realpath(buff1, buff2, 0))
+ return FALSE;
+ }
+ convert_dirname(buff2, buff1, NullS);
+ if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
+ return FALSE;
+ return TRUE;
+}
+
static int fix_paths(void)
{
char buff[FN_REFLEN],*pos;
@@ -8837,10 +8879,26 @@ static int fix_paths(void)
*/
if (opt_secure_file_priv)
{
- convert_dirname(buff, opt_secure_file_priv, NullS);
- my_free(opt_secure_file_priv, MYF(0));
- opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
+ if (*opt_secure_file_priv == 0)
+ {
+ opt_secure_file_priv= 0;
+ }
+ else
+ {
+ if (strlen(opt_secure_file_priv) >= FN_REFLEN)
+ opt_secure_file_priv[FN_REFLEN-1]= '\0';
+ if (my_realpath(buff, opt_secure_file_priv, 0))
+ {
+ sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
+ return 1;
+ }
+ char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
+ convert_dirname(secure_file_real_path, buff, NullS);
+ my_free(opt_secure_file_priv, MYF(0));
+ opt_secure_file_priv= secure_file_real_path;
+ }
}
+
return 0;
}
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2009-07-28 18:44:28 +0000
+++ b/sql/net_serv.cc 2010-04-29 23:18:19 +0000
@@ -136,6 +136,9 @@ my_bool my_net_init(NET *net, Vio* vio)
#else
net->query_cache_query= 0;
#endif
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ net->skip_big_packet= FALSE;
+#endif
if (vio != 0) /* If real connection */
{
@@ -949,6 +952,7 @@ my_real_read(NET *net, size_t *complen)
{
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
if (!net->compress &&
+ net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */
#endif
=== modified file 'sql/partition_info.cc'
--- a/sql/partition_info.cc 2009-09-23 13:21:29 +0000
+++ b/sql/partition_info.cc 2010-05-04 14:03:28 +0000
@@ -972,7 +972,7 @@ bool partition_info::check_partition_inf
part_elem->engine_type= default_engine_type;
}
if (check_table_name(part_elem->partition_name,
- strlen(part_elem->partition_name)))
+ strlen(part_elem->partition_name), FALSE))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
@@ -990,7 +990,7 @@ bool partition_info::check_partition_inf
{
sub_elem= sub_it++;
if (check_table_name(sub_elem->partition_name,
- strlen(sub_elem->partition_name)))
+ strlen(sub_elem->partition_name), FALSE))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2010-03-19 09:06:40 +0000
+++ b/sql/slave.cc 2010-05-04 09:41:28 +0000
@@ -2883,6 +2883,11 @@ pthread_handler_t handle_slave_sql(void
{
THD *thd; /* needs to be first for thread_stack */
char llbuff[22],llbuff1[22];
+ char saved_log_name[FN_REFLEN];
+ char saved_master_log_name[FN_REFLEN];
+ my_off_t saved_log_pos;
+ my_off_t saved_master_log_pos;
+ my_off_t saved_skip= 0;
Relay_log_info* rli = &((Master_info*)arg)->rli;
const char *errmsg;
@@ -3028,6 +3033,17 @@ log '%s' at position %s, relay log '%s'
do not want to wait for next event in this case.
*/
pthread_mutex_lock(&rli->data_lock);
+ if (rli->slave_skip_counter)
+ {
+ char *pos;
+ pos= strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ pos= strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ saved_log_pos= rli->group_relay_log_pos;
+ saved_master_log_pos= rli->group_master_log_pos;
+ saved_skip= rli->slave_skip_counter;
+ }
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
rli->is_until_satisfied(thd, NULL))
{
@@ -3046,6 +3062,21 @@ log '%s' at position %s, relay log '%s'
thd_proc_info(thd, "Reading event from the relay log");
DBUG_ASSERT(rli->sql_thd == thd);
THD_CHECK_SENTRY(thd);
+
+ if (saved_skip && rli->slave_skip_counter == 0)
+ {
+ sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
+ "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
+ "master_log_pos='%ld' and new position at "
+ "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
+ "master_log_pos='%ld' ",
+ (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
+ saved_master_log_name, (ulong) saved_master_log_pos,
+ rli->group_relay_log_name, (ulong) rli->group_relay_log_pos,
+ rli->group_master_log_name, (ulong) rli->group_master_log_pos);
+ saved_skip= 0;
+ }
+
if (exec_relay_log_event(thd,rli))
{
DBUG_PRINT("info", ("exec_relay_log_event() failed"));
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-03-29 02:32:30 +0000
+++ b/sql/sp_head.cc 2010-04-01 13:15:22 +0000
@@ -745,21 +745,12 @@ sp_head::create(THD *thd)
sp_head::~sp_head()
{
+ LEX *lex;
+ sp_instr *i;
DBUG_ENTER("sp_head::~sp_head");
- destroy();
- delete m_next_cached_sp;
- if (m_thd)
- restore_thd_mem_root(m_thd);
- DBUG_VOID_RETURN;
-}
-void
-sp_head::destroy()
-{
- sp_instr *i;
- LEX *lex;
- DBUG_ENTER("sp_head::destroy");
- DBUG_PRINT("info", ("name: %s", m_name.str));
+ /* sp_head::restore_thd_mem_root() must already have been called. */
+ DBUG_ASSERT(m_thd == NULL);
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
delete i;
@@ -770,21 +761,22 @@ sp_head::destroy()
/*
If we have non-empty LEX stack then we just came out of parser with
error. Now we should delete all auxilary LEXes and restore original
- THD::lex (In this case sp_head::restore_thd_mem_root() was not called
- too, so m_thd points to the current thread context).
- It is safe to not update LEX::ptr because further query string parsing
- and execution will be stopped anyway.
+ THD::lex. It is safe to not update LEX::ptr because further query
+ string parsing and execution will be stopped anyway.
*/
- DBUG_ASSERT(m_lex.is_empty() || m_thd);
while ((lex= (LEX *)m_lex.pop()))
{
- lex_end(m_thd->lex);
- delete m_thd->lex;
- m_thd->lex= lex;
+ THD *thd= lex->thd;
+ lex_end(thd->lex);
+ delete thd->lex;
+ thd->lex= lex;
}
hash_free(&m_sptabs);
hash_free(&m_sroutines);
+
+ delete m_next_cached_sp;
+
DBUG_VOID_RETURN;
}
=== modified file 'sql/sp_head.h'
--- a/sql/sp_head.h 2009-11-20 15:18:01 +0000
+++ b/sql/sp_head.h 2010-04-01 13:15:22 +0000
@@ -289,10 +289,6 @@ public:
virtual ~sp_head();
- /// Free memory
- void
- destroy();
-
bool
execute_trigger(THD *thd,
const LEX_STRING *db_name,
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-02-26 13:16:46 +0000
+++ b/sql/sql_acl.cc 2010-03-22 09:51:16 +0000
@@ -6117,19 +6117,19 @@ bool mysql_revoke_all(THD *thd, List <L
VOID(pthread_mutex_unlock(&acl_cache->lock));
- int binlog_error=
+ if (result)
+ my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+
+ result= result |
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- /* error for writing binary log has already been reported */
- if (result && !binlog_error)
- my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
- DBUG_RETURN(result || binlog_error);
+ DBUG_RETURN(result);
}
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-03-29 02:32:30 +0000
+++ b/sql/sql_class.cc 2010-05-03 16:14:39 +0000
@@ -284,6 +284,37 @@ void **thd_ha_data(const THD *thd, const
return (void **) &thd->ha_data[hton->slot].ha_ptr;
}
+
+/**
+ Provide a handler data getter to simplify coding
+*/
+extern "C"
+void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
+{
+ return *thd_ha_data(thd, hton);
+}
+
+
+/**
+ Provide a handler data setter to simplify coding
+ @see thd_set_ha_data() definition in plugin.h
+*/
+extern "C"
+void thd_set_ha_data(THD *thd, const struct handlerton *hton,
+ const void *ha_data)
+{
+ plugin_ref *lock= &thd->ha_data[hton->slot].lock;
+ if (ha_data && !*lock)
+ *lock= ha_lock_engine(NULL, (handlerton*) hton);
+ else if (!ha_data && *lock)
+ {
+ plugin_unlock(NULL, *lock);
+ *lock= NULL;
+ }
+ *thd_ha_data(thd, hton)= (void*) ha_data;
+}
+
+
extern "C"
long long thd_test_options(const THD *thd, long long test_options)
{
@@ -1800,8 +1831,7 @@ static File create_file(THD *thd, char *
else
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
{
/* Write only allowed to dir or subdir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-03-29 02:32:30 +0000
+++ b/sql/sql_class.h 2010-04-14 09:53:59 +0000
@@ -1264,7 +1264,11 @@ struct Ha_data
@sa trans_register_ha()
*/
Ha_trx_info ha_info[2];
-
+ /**
+ NULL: engine is not bound to this thread
+ non-NULL: engine is bound to this thread, engine shutdown forbidden
+ */
+ plugin_ref lock;
Ha_data() :ha_ptr(NULL) {}
};
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2009-12-18 18:44:24 +0000
+++ b/sql/sql_connect.cc 2010-04-29 23:18:19 +0000
@@ -471,6 +471,13 @@ check_user(THD *thd, enum enum_server_co
}
my_ok(thd);
thd->password= test(passwd_len); // remember for error messages
+ /*
+ Allow the network layer to skip big packets. Although a malicious
+ authenticated session might use this to trick the server to read
+ big packets indefinitely, this is a previously established behavior
+ that needs to be preserved as to not break backwards compatibility.
+ */
+ thd->net.skip_big_packet= TRUE;
/* Ready to handle queries */
DBUG_RETURN(0);
}
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2010-02-06 19:54:30 +0000
+++ b/sql/sql_lex.cc 2010-04-01 13:15:22 +0000
@@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_err
*/
if (thd->lex->sphead)
{
+ thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2010-03-09 10:19:10 +0000
+++ b/sql/sql_load.cc 2010-05-03 16:14:39 +0000
@@ -348,16 +348,11 @@ int mysql_load(THD *thd,sql_exchange *ex
DBUG_ASSERT(FALSE);
#endif
}
- else if (opt_secure_file_priv)
+ else if (!is_secure_file_path(name))
{
- char secure_file_real_path[FN_REFLEN];
- (void) my_realpath(secure_file_real_path, opt_secure_file_priv, 0);
- if (strncmp(secure_file_real_path, name, strlen(secure_file_real_path)))
- {
- /* Read only allowed from within dir specified by secure_file_priv */
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- DBUG_RETURN(TRUE);
- }
+ /* Read only allowed from within dir specified by secure_file_priv */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ DBUG_RETURN(TRUE);
}
}
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-04-12 10:12:20 +0000
+++ b/sql/sql_parse.cc 2010-05-04 14:03:28 +0000
@@ -1300,8 +1300,23 @@ bool dispatch_command(enum enum_server_c
We have name + wildcard in packet, separated by endzero
*/
arg_end= strend(packet);
+ uint arg_length= arg_end - packet;
+
+ /* Check given table name length. */
+ if (arg_length >= packet_length || arg_length > NAME_LEN)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ break;
+ }
thd->convert_string(&conv_name, system_charset_info,
- packet, (uint) (arg_end - packet), thd->charset());
+ packet, arg_length, thd->charset());
+ if (check_table_name(conv_name.str, conv_name.length, FALSE))
+ {
+ /* this is OK due to convert_string() null-terminating the string */
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
+ break;
+ }
+
table_list.alias= table_list.table_name= conv_name.str;
packet= arg_end + 1;
@@ -6225,7 +6240,7 @@ TABLE_LIST *st_select_lex::add_table_to_
DBUG_RETURN(0); // End of memory
alias_str= alias ? alias->str : table->table.str;
if (!test(table_options & TL_OPTION_ALIAS) &&
- check_table_name(table->table.str, table->table.length))
+ check_table_name(table->table.str, table->table.length, FALSE))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
DBUG_RETURN(0);
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2010-03-09 12:16:17 +0000
+++ b/sql/sql_plugin.cc 2010-04-22 13:52:00 +0000
@@ -1006,9 +1006,14 @@ void plugin_unlock_list(THD *thd, plugin
static int plugin_initialize(struct st_plugin_int *plugin)
{
+ int ret= 1;
DBUG_ENTER("plugin_initialize");
safe_mutex_assert_owner(&LOCK_plugin);
+ uint state= plugin->state;
+ DBUG_ASSERT(state == PLUGIN_IS_UNINITIALIZED);
+
+ pthread_mutex_unlock(&LOCK_plugin);
if (plugin_type_initialize[plugin->plugin->type])
{
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
@@ -1027,8 +1032,7 @@ static int plugin_initialize(struct st_p
goto err;
}
}
-
- plugin->state= PLUGIN_IS_READY;
+ state= PLUGIN_IS_READY; // plugin->init() succeeded
if (plugin->plugin->status_vars)
{
@@ -1047,7 +1051,8 @@ static int plugin_initialize(struct st_p
if (add_status_vars(array)) // add_status_vars makes a copy
goto err;
#else
- add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
+ if (add_status_vars(plugin->plugin->status_vars))
+ goto err;
#endif /* FIX_LATER */
}
@@ -1067,9 +1072,12 @@ static int plugin_initialize(struct st_p
}
}
- DBUG_RETURN(0);
+ ret= 0;
+
err:
- DBUG_RETURN(1);
+ pthread_mutex_lock(&LOCK_plugin);
+ plugin->state= state;
+ DBUG_RETURN(ret);
}
@@ -1657,6 +1665,12 @@ bool mysql_install_plugin(THD *thd, cons
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
bzero(&tables, sizeof(tables));
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
@@ -1733,6 +1747,12 @@ bool mysql_uninstall_plugin(THD *thd, co
struct st_plugin_int *plugin;
DBUG_ENTER("mysql_uninstall_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
bzero(&tables, sizeof(tables));
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc 2010-03-19 09:06:40 +0000
+++ b/sql/sql_repl.cc 2010-05-04 09:17:20 +0000
@@ -1134,6 +1134,10 @@ bool change_master(THD* thd, Master_info
int thread_mask;
const char* errmsg= 0;
bool need_relay_log_purge= 1;
+ char saved_host[HOSTNAME_LENGTH + 1];
+ uint saved_port;
+ char saved_log_name[FN_REFLEN];
+ my_off_t saved_log_pos;
DBUG_ENTER("change_master");
lock_slave_threads(mi);
@@ -1163,6 +1167,17 @@ bool change_master(THD* thd, Master_info
*/
/*
+ Before processing the command, save the previous state.
+ */
+ char *pos;
+ pos= strmake(saved_host, mi->host, HOSTNAME_LENGTH);
+ pos= '\0';
+ saved_port= mi->port;
+ pos= strmake(saved_log_name, mi->master_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ saved_log_pos= mi->master_log_pos;
+
+ /*
If the user specified host or port without binlog or position,
reset binlog's name to FIRST and position to 4.
*/
@@ -1325,6 +1340,15 @@ bool change_master(THD* thd, Master_info
/* Clear the errors, for a clean start */
mi->rli.clear_error();
mi->rli.clear_until_condition();
+
+ sql_print_information("'CHANGE MASTER TO executed'. "
+ "Previous state master_host='%s', master_port='%u', master_log_file='%s', "
+ "master_log_pos='%ld'. "
+ "New state master_host='%s', master_port='%u', master_log_file='%s', "
+ "master_log_pos='%ld'.", saved_host, saved_port, saved_log_name,
+ (ulong) saved_log_pos, mi->host, mi->port, mi->master_log_name,
+ (ulong) mi->master_log_pos);
+
/*
If we don't write new coordinates to disk now, then old will remain in
relay-log.info until START SLAVE is issued; but if mysqld is shutdown
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-04-12 10:12:20 +0000
+++ b/sql/sql_select.cc 2010-04-30 11:27:17 +0000
@@ -1107,8 +1107,7 @@ JOIN::optimize()
}
if (conds && const_table_map != found_const_table_map &&
- (select_options & SELECT_DESCRIBE) &&
- select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
+ (select_options & SELECT_DESCRIBE))
{
conds=new Item_int((longlong) 0,1); // Always false
}
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2010-04-12 10:12:20 +0000
+++ b/sql/sql_table.cc 2010-05-04 14:03:28 +0000
@@ -435,7 +435,21 @@ uint tablename_to_filename(const char *f
DBUG_PRINT("enter", ("from '%s'", from));
if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
+ {
+ /*
+ Check if the name supplied is a valid mysql 5.0 name and
+ make the name a zero length string if it's not.
+ Note that just returning zero length is not enough :
+ a lot of places don't check the return value and expect
+ a zero terminated string.
+ */
+ if (check_table_name(to, length, TRUE))
+ {
+ to[0]= 0;
+ length= 0;
+ }
DBUG_RETURN(length);
+ }
length= strconvert(system_charset_info, from,
&my_charset_filename, to, to_length, &errors);
if (check_if_legal_tablename(to) &&
@@ -6922,6 +6936,13 @@ view_err:
&candidate_key_count))
goto err;
+ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
+ if (need_copy_table_res != ALTER_TABLE_METADATA_ONLY)
+ goto err; });
+ DBUG_EXECUTE_IF("alter_table_only_index_change", {
+ if (need_copy_table_res != ALTER_TABLE_INDEX_CHANGED)
+ goto err; });
+
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
need_copy_table= need_copy_table_res;
}
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2010-02-22 13:23:47 +0000
+++ b/sql/sql_update.cc 2010-04-28 12:55:54 +0000
@@ -1379,6 +1379,16 @@ int multi_update::prepare(List<Item> &no
{
table->read_set= &table->def_read_set;
bitmap_union(table->read_set, &table->tmp_set);
+ /*
+ If a timestamp field settable on UPDATE is present then to avoid wrong
+ update force the table handler to retrieve write-only fields to be able
+ to compare records and detect data change.
+ */
+ if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
+ table->timestamp_field &&
+ (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
+ table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ bitmap_union(table->read_set, table->write_set);
}
}
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-03-14 16:01:45 +0000
+++ b/sql/sql_yacc.yy 2010-05-04 14:03:28 +0000
@@ -6133,7 +6133,7 @@ alter_list_item:
{
MYSQL_YYABORT;
}
- if (check_table_name($3->table.str,$3->table.length) ||
+ if (check_table_name($3->table.str,$3->table.length, FALSE) ||
($3->db.str && check_db_name(&$3->db)))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2010-03-12 06:33:16 +0000
+++ b/sql/table.cc 2010-05-04 14:03:28 +0000
@@ -494,6 +494,26 @@ inline bool is_system_table_name(const c
}
+/**
+ Check if a string contains path elements
+*/
+
+static inline bool has_disabled_path_chars(const char *str)
+{
+ for (; *str; str++)
+ switch (*str)
+ {
+ case FN_EXTCHAR:
+ case '/':
+ case '\\':
+ case '~':
+ case '@':
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/*
Read table definition from a binary / text based .frm file
@@ -549,7 +569,8 @@ int open_table_def(THD *thd, TABLE_SHARE
This kind of tables must have been opened only by the
my_open() above.
*/
- if (strchr(share->table_name.str, '@') ||
+ if (has_disabled_path_chars(share->table_name.str) ||
+ has_disabled_path_chars(share->db.str) ||
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
@@ -2711,7 +2732,6 @@ bool check_db_name(LEX_STRING *org_name)
(name_length > NAME_CHAR_LEN)); /* purecov: inspected */
}
-
/*
Allow anything as a table name, as long as it doesn't contain an
' ' at the end
@@ -2719,7 +2739,7 @@ bool check_db_name(LEX_STRING *org_name)
*/
-bool check_table_name(const char *name, uint length)
+bool check_table_name(const char *name, uint length, bool check_for_path_chars)
{
uint name_length= 0; // name length in symbols
const char *end= name+length;
@@ -2746,6 +2766,9 @@ bool check_table_name(const char *name,
continue;
}
}
+ if (check_for_path_chars &&
+ (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
+ return 1;
#endif
name++;
name_length++;
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2009-11-03 00:52:57 +0000
+++ b/tests/mysql_client_test.c 2010-05-04 14:03:28 +0000
@@ -18049,6 +18049,50 @@ static void test_bug44495()
DBUG_VOID_RETURN;
}
+static void test_bug53371()
+{
+ int rc;
+ MYSQL_RES *result;
+
+ myheader("test_bug53371");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
+
+ rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE DATABASE bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
+ myquery(rc);
+
+ rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
+ DIE_UNLESS(rc);
+ DIE_UNLESS(mysql_errno(mysql) == 1142);
+
+ result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
+ DIE_IF(result);
+
+ result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
+ DIE_IF(result);
+
+ rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP DATABASE bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
+ myquery(rc);
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -18358,6 +18402,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug30472", test_bug30472 },
{ "test_bug20023", test_bug20023 },
{ "test_bug45010", test_bug45010 },
+ { "test_bug53371", test_bug53371 },
{ "test_bug31418", test_bug31418 },
{ "test_bug31669", test_bug31669 },
{ "test_bug28386", test_bug28386 },
Attachment: [text/bzr-bundle] bzr/vasil.dimov@oracle.com-20100511104134-prkxuymq8wysx8rf.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-innodb branch (vasil.dimov:3456) | vasil.dimov | 11 May |