summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2009-08-04 10:53:15 -0300
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2009-08-04 10:53:15 -0300
commit49d88efc078f384605edc7fb999e7678d6aa51e0 (patch)
tree0e16d7008f0346b0a3a87d68e81cfed416c2cbb4
parent52c95d0ccfef7f897bd79ee4b48da5ec752c70c2 (diff)
parent77acccc21fd4e95811757d95788d711fff45c586 (diff)
downloadmariadb-git-49d88efc078f384605edc7fb999e7678d6aa51e0.tar.gz
Merge from mysql-5.0-bugteam.
-rwxr-xr-xCMakeLists.txt12
-rw-r--r--client/Makefile.am2
-rw-r--r--client/mysql_upgrade.c2
-rw-r--r--client/mysqldump.c4
-rw-r--r--dbug/dbug.c13
-rw-r--r--extra/perror.c1
-rw-r--r--include/config-netware.h2
-rw-r--r--include/config-win.h13
-rw-r--r--include/my_base.h3
-rw-r--r--include/my_sys.h2
-rw-r--r--include/violite.h10
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--libmysqld/Makefile.am2
-rw-r--r--mysql-test/include/rpl_trigger_common.inc (renamed from mysql-test/t/rpl_trigger.test)93
-rw-r--r--mysql-test/r/bug40113.result29
-rw-r--r--mysql-test/r/fulltext.result8
-rw-r--r--mysql-test/r/group_min_max.result6
-rw-r--r--mysql-test/r/innodb-autoinc-optimize.result2
-rw-r--r--mysql-test/r/insert_select.result13
-rw-r--r--mysql-test/r/rpl_trigger_not_windows.result (renamed from mysql-test/r/rpl_trigger.result)0
-rw-r--r--mysql-test/r/rpl_trigger_windows.result932
-rw-r--r--mysql-test/r/subselect.result22
-rw-r--r--mysql-test/t/bug40113-master.opt1
-rw-r--r--mysql-test/t/bug40113.test46
-rw-r--r--mysql-test/t/fulltext.test15
-rw-r--r--mysql-test/t/group_min_max.test2
-rw-r--r--mysql-test/t/innodb-autoinc-optimize.test3
-rw-r--r--mysql-test/t/innodb_notembedded.test11
-rw-r--r--mysql-test/t/insert_select.test21
-rw-r--r--mysql-test/t/rpl_trigger_not_windows.test8
-rw-r--r--mysql-test/t/rpl_trigger_windows.test8
-rw-r--r--mysql-test/t/subselect.test22
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/array.c13
-rw-r--r--ndb/src/mgmsrv/Makefile.am2
-rw-r--r--sql/Makefile.am2
-rw-r--r--sql/ha_innodb.cc12
-rw-r--r--sql/ha_myisam.cc11
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_subselect.cc4
-rw-r--r--sql/log_event.cc16
-rw-r--r--sql/mysqld.cc15
-rw-r--r--sql/net_serv.cc13
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/slave.cc20
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sp_head.cc6
-rw-r--r--sql/sql_acl.cc8
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_class.cc31
-rw-r--r--sql/sql_class.h52
-rw-r--r--sql/sql_delete.cc10
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_parse.cc51
-rw-r--r--sql/sql_profile.cc2
-rw-r--r--sql/sql_repl.cc4
-rw-r--r--sql/sql_select.cc29
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/sql_yacc.yy29
-rw-r--r--sql/unireg.h4
-rw-r--r--strings/strmake.c6
-rw-r--r--tests/mysql_client_test.c42
-rw-r--r--vio/viosslfactories.c60
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;
}