diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-04 10:53:15 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2009-08-04 10:53:15 -0300 |
commit | 49d88efc078f384605edc7fb999e7678d6aa51e0 (patch) | |
tree | 0e16d7008f0346b0a3a87d68e81cfed416c2cbb4 | |
parent | 52c95d0ccfef7f897bd79ee4b48da5ec752c70c2 (diff) | |
parent | 77acccc21fd4e95811757d95788d711fff45c586 (diff) | |
download | mariadb-git-49d88efc078f384605edc7fb999e7678d6aa51e0.tar.gz |
Merge from mysql-5.0-bugteam.
69 files changed, 1531 insertions, 277 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 91c3a804eea..5705a2dfe57 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR) +CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR) +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0005 NEW) +ENDIF(COMMAND cmake_policy) PROJECT(MySql) @@ -26,6 +29,13 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in # Set standard options ADD_DEFINITIONS(-DCMAKE_BUILD) ADD_DEFINITIONS(-DHAVE_YASSL) +ADD_DEFINITIONS(-DCMAKE_CONFIGD) +ADD_DEFINITIONS(-DDEFAULT_MYSQL_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/") +ADD_DEFINITIONS(-DDEFAULT_BASEDIR="c:/Program Files/MySQL/") +ADD_DEFINITIONS(-DMYSQL_DATADIR="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/data") +ADD_DEFINITIONS(-DDEFAULT_CHARSET_HOME="c:/Program Files/MySQL/MySQL Server ${MYSQL_BASE_VERSION}/") +ADD_DEFINITIONS(-DPACKAGE=mysql) +ADD_DEFINITIONS(-DSHAREDIR="share") # Set debug options SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS") diff --git a/client/Makefile.am b/client/Makefile.am index 672bb2e0c47..e77d294b0ac 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -57,7 +57,7 @@ strings_src=decimal.c # Fix for mit-threads DEFS = -DUNDEF_THREADS_HACK \ -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ - -DDATADIR="\"$(localstatedir)\"" + -DMYSQL_DATADIR="\"$(localstatedir)\"" EXTRA_DIST = get_password.c CMakeLists.txt echo.c diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index e3500c81fb9..ff414fff592 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -387,7 +387,7 @@ static void find_tool(char *tool_executable_name, const char *tool_name, last_fn_libchar -= 6; } - len= last_fn_libchar - self_name; + len= (int) (last_fn_libchar - self_name); my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s", len, self_name, FN_LIBCHAR, tool_name); diff --git a/client/mysqldump.c b/client/mysqldump.c index fa6c21ed273..1918a657316 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3122,7 +3122,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table(hash_key,end - hash_key)) + if (include_table(hash_key,(uint) (end - hash_key))) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -3143,7 +3143,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table(hash_key, end - hash_key)) + if (include_table(hash_key, (uint) (end - hash_key))) get_view_structure(table, database); } if (opt_xml) diff --git a/dbug/dbug.c b/dbug/dbug.c index baf080f5e27..1704db79b36 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -855,8 +855,9 @@ void _db_pop_() } \ } while (0) -int _db_explain_ (CODE_STATE *cs, char *buf, size_t len) -{ +int _db_explain_ (CODE_STATE *cs, char *buf, size_t len_arg) +{ + uint len= (uint) len_arg; char *start=buf, *end=buf+len-4; get_code_state_or_return *buf=0; @@ -1267,7 +1268,7 @@ static struct link *ListAdd(struct link *head, start= ctlp; while (ctlp < end && *ctlp != ',') ctlp++; - len=ctlp-start; + len=(int) (ctlp-start); new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); memcpy(new_malloc->str, start, len); new_malloc->str[len]=0; @@ -1303,7 +1304,7 @@ static struct link *ListDel(struct link *head, { const char *start; struct link **cur; - int len; + size_t len; while (ctlp < end) { @@ -1357,7 +1358,7 @@ static struct link *ListCopy(struct link *orig) head= NULL; while (orig != NULL) { - len= strlen(orig->str); + len= (int) strlen(orig->str); new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); memcpy(new_malloc->str, orig->str, len); new_malloc->str[len]= 0; @@ -1827,7 +1828,7 @@ static void DBUGOpenFile(CODE_STATE *cs, { if (end) { - int len=end-name; + size_t len=(size_t) (end-name); memcpy(cs->stack->name, name, len); cs->stack->name[len]=0; } diff --git a/extra/perror.c b/extra/perror.c index ba638aca819..1ee2ec08d83 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -108,6 +108,7 @@ static HA_ERRORS ha_errlist[]= { 161,"The table is not writable"}, { 162,"Failed to get the next autoinc value"}, { 163,"Failed to set the row autoinc value"}, + { 164,"Too many active concurrent transactions"}, { -30999, "DB_INCOMPLETE: Sync didn't finish"}, { -30998, "DB_KEYEMPTY: Key/data deleted or never created"}, { -30997, "DB_KEYEXIST: The key/data pair already exists"}, diff --git a/include/config-netware.h b/include/config-netware.h index 85a5ef86829..b0cf7986451 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -110,7 +110,7 @@ extern "C" { #define DEFAULT_BASEDIR "sys:/" #define SHAREDIR "share/" #define DEFAULT_CHARSET_HOME "sys:/mysql/" -#define DATADIR "data/" +#define MYSQL_DATADIR "data/" /* 64-bit file system calls */ #define SIZEOF_OFF_T 8 diff --git a/include/config-win.h b/include/config-win.h index ab463a7c142..84705809d7a 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -15,15 +15,6 @@ /* Defines for Win32 to make it compatible for MySQL */ -#ifdef __WIN2000__ -/* We have to do this define before including windows.h to get the AWE API -functions */ -#define _WIN32_WINNT 0x0500 -#else -/* Get NT 4.0 functions */ -#define _WIN32_WINNT 0x0400 -#endif - #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Avoid endless warnings about sprintf() etc. being unsafe. */ #define _CRT_SECURE_NO_DEPRECATE 1 @@ -312,13 +303,15 @@ inline ulonglong double2ulonglong(double d) #ifdef _CUSTOMCONFIG_ #include <custom_conf.h> #else +#ifndef CMAKE_CONFIGD #define DEFAULT_MYSQL_HOME "c:\\mysql" -#define DATADIR "c:\\mysql\\data" +#define MYSQL_DATADIR "c:\\mysql\\data" #define PACKAGE "mysql" #define DEFAULT_BASEDIR "C:\\" #define SHAREDIR "share" #define DEFAULT_CHARSET_HOME "C:/mysql/" #endif +#endif #ifndef DEFAULT_HOME_ENV #define DEFAULT_HOME_ENV MYSQL_HOME #endif diff --git a/include/my_base.h b/include/my_base.h index e45a73d68ed..181824012d9 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -377,9 +377,10 @@ enum ha_base_keytype { #define HA_ERR_TABLE_READONLY 161 /* The table is not writable */ #define HA_ERR_AUTOINC_READ_FAILED 162/* Failed to get the next autoinc value */ #define HA_ERR_AUTOINC_ERANGE 163 /* Failed to set the row autoinc value */ +#define HA_ERR_TOO_MANY_CONCURRENT_TRXS 164 /*Too many active concurrent transactions */ /* You must also add numbers and description to extra/perror.c ! */ -#define HA_ERR_LAST 163 /*Copy last error nr.*/ +#define HA_ERR_LAST 164 /*Copy last error nr.*/ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/include/my_sys.h b/include/my_sys.h index bfb1a672641..4254ec3dbcb 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -512,7 +512,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); ((info)->write_pos + (Count) <=(info)->write_end ?\ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\ ((info)->write_pos+=(Count)),0) : \ - (*(info)->write_function)((info),(Buffer),(Count))) + (*(info)->write_function)((info),(Buffer), (uint)(Count))) #define my_b_get(info) \ ((info)->read_pos != (info)->read_end ?\ diff --git a/include/violite.h b/include/violite.h index 7b57667541a..b04fe108314 100644 --- a/include/violite.h +++ b/include/violite.h @@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T; #include <openssl/ssl.h> #include <openssl/err.h> +enum enum_ssl_init_error +{ + SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, + SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS, + SSL_INITERR_MEMFAIL, SSL_INITERR_LASTERR +}; +const char* sslGetErrString(enum enum_ssl_init_error err); + struct st_VioSSLFd { SSL_CTX *ssl_context; @@ -124,7 +132,7 @@ struct st_VioSSLFd struct st_VioSSLFd *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file,const char *ca_path, - const char *cipher); + const char *cipher, enum enum_ssl_init_error* error); #endif /* HAVE_OPENSSL */ #ifdef HAVE_SMEM diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index ad0ac53cfba..b7942d20cea 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -82,7 +82,7 @@ vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo CLEANFILES = $(target_libadd) $(SHLIBOBJS) \ $(target) DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ + -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ -DDEFAULT_HOME_ENV=MYSQL_HOME \ -DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 17e308b3324..fd2609d026e 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -23,7 +23,7 @@ MYSQLBASEdir= $(prefix) DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ + -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" INCLUDES= @bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \ -I$(top_builddir)/include -I$(top_srcdir)/include \ diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/include/rpl_trigger_common.inc index d5472b47b7b..792147e2f59 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/include/rpl_trigger_common.inc @@ -1,10 +1,4 @@ # -# Test of triggers with replication -# - -source include/master-slave.inc; - -# # #12482: Triggers has side effects with auto_increment values # @@ -284,63 +278,76 @@ while ($rnd) # 1. Check that the trigger's replication is succeeded. -# Stop the slave. +# +# This was introduced due to the following bug on windows: +# BUG#43264 Test rpl_trigger is failing randomly w/ use of copy_file in 5.0 +# Unfortunately, it is not possible to share a solution as 5.0 has the following issues: +# 1 - Inability to restart a server in the middle of a test case. +# 2 - Neither the index or the binlogs are re-opened when the slave is stopped and +# restarted. +# +if (`select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows") = 0`) +{ + # Stop the slave. -connection slave; -STOP SLAVE; + connection slave; + STOP SLAVE; -# Replace master's binlog. + # Replace master's binlog. -connection master; -FLUSH LOGS; ---remove_file $MYSQLTEST_VARDIR/log/master-bin.000001 ---copy_file $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001 + connection master; + FLUSH LOGS; + --remove_file $MYSQLTEST_VARDIR/log/master-bin.000001 + --copy_file $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001 -# Make the slave to replay the new binlog. + # Make the slave to replay the new binlog. -connection slave; -RESET SLAVE; -START SLAVE; + connection slave; + RESET SLAVE; + START SLAVE; -SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0; + SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0; -# Check that the replication succeeded. + # Check that the replication succeeded. -SHOW TABLES LIKE 't_'; -SHOW TRIGGERS; -SELECT * FROM t1; -SELECT * FROM t2; + SHOW TABLES LIKE 't_'; + SHOW TRIGGERS; + SELECT * FROM t1; + SELECT * FROM t2; -# 2. Check that the trigger is non-SUID on the slave; -# 3. Check that the trigger can be activated on the slave. + # 2. Check that the trigger is non-SUID on the slave; + # 3. Check that the trigger can be activated on the slave. -INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(2); -SELECT * FROM t1; -SELECT * FROM t2; + SELECT * FROM t1; + SELECT * FROM t2; -# That's all, cleanup. + # That's all, cleanup. -DROP TRIGGER trg1; -DROP TABLE t1; -DROP TABLE t2; + DROP TRIGGER trg1; + DROP TABLE t1; + DROP TABLE t2; -STOP SLAVE; -RESET SLAVE; + connection slave; -# The master should be clean. + STOP SLAVE; + --source include/wait_for_slave_to_stop.inc + RESET SLAVE; -connection master; -SHOW TABLES LIKE 't_'; -SHOW TRIGGERS; + # The master should be clean. -RESET MASTER; + connection master; + SHOW TABLES LIKE 't_'; + SHOW TRIGGERS; -# Restart slave. + RESET MASTER; -connection slave; -START SLAVE; + # Restart slave. + connection slave; + START SLAVE; +} # # BUG#20438: CREATE statements for views, stored routines and triggers can be diff --git a/mysql-test/r/bug40113.result b/mysql-test/r/bug40113.result new file mode 100644 index 00000000000..289037a3f35 --- /dev/null +++ b/mysql-test/r/bug40113.result @@ -0,0 +1,29 @@ +# +# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +# without error +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1070109,99); +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; +INSERT INTO t2 (b,a) VALUES (7,1070109); +SELECT * FROM t1; +a b +1070109 99 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +b +7 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1; +a b +1070109 99 +DROP TABLE t2, t1; +End of 5.0 tests diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 6ea17644f9d..b0197e0aec2 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -510,3 +510,11 @@ CREATE TABLE t1(a TEXT); SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); ERROR HY000: Incorrect arguments to AGAINST DROP TABLE t1; +CREATE TABLE t1 (col text, FULLTEXT KEY full_text (col)); +PREPARE s FROM +"SELECT MATCH (col) AGAINST('findme') FROM t1 ORDER BY MATCH (col) AGAINST('findme')" + ; +EXECUTE s; +MATCH (col) AGAINST('findme') +DEALLOCATE PREPARE s; +DROP TABLE t1; diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 1138a5e1d88..9acbbaac499 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2278,12 +2278,10 @@ Handler_read_key 8 Handler_read_next 0 FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x -FROM t1) > 10000; -Warnings: -Error 1242 Subquery returns more than 1 row +FROM t1 WHERE a = 1 AND b = 1) > 10000; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value -Handler_read_key 8 +Handler_read_key 9 Handler_read_next 1 DROP TABLE t1,t2,t3; CREATE TABLE t1 (a int, INDEX idx(a)); diff --git a/mysql-test/r/innodb-autoinc-optimize.result b/mysql-test/r/innodb-autoinc-optimize.result index 61739f0713a..49e31a3eede 100644 --- a/mysql-test/r/innodb-autoinc-optimize.result +++ b/mysql-test/r/innodb-autoinc-optimize.result @@ -4,3 +4,5 @@ insert into t1 set a = -1; optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK +==== clean up ==== +DROP TABLE t1; diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 7a37f49125a..2b977acdeb1 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -842,3 +842,16 @@ Table Op Msg_type Msg_text test.t2 check status OK drop table t1,t2; ################################################################## +# +# Bug #46075: Assertion failed: 0, file .\protocol.cc, line 416 +# +CREATE TABLE t1(a INT); +SET max_heap_table_size = 16384; +SET @old_myisam_data_pointer_size = @@myisam_data_pointer_size; +SET GLOBAL myisam_data_pointer_size = 2; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7; +ERROR HY000: The table '' is full +SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size; +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/rpl_trigger.result b/mysql-test/r/rpl_trigger_not_windows.result index 51e7c15bc12..51e7c15bc12 100644 --- a/mysql-test/r/rpl_trigger.result +++ b/mysql-test/r/rpl_trigger_not_windows.result diff --git a/mysql-test/r/rpl_trigger_windows.result b/mysql-test/r/rpl_trigger_windows.result new file mode 100644 index 00000000000..a3781a6873f --- /dev/null +++ b/mysql-test/r/rpl_trigger_windows.result @@ -0,0 +1,932 @@ +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; +create table t1 (a int auto_increment, primary key (a), b int, rand_value double not null); +create table t2 (a int auto_increment, primary key (a), b int); +create table t3 (a int auto_increment, primary key (a), name varchar(64) not null, old_a int, old_b int, rand_value double not null); +create trigger t1 before insert on t1 for each row +begin +insert into t3 values (NULL, "t1", new.a, new.b, rand()); +end| +create trigger t2 after insert on t2 for each row +begin +insert into t3 values (NULL, "t2", new.a, new.b, rand()); +end| +insert into t3 values(100,"log",0,0,0); +SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186; +insert into t1 values(1,1,rand()),(NULL,2,rand()); +insert into t2 (b) values(last_insert_id()); +insert into t2 values(3,0),(NULL,0); +insert into t2 values(NULL,0),(500,0); +select a,b, truncate(rand_value,4) from t1; +a b truncate(rand_value,4) +1 1 0.4320 +2 2 0.3055 +select * from t2; +a b +1 2 +3 0 +4 0 +5 0 +500 0 +select a,name, old_a, old_b, truncate(rand_value,4) from t3; +a name old_a old_b truncate(rand_value,4) +100 log 0 0 0.0000 +101 t1 1 1 0.3203 +102 t1 0 2 0.5666 +103 t2 1 2 0.9164 +104 t2 3 0 0.8826 +105 t2 4 0 0.6635 +106 t2 5 0 0.6699 +107 t2 500 0 0.3593 + +--- On slave -- +select a,b, truncate(rand_value,4) from t1; +a b truncate(rand_value,4) +1 1 0.4320 +2 2 0.3055 +select * from t2; +a b +1 2 +3 0 +4 0 +5 0 +500 0 +select a,name, old_a, old_b, truncate(rand_value,4) from t3; +a name old_a old_b truncate(rand_value,4) +100 log 0 0 0.0000 +101 t1 1 1 0.3203 +102 t1 0 2 0.5666 +103 t2 1 2 0.9164 +104 t2 3 0 0.8826 +105 t2 4 0 0.6635 +106 t2 5 0 0.6699 +107 t2 500 0 0.3593 +drop table t1,t2,t3; +select get_lock("bug12480",2); +get_lock("bug12480",2) +1 +create table t1 (a datetime,b datetime, c datetime); +drop function if exists bug12480; +create function bug12480() returns datetime +begin +set @a=get_lock("bug12480",2); +return now(); +end| +create trigger t1_first before insert on t1 +for each row begin +set @a=get_lock("bug12480",2); +set new.b= now(); +set new.c= bug12480(); +end +| +insert into t1 set a = now(); +select a=b && a=c from t1; +a=b && a=c +1 +SELECT routine_name, definer +FROM information_schema.routines +WHERE routine_name = 'bug12480'; +routine_name definer +bug12480 root@localhost +SELECT trigger_name, definer +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; +trigger_name definer +t1_first root@localhost + +--- On slave -- +SELECT routine_name, definer +FROM information_schema.routines +WHERE routine_name = 'bug12480'; +routine_name definer +bug12480 root@localhost +SELECT trigger_name, definer +FROM information_schema.triggers +WHERE trigger_name = 't1_first'; +trigger_name definer +t1_first root@localhost +select a=b && a=c from t1; +a=b && a=c +1 +test +1 +truncate table t1; +drop trigger t1_first; +insert into t1 values ("2003-03-03","2003-03-03","2003-03-03"),(bug12480(),bug12480(),bug12480()),(now(),now(),now()); +select a=b && a=c from t1; +a=b && a=c +1 +1 +1 +drop function bug12480; +drop table t1; +create table t1 (i int); +create table t2 (i int); +create trigger tr1 before insert on t1 for each row +begin +insert into t2 values (1); +end| +create database other; +use other; +insert into test.t1 values (1); +use test; +drop table t1,t2; +drop database other; +test case for BUG#13227 +------------------- +10 +------------------- +drop table if exists t110; +drop table if exists t210,t310; +create table t110 (f1 int) /* 2 replicate */; +insert into t110 values (-5); +insert into t110 values (-4); +insert into t110 values (-3); +insert into t110 values (-2); +insert into t110 values (-1); +select * from t110; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg110 before update on t110 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t210 where f1=NEW.f1; +INSERT INTO t310 values (r); +end| +create table t210 (f1 int, f2 int) /* slave local */; +create table t310 (f3 int) /* slave local */; +insert into t210 values (5, 5*100); +insert into t210 values (4, 4*100); +insert into t210 values (3, 3*100); +insert into t210 values (2, 2*100); +insert into t210 values (1, 1*100); +select * from t210; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t110 SET f1=5 where f1=-5; +SELECT * from t110 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t310 /* must be f3 5*100 */; +f3 +500 +UPDATE t110 SET f1=5 where f1=-5; +UPDATE t110 SET f1=4 where f1=-4; +UPDATE t110 SET f1=3 where f1=-3; +UPDATE t110 SET f1=2 where f1=-2; +UPDATE t110 SET f1=1 where f1=-1; +SELECT * from t110 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t310 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg110; +drop table t210,t310; +drop table t110; +------------------- +9 +------------------- +drop table if exists t19; +drop table if exists t29,t39; +create table t19 (f1 int) /* 2 replicate */; +insert into t19 values (-5); +insert into t19 values (-4); +insert into t19 values (-3); +insert into t19 values (-2); +insert into t19 values (-1); +select * from t19; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg19 before update on t19 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t29 where f1=NEW.f1; +INSERT INTO t39 values (r); +end| +create table t29 (f1 int, f2 int) /* slave local */; +create table t39 (f3 int) /* slave local */; +insert into t29 values (5, 5*100); +insert into t29 values (4, 4*100); +insert into t29 values (3, 3*100); +insert into t29 values (2, 2*100); +insert into t29 values (1, 1*100); +select * from t29; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t19 SET f1=5 where f1=-5; +SELECT * from t19 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t39 /* must be f3 5*100 */; +f3 +500 +UPDATE t19 SET f1=5 where f1=-5; +UPDATE t19 SET f1=4 where f1=-4; +UPDATE t19 SET f1=3 where f1=-3; +UPDATE t19 SET f1=2 where f1=-2; +UPDATE t19 SET f1=1 where f1=-1; +SELECT * from t19 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t39 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg19; +drop table t29,t39; +drop table t19; +------------------- +8 +------------------- +drop table if exists t18; +drop table if exists t28,t38; +create table t18 (f1 int) /* 2 replicate */; +insert into t18 values (-5); +insert into t18 values (-4); +insert into t18 values (-3); +insert into t18 values (-2); +insert into t18 values (-1); +select * from t18; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg18 before update on t18 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t28 where f1=NEW.f1; +INSERT INTO t38 values (r); +end| +create table t28 (f1 int, f2 int) /* slave local */; +create table t38 (f3 int) /* slave local */; +insert into t28 values (5, 5*100); +insert into t28 values (4, 4*100); +insert into t28 values (3, 3*100); +insert into t28 values (2, 2*100); +insert into t28 values (1, 1*100); +select * from t28; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t18 SET f1=5 where f1=-5; +SELECT * from t18 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t38 /* must be f3 5*100 */; +f3 +500 +UPDATE t18 SET f1=5 where f1=-5; +UPDATE t18 SET f1=4 where f1=-4; +UPDATE t18 SET f1=3 where f1=-3; +UPDATE t18 SET f1=2 where f1=-2; +UPDATE t18 SET f1=1 where f1=-1; +SELECT * from t18 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t38 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg18; +drop table t28,t38; +drop table t18; +------------------- +7 +------------------- +drop table if exists t17; +drop table if exists t27,t37; +create table t17 (f1 int) /* 2 replicate */; +insert into t17 values (-5); +insert into t17 values (-4); +insert into t17 values (-3); +insert into t17 values (-2); +insert into t17 values (-1); +select * from t17; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg17 before update on t17 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t27 where f1=NEW.f1; +INSERT INTO t37 values (r); +end| +create table t27 (f1 int, f2 int) /* slave local */; +create table t37 (f3 int) /* slave local */; +insert into t27 values (5, 5*100); +insert into t27 values (4, 4*100); +insert into t27 values (3, 3*100); +insert into t27 values (2, 2*100); +insert into t27 values (1, 1*100); +select * from t27; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t17 SET f1=5 where f1=-5; +SELECT * from t17 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t37 /* must be f3 5*100 */; +f3 +500 +UPDATE t17 SET f1=5 where f1=-5; +UPDATE t17 SET f1=4 where f1=-4; +UPDATE t17 SET f1=3 where f1=-3; +UPDATE t17 SET f1=2 where f1=-2; +UPDATE t17 SET f1=1 where f1=-1; +SELECT * from t17 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t37 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg17; +drop table t27,t37; +drop table t17; +------------------- +6 +------------------- +drop table if exists t16; +drop table if exists t26,t36; +create table t16 (f1 int) /* 2 replicate */; +insert into t16 values (-5); +insert into t16 values (-4); +insert into t16 values (-3); +insert into t16 values (-2); +insert into t16 values (-1); +select * from t16; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg16 before update on t16 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t26 where f1=NEW.f1; +INSERT INTO t36 values (r); +end| +create table t26 (f1 int, f2 int) /* slave local */; +create table t36 (f3 int) /* slave local */; +insert into t26 values (5, 5*100); +insert into t26 values (4, 4*100); +insert into t26 values (3, 3*100); +insert into t26 values (2, 2*100); +insert into t26 values (1, 1*100); +select * from t26; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t16 SET f1=5 where f1=-5; +SELECT * from t16 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t36 /* must be f3 5*100 */; +f3 +500 +UPDATE t16 SET f1=5 where f1=-5; +UPDATE t16 SET f1=4 where f1=-4; +UPDATE t16 SET f1=3 where f1=-3; +UPDATE t16 SET f1=2 where f1=-2; +UPDATE t16 SET f1=1 where f1=-1; +SELECT * from t16 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t36 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg16; +drop table t26,t36; +drop table t16; +------------------- +5 +------------------- +drop table if exists t15; +drop table if exists t25,t35; +create table t15 (f1 int) /* 2 replicate */; +insert into t15 values (-5); +insert into t15 values (-4); +insert into t15 values (-3); +insert into t15 values (-2); +insert into t15 values (-1); +select * from t15; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg15 before update on t15 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t25 where f1=NEW.f1; +INSERT INTO t35 values (r); +end| +create table t25 (f1 int, f2 int) /* slave local */; +create table t35 (f3 int) /* slave local */; +insert into t25 values (5, 5*100); +insert into t25 values (4, 4*100); +insert into t25 values (3, 3*100); +insert into t25 values (2, 2*100); +insert into t25 values (1, 1*100); +select * from t25; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t15 SET f1=5 where f1=-5; +SELECT * from t15 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t35 /* must be f3 5*100 */; +f3 +500 +UPDATE t15 SET f1=5 where f1=-5; +UPDATE t15 SET f1=4 where f1=-4; +UPDATE t15 SET f1=3 where f1=-3; +UPDATE t15 SET f1=2 where f1=-2; +UPDATE t15 SET f1=1 where f1=-1; +SELECT * from t15 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t35 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg15; +drop table t25,t35; +drop table t15; +------------------- +4 +------------------- +drop table if exists t14; +drop table if exists t24,t34; +create table t14 (f1 int) /* 2 replicate */; +insert into t14 values (-5); +insert into t14 values (-4); +insert into t14 values (-3); +insert into t14 values (-2); +insert into t14 values (-1); +select * from t14; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg14 before update on t14 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t24 where f1=NEW.f1; +INSERT INTO t34 values (r); +end| +create table t24 (f1 int, f2 int) /* slave local */; +create table t34 (f3 int) /* slave local */; +insert into t24 values (5, 5*100); +insert into t24 values (4, 4*100); +insert into t24 values (3, 3*100); +insert into t24 values (2, 2*100); +insert into t24 values (1, 1*100); +select * from t24; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t14 SET f1=5 where f1=-5; +SELECT * from t14 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t34 /* must be f3 5*100 */; +f3 +500 +UPDATE t14 SET f1=5 where f1=-5; +UPDATE t14 SET f1=4 where f1=-4; +UPDATE t14 SET f1=3 where f1=-3; +UPDATE t14 SET f1=2 where f1=-2; +UPDATE t14 SET f1=1 where f1=-1; +SELECT * from t14 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t34 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg14; +drop table t24,t34; +drop table t14; +------------------- +3 +------------------- +drop table if exists t13; +drop table if exists t23,t33; +create table t13 (f1 int) /* 2 replicate */; +insert into t13 values (-5); +insert into t13 values (-4); +insert into t13 values (-3); +insert into t13 values (-2); +insert into t13 values (-1); +select * from t13; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg13 before update on t13 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t23 where f1=NEW.f1; +INSERT INTO t33 values (r); +end| +create table t23 (f1 int, f2 int) /* slave local */; +create table t33 (f3 int) /* slave local */; +insert into t23 values (5, 5*100); +insert into t23 values (4, 4*100); +insert into t23 values (3, 3*100); +insert into t23 values (2, 2*100); +insert into t23 values (1, 1*100); +select * from t23; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t13 SET f1=5 where f1=-5; +SELECT * from t13 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t33 /* must be f3 5*100 */; +f3 +500 +UPDATE t13 SET f1=5 where f1=-5; +UPDATE t13 SET f1=4 where f1=-4; +UPDATE t13 SET f1=3 where f1=-3; +UPDATE t13 SET f1=2 where f1=-2; +UPDATE t13 SET f1=1 where f1=-1; +SELECT * from t13 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t33 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg13; +drop table t23,t33; +drop table t13; +------------------- +2 +------------------- +drop table if exists t12; +drop table if exists t22,t32; +create table t12 (f1 int) /* 2 replicate */; +insert into t12 values (-5); +insert into t12 values (-4); +insert into t12 values (-3); +insert into t12 values (-2); +insert into t12 values (-1); +select * from t12; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg12 before update on t12 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t22 where f1=NEW.f1; +INSERT INTO t32 values (r); +end| +create table t22 (f1 int, f2 int) /* slave local */; +create table t32 (f3 int) /* slave local */; +insert into t22 values (5, 5*100); +insert into t22 values (4, 4*100); +insert into t22 values (3, 3*100); +insert into t22 values (2, 2*100); +insert into t22 values (1, 1*100); +select * from t22; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t12 SET f1=5 where f1=-5; +SELECT * from t12 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t32 /* must be f3 5*100 */; +f3 +500 +UPDATE t12 SET f1=5 where f1=-5; +UPDATE t12 SET f1=4 where f1=-4; +UPDATE t12 SET f1=3 where f1=-3; +UPDATE t12 SET f1=2 where f1=-2; +UPDATE t12 SET f1=1 where f1=-1; +SELECT * from t12 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t32 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg12; +drop table t22,t32; +drop table t12; +------------------- +1 +------------------- +drop table if exists t11; +drop table if exists t21,t31; +create table t11 (f1 int) /* 2 replicate */; +insert into t11 values (-5); +insert into t11 values (-4); +insert into t11 values (-3); +insert into t11 values (-2); +insert into t11 values (-1); +select * from t11; +f1 +-5 +-4 +-3 +-2 +-1 +create trigger trg11 before update on t11 /* slave local */ +for each row +begin +DECLARE r integer; +SELECT f2 INTO r FROM t21 where f1=NEW.f1; +INSERT INTO t31 values (r); +end| +create table t21 (f1 int, f2 int) /* slave local */; +create table t31 (f3 int) /* slave local */; +insert into t21 values (5, 5*100); +insert into t21 values (4, 4*100); +insert into t21 values (3, 3*100); +insert into t21 values (2, 2*100); +insert into t21 values (1, 1*100); +select * from t21; +f1 f2 +5 500 +4 400 +3 300 +2 200 +1 100 +UPDATE t11 SET f1=5 where f1=-5; +SELECT * from t11 /* must be f1 5, 1 - 5 2 - 5 ... -1 */; +f1 +5 +-4 +-3 +-2 +-1 +SELECT * from t31 /* must be f3 5*100 */; +f3 +500 +UPDATE t11 SET f1=5 where f1=-5; +UPDATE t11 SET f1=4 where f1=-4; +UPDATE t11 SET f1=3 where f1=-3; +UPDATE t11 SET f1=2 where f1=-2; +UPDATE t11 SET f1=1 where f1=-1; +SELECT * from t11 /* must be f1 5 ... 1 */; +f1 +5 +4 +3 +2 +1 +SELECT * from t31 /* must be f3 5 * 100 ... 100 */; +f3 +500 +400 +300 +200 +100 +drop trigger trg11; +drop table t21,t31; +drop table t11; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating objects... +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); +/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 +FOR EACH ROW +INSERT INTO t2 VALUES(NEW.c * 10) */; + +---> Inserting value... +INSERT INTO t1 VALUES(1); + +---> Checking on master... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> connection: master + +---> Cleaning up... +DROP TABLE t1; +DROP TABLE t2; +drop table if exists t1; +create table t1(a int, b varchar(50)); +drop trigger not_a_trigger; +ERROR HY000: Trigger does not exist +drop trigger if exists not_a_trigger; +Warnings: +Note 1360 Trigger does not exist +create trigger t1_bi before insert on t1 +for each row set NEW.b := "In trigger t1_bi"; +insert into t1 values (1, "a"); +drop trigger if exists t1_bi; +insert into t1 values (2, "b"); +drop trigger if exists t1_bi; +Warnings: +Note 1360 Trigger does not exist +insert into t1 values (3, "c"); +select * from t1; +a b +1 In trigger t1_bi +2 b +3 c +select * from t1; +a b +1 In trigger t1_bi +2 b +3 c +drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 671e5d8f532..324a6073426 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4452,4 +4452,26 @@ WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION; DELETE FROM v3; DROP VIEW v1,v2,v3; DROP TABLE t1,t2; +# +# Bug#45061: Incorrectly market field caused wrong result. +# +CREATE TABLE `C` ( +`int_nokey` int(11) NOT NULL, +`int_key` int(11) NOT NULL, +KEY `int_key` (`int_key`) +); +INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4), +(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7), +(5,2), (1,8), (7,0), (0,9), (9,5); +SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`); +int_nokey int_key +9 9 +0 0 +5 5 +0 0 +EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY C ALL NULL NULL NULL NULL 20 Using where +DROP TABLE C; +# End of test for bug#45061. End of 5.0 tests. diff --git a/mysql-test/t/bug40113-master.opt b/mysql-test/t/bug40113-master.opt new file mode 100644 index 00000000000..462f8fbe828 --- /dev/null +++ b/mysql-test/t/bug40113-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=1 diff --git a/mysql-test/t/bug40113.test b/mysql-test/t/bug40113.test new file mode 100644 index 00000000000..6d35d0b73d3 --- /dev/null +++ b/mysql-test/t/bug40113.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +--echo # without error +--echo # + +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; + +INSERT INTO t1 (a,b) VALUES (1070109,99); + +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; + +INSERT INTO t2 (b,a) VALUES (7,1070109); + +SELECT * FROM t1; + +BEGIN; + +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +CONNECT (addconroot, localhost, root,,); +CONNECTION addconroot; + +BEGIN; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); + +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); + +--error ER_LOCK_WAIT_TIMEOUT +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); + +SELECT * FROM t1; + +CONNECTION default; +DISCONNECT addconroot; + +DROP TABLE t2, t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 76661ba4e63..9551c98f143 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -440,3 +440,18 @@ CREATE TABLE t1(a TEXT); --error ER_WRONG_ARGUMENTS SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); DROP TABLE t1; + +# +# BUG#37740 Server crashes on execute statement with full text search and match against +# + +CREATE TABLE t1 (col text, FULLTEXT KEY full_text (col)); + +PREPARE s FROM + "SELECT MATCH (col) AGAINST('findme') FROM t1 ORDER BY MATCH (col) AGAINST('findme')" + ; + +EXECUTE s; +DEALLOCATE PREPARE s; +DROP TABLE t1; + diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 163c170eaa0..c81babb42e6 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -866,7 +866,7 @@ DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000; SHOW STATUS LIKE 'handler_read__e%'; FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x - FROM t1) > 10000; + FROM t1 WHERE a = 1 AND b = 1) > 10000; SHOW STATUS LIKE 'handler_read__e%'; DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/innodb-autoinc-optimize.test b/mysql-test/t/innodb-autoinc-optimize.test index c7e22a8ff40..0f0cb57f92f 100644 --- a/mysql-test/t/innodb-autoinc-optimize.test +++ b/mysql-test/t/innodb-autoinc-optimize.test @@ -14,3 +14,6 @@ insert into t1 set a = -1; # NOTE: The database needs to be shutdown and restarted (here) for # the test to work. It's included for reference only. optimize table t1; + +--echo ==== clean up ==== +DROP TABLE t1; diff --git a/mysql-test/t/innodb_notembedded.test b/mysql-test/t/innodb_notembedded.test index 53332d9fda4..4c29781184d 100644 --- a/mysql-test/t/innodb_notembedded.test +++ b/mysql-test/t/innodb_notembedded.test @@ -33,8 +33,15 @@ rollback; connection b; reap; rollback; + +# Cleanup +connection a; +disconnect a; +--source include/wait_until_disconnected.inc +connection b; +disconnect b; +--source include/wait_until_disconnected.inc connection default; drop table t1; drop function f1; -disconnect a; -disconnect b; + diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 78a903e0d18..06ed858b696 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -397,3 +397,24 @@ check table t2 extended; drop table t1,t2; --echo ################################################################## +--echo # +--echo # Bug #46075: Assertion failed: 0, file .\protocol.cc, line 416 +--echo # + +CREATE TABLE t1(a INT); +# To force MyISAM temp. table in the following INSERT ... SELECT. +SET max_heap_table_size = 16384; +# To overflow the temp. table. +SET @old_myisam_data_pointer_size = @@myisam_data_pointer_size; +SET GLOBAL myisam_data_pointer_size = 2; + +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); + +--error ER_RECORD_FILE_FULL +INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7; + +# Cleanup +SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/rpl_trigger_not_windows.test b/mysql-test/t/rpl_trigger_not_windows.test new file mode 100644 index 00000000000..b90e0f504f4 --- /dev/null +++ b/mysql-test/t/rpl_trigger_not_windows.test @@ -0,0 +1,8 @@ +# +# Test of triggers with replication +# + +source include/master-slave.inc; +source include/not_windows.inc; + +--source include/rpl_trigger_common.inc diff --git a/mysql-test/t/rpl_trigger_windows.test b/mysql-test/t/rpl_trigger_windows.test new file mode 100644 index 00000000000..f1bd73f10b6 --- /dev/null +++ b/mysql-test/t/rpl_trigger_windows.test @@ -0,0 +1,8 @@ +# +# Test of triggers with replication +# + +source include/master-slave.inc; +source include/windows.inc; + +--source include/rpl_trigger_common.inc diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 96e5738526b..9d4fc9030f2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3428,4 +3428,26 @@ DELETE FROM v3; DROP VIEW v1,v2,v3; DROP TABLE t1,t2; +--echo # +--echo # Bug#45061: Incorrectly market field caused wrong result. +--echo # +CREATE TABLE `C` ( + `int_nokey` int(11) NOT NULL, + `int_key` int(11) NOT NULL, + KEY `int_key` (`int_key`) +); + +INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4), +(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7), +(5,2), (1,8), (7,0), (0,9), (9,5); + +--disable_warnings +SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`); +EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`); +--enable_warnings + +DROP TABLE C; +--echo # End of test for bug#45061. + + --echo End of 5.0 tests. diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 8c6bf5f7006..7cb87492b40 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -66,7 +66,7 @@ libmysys_a_LIBADD = @THREAD_LOBJECTS@ # charset2html_DEPENDENCIES= $(LIBRARIES) EXTRA_PROGRAMS = DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ + -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ -DDEFAULT_HOME_ENV=MYSQL_HOME \ diff --git a/mysys/array.c b/mysys/array.c index 4ea1946d837..354508f05ef 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -31,10 +31,10 @@ DESCRIPTION init_dynamic_array() initiates array and allocate space for init_alloc eilements. - Array is usable even if space allocation failed. + Array is usable even if space allocation failed, hence, the + function never returns TRUE. RETURN VALUE - TRUE my_malloc_ci() failed FALSE Ok */ @@ -56,11 +56,12 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, array->max_element=init_alloc; array->alloc_increment=alloc_increment; array->size_of_element=element_size; - if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME)))) - { + /* + Since the dynamic array is usable even if allocation fails here malloc + should not throw an error + */ + if (!(array->buffer= (char*) my_malloc_ci(element_size*init_alloc, MYF(0)))) array->max_element=0; - DBUG_RETURN(TRUE); - } DBUG_RETURN(FALSE); } diff --git a/ndb/src/mgmsrv/Makefile.am b/ndb/src/mgmsrv/Makefile.am index 3d1845957e6..495d31c8d15 100644 --- a/ndb/src/mgmsrv/Makefile.am +++ b/ndb/src/mgmsrv/Makefile.am @@ -48,7 +48,7 @@ LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CommandInterpreter.lo \ @TERMCAP_LIB@ DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ + -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\"" diff --git a/sql/Makefile.am b/sql/Makefile.am index 2a0d59d0ab9..e4f339384c9 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -114,7 +114,7 @@ mysql_tzinfo_to_sql_LDADD = @MYSQLD_EXTRA_LDFLAGS@ $(LDADD) $(CXXLDFLAGS) DEFS = -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DDATADIR="\"$(MYSQLDATAdir)\"" \ + -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ @DEFS@ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 7eb6ef05d9c..4bd54805a95 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -526,17 +526,7 @@ convert_error_code_to_mysql( return(HA_ERR_LOCK_TABLE_FULL); } else if (error == DB_TOO_MANY_CONCURRENT_TRXS) { - /* Once MySQL add the appropriate code to errmsg.txt then - we can get rid of this #ifdef. NOTE: The code checked by - the #ifdef is the suggested name for the error condition - and the actual error code name could very well be different. - This will require some monitoring, ie. the status - of this request on our part.*/ -#ifdef ER_TOO_MANY_CONCURRENT_TRXS - return(ER_TOO_MANY_CONCURRENT_TRXS); -#else - return(HA_ERR_RECORD_FILE_FULL); -#endif + return(HA_ERR_TOO_MANY_CONCURRENT_TRXS); } else if (error == DB_UNSUPPORTED) { diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index dadd39bb6e8..dfd739f6db8 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1487,10 +1487,8 @@ bool ha_myisam::check_and_repair(THD *thd) old_query= thd->query; old_query_length= thd->query_length; - pthread_mutex_lock(&LOCK_thread_count); - thd->query= (char*) table->s->table_name; - thd->query_length= (uint32) strlen(table->s->table_name); - pthread_mutex_unlock(&LOCK_thread_count); + thd->set_query((char*) table->s->table_name, + (uint32) strlen(table->s->table_name)); if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt)) { @@ -1503,10 +1501,7 @@ bool ha_myisam::check_and_repair(THD *thd) if (repair(thd, &check_opt)) error=1; } - pthread_mutex_lock(&LOCK_thread_count); - thd->query= old_query; - thd->query_length= old_query_length; - pthread_mutex_unlock(&LOCK_thread_count); + thd->set_query(old_query, old_query_length); DBUG_RETURN(error); } diff --git a/sql/handler.cc b/sql/handler.cc index 2840037024b..e2941bfaecf 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -426,6 +426,7 @@ static int ha_init_errors(void) SETMSG(HA_ERR_TABLE_READONLY, ER(ER_OPEN_AS_READONLY)); SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER(ER_AUTOINC_READ_FAILED)); SETMSG(HA_ERR_AUTOINC_ERANGE, ER(ER_WARN_DATA_OUT_OF_RANGE)); + SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER(ER_TOO_MANY_CONCURRENT_TRXS)); /* Register the error messages for use with my_error(). */ return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -1927,6 +1928,9 @@ void handler::print_error(int error, myf errflag) case HA_ERR_AUTOINC_ERANGE: textno= ER_WARN_DATA_OUT_OF_RANGE; break; + case HA_ERR_TOO_MANY_CONCURRENT_TRXS: + textno= ER_TOO_MANY_CONCURRENT_TRXS; + break; default: { /* The error was "unknown" to this function. diff --git a/sql/item.cc b/sql/item.cc index 1e379527fb7..eecb48aa16f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -598,6 +598,7 @@ bool Item_ident::remove_dependence_processor(byte * arg) DBUG_ENTER("Item_ident::remove_dependence_processor"); if (depended_from == (st_select_lex *) arg) depended_from= 0; + context= &((st_select_lex *) arg)->context; DBUG_RETURN(0); } diff --git a/sql/item_func.h b/sql/item_func.h index 33aeddfe6e6..47a13559e90 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1456,6 +1456,7 @@ public: ft_handler->please->close_search(ft_handler); ft_handler= 0; concat_ws= 0; + table= 0; // required by Item_func_match::eq() DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 13eeba3ea27..805669b3cfa 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1145,6 +1145,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, else { // it is single select without tables => possible optimization + // remove the dependence mark since the item is moved to upper + // select and is not outer anymore. + item->walk(&Item::remove_dependence_processor, + (byte *) select_lex->outer_select()); item= func->create(left_expr, item); // fix_field of item will be done in time of substituting substitution= item; diff --git a/sql/log_event.cc b/sql/log_event.cc index d50c7cc8111..9b0f8e97a28 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1960,8 +1960,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - thd->query_length= q_len_arg; - thd->query= (char*)query_arg; + thd->set_query((char*)query_arg, q_len_arg); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = next_query_id(); VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -2164,7 +2163,6 @@ Default database: '%s'. Query: '%s'", } /* End of if (db_ok(... */ end: - VOID(pthread_mutex_lock(&LOCK_thread_count)); /* Probably we have set thd->query, thd->db, thd->catalog to point to places in the data_buf of this event. Now the event is going to be deleted @@ -2177,10 +2175,8 @@ end: */ thd->catalog= 0; thd->set_db(NULL, 0); /* will free the current database */ + thd->set_query(NULL, 0); DBUG_PRINT("info", ("end: query= 0")); - thd->query= 0; // just to be sure - thd->query_length= 0; - VOID(pthread_mutex_unlock(&LOCK_thread_count)); close_thread_tables(thd); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); /* @@ -3259,8 +3255,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start, (char **)&thd->lex->fname_end); *end= 0; - thd->query_length= (uint) (end - load_data_query); - thd->query= load_data_query; + thd->set_query(load_data_query, (uint) (end - load_data_query)); if (sql_ex.opt_flags & REPLACE_FLAG) { @@ -3366,12 +3361,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, error: thd->net.vio = 0; const char *remember_db= thd->db; - VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->catalog= 0; thd->set_db(NULL, 0); /* will free the current database */ - thd->query= 0; - thd->query_length= 0; - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + thd->set_query(NULL, 0); close_thread_tables(thd); if (thd->query_error) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 592ae3e755a..37b3754d716 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3036,7 +3036,7 @@ static int init_common_variables(const char *conf_file_name, int argc, sys_init_connect.value_length= 0; if ((sys_init_connect.value= opt_init_connect)) - sys_init_connect.value_length= strlen(opt_init_connect); + sys_init_connect.value_length= (uint) strlen(opt_init_connect); else sys_init_connect.value=my_strdup("",MYF(0)); sys_init_connect.is_os_charset= TRUE; @@ -3249,14 +3249,17 @@ static void init_ssl() #ifdef HAVE_OPENSSL if (opt_use_ssl) { + enum enum_ssl_init_error error= SSL_INITERR_NOERROR; + /* having ssl_acceptor_fd != 0 signals the use of SSL */ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, - opt_ssl_cipher); + opt_ssl_cipher, &error); DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd)); if (!ssl_acceptor_fd) { sql_print_warning("Failed to setup SSL"); + sql_print_warning("SSL error: %s", sslGetErrString(error)); opt_use_ssl = 0; have_ssl= SHOW_OPTION_DISABLED; } @@ -3747,7 +3750,6 @@ int main(int argc, char **argv) select_thread=pthread_self(); select_thread_in_use=1; - init_ssl(); #ifdef HAVE_LIBWRAP libwrapName= my_progname+dirname_length(my_progname); @@ -3804,6 +3806,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); if (init_server_components()) exit(1); + init_ssl(); network_init(); #ifdef __WIN__ @@ -6168,7 +6171,7 @@ The minimum value for this variable is 4096.", "Joins that are probably going to read more than max_join_size records return an error.", (gptr*) &global_system_variables.max_join_size, (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, - ~0L, 1, ~0L, 0, 1, 0}, + HA_POS_ERROR, 1, HA_POS_ERROR, 0, 1, 0}, {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA, "Max number of bytes in sorted records.", (gptr*) &global_system_variables.max_length_for_sort_data, @@ -6862,7 +6865,7 @@ static void mysql_init_variables(void) /* Set directory paths */ strmake(language, LANGUAGE, sizeof(language)-1); - strmake(mysql_real_data_home, get_relative_path(DATADIR), + strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR), sizeof(mysql_real_data_home)-1); mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here mysql_data_home_buff[1]=0; @@ -7840,7 +7843,7 @@ static void fix_paths(void) } convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0)); - mysql_unpacked_real_data_home_len= strlen(mysql_unpacked_real_data_home); + mysql_unpacked_real_data_home_len= (int) strlen(mysql_unpacked_real_data_home); if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR) --mysql_unpacked_real_data_home_len; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 627a5fae5e3..fdabad6f569 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -188,10 +188,12 @@ my_bool net_realloc(NET *net, ulong length) pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); /* We must allocate some extra bytes for the end 0 and to be able to - read big compressed blocks + read big compressed blocks + 1 safety byte since uint3korr() in + my_real_read() may actually read 4 bytes depending on build flags and + platform. */ if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length + - NET_HEADER_SIZE + COMP_HEADER_SIZE, + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1, MYF(MY_WME)))) { net->error= 1; @@ -919,6 +921,13 @@ my_real_read(NET *net, ulong *complen) #ifdef HAVE_COMPRESS if (net->compress) { + /* + The following uint3korr() may read 4 bytes, so make sure we don't + read unallocated or uninitialized memory. The right-hand expression + must match the size of the buffer allocated in net_realloc(). + */ + DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <= + net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1); /* If the packet is compressed then complen > 0 and contains the number of bytes in the uncompressed packet diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 571a342fa17..32f9b0df4c0 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -792,7 +792,7 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, PARAM *param): Sql_alloc() SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, PARAM *param) : Sql_alloc() { - uint elements= (arg->trees_end - arg->trees); + uint elements= (uint) (arg->trees_end - arg->trees); if (elements > PREALLOCED_TREES) { uint size= elements * sizeof (SEL_TREE **); diff --git a/sql/set_var.cc b/sql/set_var.cc index aebebb3b465..c885f7160e9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3528,7 +3528,7 @@ int set_var_password::check(THD *thd) { DBUG_ASSERT(thd->security_ctx->priv_user); user->user.str= (char *) thd->security_ctx->priv_user; - user->user.length= strlen(thd->security_ctx->priv_user); + user->user.length= (uint) strlen(thd->security_ctx->priv_user); } /* Returns 1 as the function sends error to client */ return check_change_password(thd, user->host.str, user->user.str, diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c688ba88b7b..2b43ba099e3 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5649,3 +5649,5 @@ ER_XA_RBTIMEOUT XA106 eng "XA_RBTIMEOUT: Transaction branch was rolled back: took too long" ER_XA_RBDEADLOCK XA102 eng "XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected" +ER_TOO_MANY_CONCURRENT_TRXS + eng "Too many active concurrent transactions" diff --git a/sql/slave.cc b/sql/slave.cc index 33ce8c21963..c5565902832 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -755,7 +755,7 @@ int terminate_slave_thread(THD* thd, int error; DBUG_PRINT("loop", ("killing slave thread")); - pthread_mutex_lock(&thd->LOCK_delete); + pthread_mutex_lock(&thd->LOCK_thd_data); #ifndef DONT_USE_THR_ALARM /* Error codes from pthread_kill are: @@ -766,7 +766,7 @@ int terminate_slave_thread(THD* thd, DBUG_ASSERT(err != EINVAL); #endif thd->awake(THD::NOT_KILLED); - pthread_mutex_unlock(&thd->LOCK_delete); + pthread_mutex_unlock(&thd->LOCK_thd_data); /* There is a small chance that slave thread might miss the first @@ -1608,15 +1608,13 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, DBUG_RETURN(1); } thd->command = COM_TABLE_DUMP; - thd->query_length= packet_len; - /* Note that we should not set thd->query until the area is initalized */ if (!(query = thd->strmake((char*) net->read_pos, packet_len))) { sql_print_error("create_table_from_dump: out of memory"); my_message(ER_GET_ERRNO, "Out of memory", MYF(0)); DBUG_RETURN(1); } - thd->query= query; + thd->set_query(query, packet_len); thd->query_error = 0; thd->net.no_send_ok = 1; @@ -3867,11 +3865,8 @@ err: // print the current replication position sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s", IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); - VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->query= 0; // extra safety - thd->query_length= 0; + thd->set_query(NULL, 0); thd->reset_db(NULL, 0); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { /* @@ -4105,17 +4100,14 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff)); err: - VOID(pthread_mutex_lock(&LOCK_thread_count)); /* Some extra safety, which should not been needed (normally, event deletion should already have done these assignments (each event which sets these variables is supposed to set them to 0 before terminating)). */ - thd->catalog= 0; + thd->catalog= 0; + thd->set_query(NULL, 0); thd->reset_db(NULL, 0); - thd->query= 0; - thd->query_length= 0; - VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd_proc_info(thd, "Waiting for slave mutex on exit"); pthread_mutex_lock(&rli->run_lock); /* We need data_lock, at least to wake up any waiting master_pos_wait() */ diff --git a/sql/sp.cc b/sql/sp.cc index 2450e9564d0..1471eb31eed 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -430,9 +430,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, type, NULL, 0, name->m_name.str, name->m_name.length, - params, strlen(params), - returns, strlen(returns), - body, strlen(body), + params, (ulong) strlen(params), + returns, (ulong) strlen(returns), + body, (ulong) strlen(body), &chistics, &definer_user_name, &definer_host_name)) { ret= SP_INTERNAL_ERROR; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 240948d217c..e32dd75486b 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -949,8 +949,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) else DBUG_RETURN(TRUE); - thd->query= pbuf; - thd->query_length= qbuf.length(); + thd->set_query(pbuf, qbuf.length()); DBUG_RETURN(FALSE); } @@ -2654,8 +2653,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) } else *nextp= m_ip+1; - thd->query= query; - thd->query_length= query_length; + thd->set_query(query, query_length); thd->query_name_consts= 0; } DBUG_RETURN(res); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 34d7e773ca2..ab4e518d5dd 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5988,15 +5988,15 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, int i= 2; CHARSET_INFO *cs= system_charset_info; restore_record(table, s->default_values); - table->field[0]->store(buff, strlen(buff), cs); + table->field[0]->store(buff, (uint) strlen(buff), cs); if (db) - table->field[i++]->store(db, strlen(db), cs); + table->field[i++]->store(db, (uint) strlen(db), cs); if (t_name) - table->field[i++]->store(t_name, strlen(t_name), cs); + table->field[i++]->store(t_name, (uint) strlen(t_name), cs); if (column) table->field[i++]->store(column, col_length, cs); table->field[i++]->store(priv, priv_length, cs); - table->field[i]->store(is_grantable, strlen(is_grantable), cs); + table->field[i]->store(is_grantable, (uint) strlen(is_grantable), cs); return schema_table_store_record(thd, table); } #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0f86a3dd311..56ab50835b6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5095,7 +5095,13 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, /* make * substituting permanent */ SELECT_LEX *select_lex= thd->lex->current_select; select_lex->with_wild= 0; - select_lex->item_list= fields; + /* + The assignment below is translated to memcpy() call (at least on some + platforms). memcpy() expects that source and destination areas do not + overlap. That problem was detected by valgrind. + */ + if (&select_lex->item_list != &fields) + select_lex->item_list= fields; thd->restore_active_arena(arena, &backup); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 387e7022d71..7d26759cb16 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -259,7 +259,7 @@ THD::THD() #ifdef SIGNAL_WITH_VIO_CLOSE active_vio = 0; #endif - pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST); /* Variables with default values */ proc_info="login"; @@ -486,8 +486,8 @@ THD::~THD() THD_CHECK_SENTRY(this); DBUG_ENTER("~THD()"); /* Ensure that no one is using THD */ - pthread_mutex_lock(&LOCK_delete); - pthread_mutex_unlock(&LOCK_delete); + pthread_mutex_lock(&LOCK_thd_data); + pthread_mutex_unlock(&LOCK_thd_data); add_to_status(&global_status_var, &status_var); /* Close connection */ @@ -513,7 +513,7 @@ THD::~THD() free_root(&transaction.mem_root,MYF(0)); #endif mysys_var=0; // Safety (shouldn't be needed) - pthread_mutex_destroy(&LOCK_delete); + pthread_mutex_destroy(&LOCK_thd_data); #ifndef DBUG_OFF dbug_sentry= THD_SENTRY_GONE; #endif @@ -551,7 +551,7 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) void THD::awake(THD::killed_state state_to_set) { THD_CHECK_SENTRY(this); - safe_mutex_assert_owner(&LOCK_delete); + safe_mutex_assert_owner(&LOCK_thd_data); killed= state_to_set; if (state_to_set != THD::KILL_QUERY) @@ -895,7 +895,7 @@ int THD::send_explain_fields(select_result *result) void THD::close_active_vio() { DBUG_ENTER("close_active_vio"); - safe_mutex_assert_owner(&LOCK_delete); + safe_mutex_assert_owner(&LOCK_thd_data); #ifndef EMBEDDED_LIBRARY if (active_vio) { @@ -2323,6 +2323,25 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup) } +void THD::set_statement(Statement *stmt) +{ + pthread_mutex_lock(&LOCK_thd_data); + Statement::set_statement(stmt); + pthread_mutex_unlock(&LOCK_thd_data); +} + + +/** Assign a new value to thd->query. */ + +void THD::set_query(char *query_arg, uint32 query_length_arg) +{ + pthread_mutex_lock(&LOCK_thd_data); + query= query_arg; + query_length= query_length_arg; + pthread_mutex_unlock(&LOCK_thd_data); +} + + /** Mark transaction to rollback and mark error as fatal to a sub-statement. diff --git a/sql/sql_class.h b/sql/sql_class.h index 82c464cb475..7c747e459a4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -835,22 +835,16 @@ public: we need to declare it char * because all table handlers are written in C and need to point to it. - Note that (A) if we set query = NULL, we must at the same time set - query_length = 0, and protect the whole operation with the - LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a - non-NULL value if its previous value is NULL. We do not need to protect - operation (B) with any mutex. To avoid crashes in races, if we do not - know that thd->query cannot change at the moment, one should print + Note that if we set query = NULL, we must at the same time set + query_length = 0, and protect the whole operation with + LOCK_thd_data mutex. To avoid crashes in races, if we do not + know that thd->query cannot change at the moment, we should print thd->query like this: - (1) reserve the LOCK_thread_count mutex; - (2) check if thd->query is NULL; - (3) if not NULL, then print at most thd->query_length characters from - it. We will see the query_length field as either 0, or the right value - for it. - Assuming that the write and read of an n-bit memory field in an n-bit - computer is atomic, we can avoid races in the above way. - This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB - STATUS. + (1) reserve the LOCK_thd_data mutex; + (2) print or copy the value of query and query_length + (3) release LOCK_thd_data mutex. + This printing is needed at least in SHOW PROCESSLIST and SHOW + ENGINE INNODB STATUS. */ char *query; uint32 query_length; // current query length @@ -866,7 +860,7 @@ public: virtual ~Statement(); /* Assign execution context (note: not all members) of given stmt to self */ - void set_statement(Statement *stmt); + virtual void set_statement(Statement *stmt); void set_n_backup_statement(Statement *stmt, Statement *backup); void restore_backup_statement(Statement *stmt, Statement *backup); /* return class type */ @@ -1229,7 +1223,15 @@ public: THR_LOCK_OWNER main_lock_id; // To use for conventional queries THR_LOCK_OWNER *lock_id; // If not main_lock_id, points to // the lock_id of a cursor. - pthread_mutex_t LOCK_delete; // Locked before thd is deleted + /** + Protects THD data accessed from other threads: + - thd->query and thd->query_length (used by SHOW ENGINE + INNODB STATUS and SHOW PROCESSLIST + - thd->mysys_var (used by KILL statement and shutdown). + Is locked when THD is deleted. + */ + pthread_mutex_t LOCK_thd_data; + /* all prepared statements and cursors of this connection */ Statement_map stmt_map; /* @@ -1637,15 +1639,15 @@ public: #ifdef SIGNAL_WITH_VIO_CLOSE inline void set_active_vio(Vio* vio) { - pthread_mutex_lock(&LOCK_delete); + pthread_mutex_lock(&LOCK_thd_data); active_vio = vio; - pthread_mutex_unlock(&LOCK_delete); + pthread_mutex_unlock(&LOCK_thd_data); } inline void clear_active_vio() { - pthread_mutex_lock(&LOCK_delete); + pthread_mutex_lock(&LOCK_thd_data); active_vio = 0; - pthread_mutex_unlock(&LOCK_delete); + pthread_mutex_unlock(&LOCK_thd_data); } void close_active_vio(); #endif @@ -1882,6 +1884,14 @@ public: */ void pop_internal_handler(); + /** Overloaded to guard query/query_length fields */ + virtual void set_statement(Statement *stmt); + + /** + Assign a new value to thd->query. + Protected with LOCK_thd_data mutex. + */ + void set_query(char *query_arg, uint32 query_length_arg); private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 30b14209a7c..3bf088609cd 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -144,6 +144,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, delete select; free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; + /* + Error was already created by quick select evaluation (check_quick()). + TODO: Add error code output parameter to Item::val_xxx() methods. + Currently they rely on the user checking DA for + errors when unwinding the stack after calling Item::val_xxx(). + */ + if (thd->net.report_error) + DBUG_RETURN(TRUE); send_ok(thd,0L); /* @@ -407,7 +415,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) if (select_lex->inner_refs_list.elements && fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); select_lex->fix_prepare_information(thd, conds, &fake_conds); DBUG_RETURN(FALSE); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 83f3b181091..d2a0f47f1a9 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1854,7 +1854,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) thread_count++; pthread_mutex_unlock(&LOCK_thread_count); di->thd.set_db(table_list->db, (uint) strlen(table_list->db)); - di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME)); + di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0); if (di->thd.db == NULL || di->thd.query == NULL) { /* The error is reported */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bcde4a971d0..45f70964f50 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1106,8 +1106,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var, values of init_command_var can't be changed */ rw_rdlock(var_mutex); - thd->query= init_command_var->value; - thd->query_length= init_command_var->value_length; + thd->set_query(init_command_var->value, init_command_var->value_length); save_client_capabilities= thd->client_capabilities; thd->client_capabilities|= CLIENT_MULTI_QUERIES; /* @@ -1326,6 +1325,7 @@ pthread_handler_t handle_bootstrap(void *arg) thd->init_for_queries(); while (fgets(buff, thd->net.max_packet, file)) { + char *query; ulong length= (ulong) strlen(buff); while (buff[length-1] != '\n' && !feof(file)) { @@ -1350,10 +1350,9 @@ pthread_handler_t handle_bootstrap(void *arg) buff[length-1] == ';')) length--; buff[length]=0; - thd->query_length=length; - thd->query= thd->memdup_w_gap(buff, length+1, - thd->db_length+1+QUERY_CACHE_FLAGS_SIZE); - thd->query[length] = '\0'; + query= thd->memdup_w_gap(buff, length + 1, + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE); + thd->set_query(query, length); DBUG_PRINT("query",("%-.4096s",thd->query)); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.set_query_source(thd->query, length); @@ -1463,8 +1462,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name) if (check_one_table_access(thd, SELECT_ACL, table_list)) goto err; thd->free_list = 0; - thd->query_length=(uint) strlen(tbl_name); - thd->query = tbl_name; + thd->set_query(tbl_name, (uint) strlen(tbl_name)); if ((error = mysqld_dump_create_info(thd, table_list, -1))) { my_error(ER_GET_ERRNO, MYF(0), my_errno); @@ -1987,9 +1985,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->profiling.set_query_source(next_packet, length); #endif + thd->set_query(next_packet, length); VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->query_length= length; - thd->query= next_packet; /* Count each statement from the client. */ @@ -2041,9 +2038,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, table_list.schema_table= schema_table; } - thd->query_length= (uint) strlen(packet); // for simplicity: don't optimize - if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) + uint query_length= (uint) strlen(packet); + if (!(fields= thd->memdup(packet, query_length + 1))) break; + thd->set_query(fields, query_length); mysql_log.write(thd,command,"%s %s",table_list.table_name, fields); if (lower_case_table_names) my_casedn_str(files_charset_info, table_list.table_name); @@ -2327,13 +2325,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, log_slow_statement(thd); thd_proc_info(thd, "cleaning up"); - VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list - thd_proc_info(thd, 0); + thd->set_query(NULL, 0); thd->command=COM_SLEEP; - thd->query=0; - thd->query_length=0; + VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); + thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); DBUG_RETURN(error); @@ -2536,6 +2533,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, bool alloc_query(THD *thd, const char *packet, uint packet_length) { + char *query; packet_length--; // Remove end null /* Remove garbage at start and end of query */ while (my_isspace(thd->charset(),packet[0]) && packet_length > 0) @@ -2551,14 +2549,13 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length) packet_length--; } /* We must allocate some extra memory for query cache */ - thd->query_length= 0; // Extra safety: Avoid races - if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), - packet_length, - thd->db_length+ 1 + - QUERY_CACHE_FLAGS_SIZE))) - return TRUE; - thd->query[packet_length]=0; - thd->query_length= packet_length; + if (! (query= (char*) thd->memdup_w_gap(packet, + packet_length, + 1 + thd->db_length + + QUERY_CACHE_FLAGS_SIZE))) + return TRUE; + query[packet_length]= '\0'; + thd->set_query(query, packet_length); /* Reclaim some memory */ thd->packet.shrink(thd->variables.net_buffer_length); @@ -7506,7 +7503,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) { if (tmp->thread_id == id) { - pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete + pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete break; } } @@ -7539,7 +7536,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) } else error=ER_KILL_DENIED_ERROR; - pthread_mutex_unlock(&tmp->LOCK_delete); + pthread_mutex_unlock(&tmp->LOCK_thd_data); } if (!error) @@ -8231,7 +8228,7 @@ int test_if_data_home_dir(const char *dir) (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); - dir_len= strlen(path); + dir_len= (int) strlen(path); if (mysql_unpacked_real_data_home_len<= dir_len) { if (dir_len > mysql_unpacked_real_data_home_len && diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index f87f92471a3..90cbd02dd1b 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -119,7 +119,7 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table) if (field) { field->set_name(field_info->old_name, - strlen(field_info->old_name), + (uint) strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) return 1; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 3d2cee6433b..f8654402bcd 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1044,7 +1044,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) if (tmp->command == COM_BINLOG_DUMP && tmp->server_id == slave_server_id) { - pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete + pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete break; } } @@ -1057,7 +1057,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) again. We just to do kill the thread ourselves. */ tmp->awake(THD::KILL_QUERY); - pthread_mutex_unlock(&tmp->LOCK_delete); + pthread_mutex_unlock(&tmp->LOCK_thd_data); } } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 672ebaf9259..0a5706ee989 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1748,7 +1748,8 @@ JOIN::exec() curr_join->having= curr_join->tmp_having= 0; // Allready done /* Change sum_fields reference to calculated fields in tmp_table */ - curr_join->all_fields= *curr_all_fields; + if (curr_join != this) + curr_join->all_fields= *curr_all_fields; if (!items1) { items1= items0 + all_fields.elements; @@ -1767,8 +1768,11 @@ JOIN::exec() fields_list.elements, all_fields)) DBUG_VOID_RETURN; } - curr_join->tmp_all_fields1= tmp_all_fields1; - curr_join->tmp_fields_list1= tmp_fields_list1; + if (curr_join != this) + { + curr_join->tmp_all_fields1= tmp_all_fields1; + curr_join->tmp_fields_list1= tmp_fields_list1; + } curr_join->items1= items1; } curr_all_fields= &tmp_all_fields1; @@ -1913,8 +1917,11 @@ JOIN::exec() tmp_fields_list2, tmp_all_fields2, fields_list.elements, tmp_all_fields1)) DBUG_VOID_RETURN; - curr_join->tmp_fields_list2= tmp_fields_list2; - curr_join->tmp_all_fields2= tmp_all_fields2; + if (curr_join != this) + { + curr_join->tmp_fields_list2= tmp_fields_list2; + curr_join->tmp_all_fields2= tmp_all_fields2; + } } curr_fields_list= &curr_join->tmp_fields_list2; curr_all_fields= &curr_join->tmp_all_fields2; @@ -1969,8 +1976,11 @@ JOIN::exec() tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field; tmp_table_param.save_copy_field_end= curr_join->tmp_table_param.copy_field_end; - curr_join->tmp_all_fields3= tmp_all_fields3; - curr_join->tmp_fields_list3= tmp_fields_list3; + if (curr_join != this) + { + curr_join->tmp_all_fields3= tmp_all_fields3; + curr_join->tmp_fields_list3= tmp_fields_list3; + } } else { @@ -10276,6 +10286,11 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, if (table->s->db_type != DB_TYPE_HEAP || error != HA_ERR_RECORD_FILE_FULL) { + /* + We don't want this error to be converted to a warning, e.g. in case of + INSERT IGNORE ... SELECT. + */ + thd->is_fatal_error= 1; table->file->print_error(error,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 75a905043d2..c328737c1c6 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -416,7 +416,8 @@ public: group_optimized_away= 0; all_fields= fields_arg; - fields_list= fields_arg; + if (&fields_list != &fields_arg) /* Avoid valgrind-warning */ + fields_list= fields_arg; bzero((char*) &keyuse,sizeof(keyuse)); tmp_table_param.init(); tmp_table_param.end_write_records= HA_POS_ERROR; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8387c087836..9eac750c22e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -287,7 +287,7 @@ find_files(THD *thd, List<char> *files, const char *db, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access=thd->col_access; #endif - uint wild_length= 0; + size_t wild_length= 0; TABLE_LIST table_list; DBUG_ENTER("find_files"); @@ -1410,16 +1410,14 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->start_time= tmp->start_time; #endif thd_info->query=0; + /* Lock THD mutex that protects its data when looking at it. */ + pthread_mutex_lock(&tmp->LOCK_thd_data); if (tmp->query) { - /* - query_length is always set to 0 when we set query = NULL; see - the comment in sql_class.h why this prevents crashes in possible - races with query_length - */ uint length= min(max_query_length, tmp->query_length); thd_info->query=(char*) thd->strmake(tmp->query,length); } + pthread_mutex_unlock(&tmp->LOCK_thd_data); thread_infos.append(thd_info); } } @@ -3738,7 +3736,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) if (item->decimals > 0) item->max_length+= 1; item->set_name(fields_info->field_name, - strlen(fields_info->field_name), cs); + (uint) strlen(fields_info->field_name), cs); break; case MYSQL_TYPE_STRING: default: diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 481fe30c6e7..f95f0a22a71 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -230,7 +230,7 @@ int mysql_update(THD *thd, if (select_lex->inner_refs_list.elements && fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) - DBUG_RETURN(-1); + DBUG_RETURN(1); if (conds) { @@ -247,7 +247,14 @@ int mysql_update(THD *thd, { delete select; free_underlaid_joins(thd, select_lex); - if (error) + /* + There was an error or the error was already sent by + the quick select evaluation. + TODO: Add error code output parameter to Item::val_xxx() methods. + Currently they rely on the user checking DA for + errors when unwinding the stack after calling Item::val_xxx(). + */ + if (error || thd->net.report_error) { DBUG_RETURN(1); // Error in where } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 49b7fafcc0b..b38b6e96890 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -41,11 +41,17 @@ #include <myisam.h> #include <myisammrg.h> +/* this is to get the bison compilation windows warnings out */ +#ifdef _MSC_VER +/* warning C4065: switch statement contains 'default' but no 'case' labels */ +#pragma warning (disable : 4065) +#endif + int yylex(void *yylval, void *yythd); const LEX_STRING null_lex_str={0,0}; -#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }} +#define yyoverflow(A,B,C,D,E,F) {ulong val= (ulong) *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }} #undef WARN_DEPRECATED /* this macro is also defined in mysql_priv.h */ #define WARN_DEPRECATED(A,B) \ @@ -2233,9 +2239,9 @@ sp_proc_stmt: lex->tok_end otherwise. */ if (yychar == YYEMPTY) - i->m_query.length= lip->ptr - sp->m_tmp_query; + i->m_query.length= (uint) (lip->ptr - sp->m_tmp_query); else - i->m_query.length= lip->tok_end - sp->m_tmp_query; + i->m_query.length= (uint) (lip->tok_end - sp->m_tmp_query); if (!(i->m_query.str= strmake_root(thd->mem_root, sp->m_tmp_query, i->m_query.length)) || @@ -9021,9 +9027,10 @@ simple_ident: Item_splocal *splocal; splocal= new Item_splocal($1, spv->offset, spv->type, - lip->tok_start_prev - - lex->sphead->m_tmp_query, - lip->tok_end - lip->tok_start_prev); + (uint) (lip->tok_start_prev - + lex->sphead->m_tmp_query), + (uint) (lip->tok_end - + lip->tok_start_prev)); if (splocal == NULL) MYSQL_YYABORT; #ifndef DBUG_OFF @@ -9737,9 +9744,9 @@ option_type_value: lip->tok_end otherwise. */ if (yychar == YYEMPTY) - qbuff.length= lip->ptr - sp->m_tmp_query; + qbuff.length= (uint) (lip->ptr - sp->m_tmp_query); else - qbuff.length= lip->tok_end - sp->m_tmp_query; + qbuff.length= (uint) (lip->tok_end - sp->m_tmp_query); if (!(qbuff.str= alloc_root(thd->mem_root, qbuff.length + 5))) MYSQL_YYABORT; @@ -11059,7 +11066,7 @@ view_select_aux: char *stmt_beg= (lex->sphead ? (char *)lex->sphead->m_tmp_query : thd->query); - lex->create_view_select_start= $2 - stmt_beg; + lex->create_view_select_start= (uint) ($2 - stmt_beg); } | '(' remember_name select_paren ')' union_opt { @@ -11068,7 +11075,7 @@ view_select_aux: char *stmt_beg= (lex->sphead ? (char *)lex->sphead->m_tmp_query : thd->query); - lex->create_view_select_start= $2 - stmt_beg; + lex->create_view_select_start= (uint) ($2 - stmt_beg); } ; @@ -11113,7 +11120,7 @@ trigger_tail: lex->stmt_definition_begin= $2; lex->ident.str= $7; - lex->ident.length= $10 - $7; + lex->ident.length= (uint) ($10 - $7); lex->sphead= sp; lex->spname= $3; diff --git a/sql/unireg.h b/sql/unireg.h index 8e01e6222e6..781b9b980e2 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -29,8 +29,8 @@ #define TEMP_PREFIX "MY" #define LOG_PREFIX "ML" #define PROGDIR "bin/" -#ifndef DATADIR -#define DATADIR "data/" +#ifndef MYSQL_DATADIR +#define MYSQL_DATADIR "data/" #endif #ifndef SHAREDIR #define SHAREDIR "share/" diff --git a/strings/strmake.c b/strings/strmake.c index 05b5878d99c..acc220bbf1c 100644 --- a/strings/strmake.c +++ b/strings/strmake.c @@ -41,9 +41,9 @@ char *strmake(register char *dst, register const char *src, uint length) write a character rather than '\0' as this makes spotting these problems in the results easier. */ - uint n= strlen(src) + 1; - if (n <= length) - memset(dst + n, (int) 'Z', length - n + 1); + uint n= 0; + while (n < length && src[n++]); + memset(dst + n, (int) 'Z', length - n + 1); #endif while (length--) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ce1a1a99b04..040ef4d050d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16248,14 +16248,14 @@ static void test_bug38486(void) stmt= mysql_stmt_init(mysql); mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type); stmt_text= "CREATE TABLE t1 (a INT)"; - mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + mysql_stmt_prepare(stmt, stmt_text, (ulong) strlen(stmt_text)); mysql_stmt_execute(stmt); mysql_stmt_close(stmt); stmt= mysql_stmt_init(mysql); mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type); stmt_text= "INSERT INTO t1 VALUES (1)"; - mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + mysql_stmt_prepare(stmt, stmt_text, (ulong) strlen(stmt_text)); mysql_stmt_execute(stmt); mysql_stmt_close(stmt); @@ -16270,33 +16270,46 @@ static void bug20023_change_user(MYSQL *con) opt_db ? opt_db : "test")); } -static void bug20023_query_int_variable(MYSQL *con, +static void bug20023_query_str_variable(MYSQL *con, const char *var_name, - int *var_value) + char *str, + size_t len) { MYSQL_RES *rs; MYSQL_ROW row; char query_buffer[MAX_TEST_QUERY_LENGTH]; - my_snprintf(query_buffer, - sizeof (query_buffer), - "SELECT @@%s", - (const char *) var_name); + my_snprintf(query_buffer, sizeof (query_buffer), + "SELECT @@%s", var_name); DIE_IF(mysql_query(con, query_buffer)); DIE_UNLESS(rs= mysql_store_result(con)); DIE_UNLESS(row= mysql_fetch_row(rs)); - *var_value= atoi(row[0]); + my_snprintf(str, len, "%s", row[0]); mysql_free_result(rs); } +static void bug20023_query_int_variable(MYSQL *con, + const char *var_name, + int *var_value) +{ + char str[32]; + bug20023_query_str_variable(con, var_name, str, sizeof(str)); + *var_value= atoi(str); +} + static void test_bug20023() { MYSQL con; int sql_big_selects_orig; - int max_join_size_orig; + /* + Type of max_join_size is ha_rows, which might be ulong or off_t + depending on the platform or configure options. Preserve the string + to avoid type overflow pitfalls. + */ + char max_join_size_orig[32]; int sql_big_selects_2; int sql_big_selects_3; @@ -16326,9 +16339,10 @@ static void test_bug20023() "session.sql_big_selects", &sql_big_selects_orig); - bug20023_query_int_variable(&con, + bug20023_query_str_variable(&con, "global.max_join_size", - &max_join_size_orig); + max_join_size_orig, + sizeof(max_join_size_orig)); /*********************************************************************** Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value. @@ -16405,8 +16419,8 @@ static void test_bug20023() my_snprintf(query_buffer, sizeof (query_buffer), - "SET @@global.max_join_size = %d", - (int) max_join_size_orig); + "SET @@global.max_join_size = %s", + max_join_size_orig); DIE_IF(mysql_query(&con, query_buffer)); DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default")); diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 4e3092b3b39..921fc111dc5 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -73,9 +73,28 @@ report_errors() DBUG_VOID_RETURN; } +static const char* +ssl_error_string[] = +{ + "No error", + "Unable to get certificate", + "Unable to get private key", + "Private key does not match the certificate public key" + "SSL_CTX_set_default_verify_paths failed", + "Failed to set ciphers to use", + "SSL_CTX_new failed" +}; + +const char* +sslGetErrString(enum enum_ssl_init_error e) +{ + DBUG_ASSERT(SSL_INITERR_NOERROR < e && e < SSL_INITERR_LASTERR); + return ssl_error_string[e]; +} static int -vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) +vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file, + enum enum_ssl_init_error* error) { DBUG_ENTER("vio_set_cert_stuff"); DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s", @@ -84,9 +103,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) { if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) { - DBUG_PRINT("error",("unable to get certificate from '%s'", cert_file)); + *error= SSL_INITERR_CERT; + DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file)); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, "SSL error: Unable to get certificate from '%s'\n", + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), cert_file); fflush(stderr); DBUG_RETURN(1); @@ -97,9 +117,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { - DBUG_PRINT("error", ("unable to get private key from '%s'", key_file)); + *error= SSL_INITERR_KEY; + DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file)); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, "SSL error: Unable to get private key from '%s'\n", + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), key_file); fflush(stderr); DBUG_RETURN(1); @@ -111,12 +132,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) */ if (!SSL_CTX_check_private_key(ctx)) { - DBUG_PRINT("error", - ("Private key does not match the certificate public key")); + *error= SSL_INITERR_NOMATCH; + DBUG_PRINT("error", ("%s",sslGetErrString(*error))); DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, - "SSL error: " - "Private key does not match the certificate public key\n"); + fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error)); fflush(stderr); DBUG_RETURN(1); } @@ -229,7 +248,8 @@ static void check_ssl_init() static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher, SSL_METHOD *method) + const char *cipher, SSL_METHOD *method, + enum enum_ssl_init_error* error) { DH *dh; struct st_VioSSLFd *ssl_fd; @@ -243,7 +263,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, if (!(ssl_fd->ssl_context= SSL_CTX_new(method))) { - DBUG_PRINT("error", ("SSL_CTX_new failed")); + *error= SSL_INITERR_MEMFAIL; + DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); my_free((void*)ssl_fd,MYF(0)); DBUG_RETURN(0); @@ -257,7 +278,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, if (cipher && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher) == 0) { - DBUG_PRINT("error", ("failed to set ciphers to use")); + *error= SSL_INITERR_CIPHERS; + DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); @@ -270,7 +292,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file, DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0) { - DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); + *error= SSL_INITERR_BAD_PATHS; + DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); my_free((void*)ssl_fd,MYF(0)); @@ -278,7 +301,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, } } - if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file)) + if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file, error)) { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); @@ -306,6 +329,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + enum enum_ssl_init_error dummy; /* Turn off verification of servers certificate if both @@ -315,7 +339,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, verify= SSL_VERIFY_NONE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, TLSv1_client_method()))) + ca_path, cipher, TLSv1_client_method(), &dummy))) { return 0; } @@ -336,12 +360,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd* new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher) + const char *cipher, enum enum_ssl_init_error* error) { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, TLSv1_server_method()))) + ca_path, cipher, TLSv1_server_method(), error))) { return 0; } |