summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Elkin <aelkin@mysql.com>2009-11-30 14:34:39 +0200
committerAndrei Elkin <aelkin@mysql.com>2009-11-30 14:34:39 +0200
commit3962da934f6e2a92ba04505bd6a33dd7d8322005 (patch)
treec5510a774ac5e8722c26070e21e3d266d6408381
parent13dad4ebd268e4bf26c4d6f478f19896770d9b78 (diff)
parenta95f54c6d81f20b07e41a7e0e2246ee00641df6c (diff)
downloadmariadb-git-3962da934f6e2a92ba04505bd6a33dd7d8322005.tar.gz
merging from 5.1 to rep+2 starting at gca(5.1, next-mr) == build@mysql.com-20091104182209-iui387z35159aoyw
-rw-r--r--Makefile.am6
-rw-r--r--client/mysql.cc26
-rw-r--r--client/mysqlbinlog.cc28
-rw-r--r--client/mysqltest.cc109
-rw-r--r--configure.in2
-rw-r--r--extra/yassl/taocrypt/src/random.cpp1
-rw-r--r--include/myisam.h4
-rw-r--r--include/mysql.h10
-rw-r--r--include/mysql.h.pp10
-rw-r--r--include/violite.h8
-rw-r--r--libmysql/libmysql.c14
-rw-r--r--libmysql/libmysql.def1
-rw-r--r--libmysqld/libmysqld.def1
-rw-r--r--mysql-test/collections/default.experimental1
-rw-r--r--mysql-test/extra/binlog_tests/drop_temp_table.test10
-rw-r--r--mysql-test/extra/rpl_tests/rpl_loaddata.test61
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_000001.test2
-rw-r--r--mysql-test/include/have_case_insensitive_fs.inc4
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm20
-rwxr-xr-xmysql-test/lib/My/SafeProcess/safe_process_win.cc3
-rw-r--r--mysql-test/lib/mtr_cases.pm4
-rw-r--r--mysql-test/r/alter_table.result8
-rw-r--r--mysql-test/r/analyse.result112
-rw-r--r--mysql-test/r/bug40113.result29
-rw-r--r--mysql-test/r/case_insensitive_fs.require2
-rw-r--r--mysql-test/r/ctype_ldml.result8
-rw-r--r--mysql-test/r/explain.result16
-rw-r--r--mysql-test/r/gis-rtree.result39
-rw-r--r--mysql-test/r/gis.result12
-rw-r--r--mysql-test/r/grant.result4
-rw-r--r--mysql-test/r/grant3.result38
-rw-r--r--mysql-test/r/grant_lowercase_fs.result16
-rw-r--r--mysql-test/r/innodb-autoinc.result237
-rw-r--r--mysql-test/r/innodb_bug44369.result8
-rw-r--r--mysql-test/r/innodb_bug46000.result8
-rw-r--r--mysql-test/r/innodb_bug47777.result13
-rw-r--r--mysql-test/r/innodb_lock_wait_timeout_1.result357
-rw-r--r--mysql-test/r/innodb_mysql.result42
-rw-r--r--mysql-test/r/join.result54
-rw-r--r--mysql-test/r/locale.result29
-rw-r--r--mysql-test/r/lowercase_fs_off.result45
-rw-r--r--mysql-test/r/myisam.result6
-rw-r--r--mysql-test/r/myisam_crash_before_flush_keys.result28
-rw-r--r--mysql-test/r/olap.result20
-rw-r--r--mysql-test/r/partition_pruning.result3
-rw-r--r--mysql-test/r/ps_grant.result6
-rw-r--r--mysql-test/r/query_cache.result2
-rw-r--r--mysql-test/r/range.result206
-rw-r--r--mysql-test/r/select.result41
-rw-r--r--mysql-test/r/sp-bugs.result47
-rw-r--r--mysql-test/r/sp-error.result16
-rw-r--r--mysql-test/r/subselect.result19
-rw-r--r--mysql-test/r/subselect3.result69
-rw-r--r--mysql-test/r/system_mysql_db.result2
-rw-r--r--mysql-test/r/type_newdecimal.result220
-rw-r--r--mysql-test/r/update.result11
-rw-r--r--mysql-test/r/view_grant.result19
-rw-r--r--mysql-test/r/xa.result25
-rw-r--r--mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result50
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_do_db.result42
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result1
-rw-r--r--mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test114
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_do_db.test90
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-zip.result98
-rw-r--r--mysql-test/suite/innodb/t/disabled.def1
-rw-r--r--mysql-test/suite/innodb/t/innodb-zip.test46
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema.test16
-rw-r--r--mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddata.result29
-rw-r--r--mysql-test/suite/rpl/t/rpl_err_ignoredtable.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test4
-rw-r--r--mysql-test/t/alter_table.test15
-rw-r--r--mysql-test/t/analyse.test70
-rw-r--r--mysql-test/t/bug40113.test46
-rw-r--r--mysql-test/t/ctype_ldml.test8
-rw-r--r--mysql-test/t/disabled.def3
-rw-r--r--mysql-test/t/explain.test20
-rw-r--r--mysql-test/t/flush_read_lock_kill.test2
-rw-r--r--mysql-test/t/gis-rtree.test21
-rw-r--r--mysql-test/t/gis.test16
-rw-r--r--mysql-test/t/grant3.test35
-rw-r--r--mysql-test/t/grant_lowercase_fs.test30
-rw-r--r--mysql-test/t/innodb-autoinc.test122
-rw-r--r--mysql-test/t/innodb_bug34300.test1
-rw-r--r--mysql-test/t/innodb_bug39438.test4
-rw-r--r--mysql-test/t/innodb_bug44369.test4
-rw-r--r--mysql-test/t/innodb_bug46000.test4
-rw-r--r--mysql-test/t/innodb_bug47777.test24
-rw-r--r--mysql-test/t/innodb_lock_wait_timeout_1-master.opt (renamed from mysql-test/t/bug40113-master.opt)0
-rw-r--r--mysql-test/t/innodb_lock_wait_timeout_1.test230
-rw-r--r--mysql-test/t/innodb_mysql.test29
-rw-r--r--mysql-test/t/join.test54
-rw-r--r--mysql-test/t/kill.test2
-rw-r--r--mysql-test/t/locale.test18
-rw-r--r--mysql-test/t/lowercase_fs_off.test62
-rw-r--r--mysql-test/t/myisam.test12
-rw-r--r--mysql-test/t/myisam_crash_before_flush_keys.test12
-rw-r--r--mysql-test/t/named_pipe.test5
-rw-r--r--mysql-test/t/olap.test15
-rw-r--r--mysql-test/t/query_cache.test3
-rw-r--r--mysql-test/t/range.test90
-rw-r--r--mysql-test/t/select.test33
-rw-r--r--mysql-test/t/sp-bugs.test61
-rw-r--r--mysql-test/t/sp-error.test24
-rw-r--r--mysql-test/t/subselect.test17
-rw-r--r--mysql-test/t/subselect3.test66
-rw-r--r--mysql-test/t/type_newdecimal.test134
-rw-r--r--mysql-test/t/update.test15
-rw-r--r--mysql-test/t/view_grant.test26
-rw-r--r--mysql-test/t/xa.test62
-rw-r--r--mysys/my_getopt.c4
-rw-r--r--mysys/typelib.c5
-rw-r--r--scripts/mysql_system_tables.sql2
-rw-r--r--scripts/mysql_system_tables_fix.sql4
-rw-r--r--sql-common/client.c6
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/events.cc10
-rw-r--r--sql/field.cc122
-rw-r--r--sql/field.h31
-rw-r--r--sql/ha_ndbcluster.cc13
-rw-r--r--sql/ha_ndbcluster_binlog.cc8
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item.cc88
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_cmpfunc.cc202
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.cc52
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_geofunc.cc9
-rw-r--r--sql/item_subselect.cc12
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/log.cc13
-rw-r--r--sql/log_event.cc16
-rw-r--r--sql/log_event_old.cc2
-rw-r--r--sql/my_decimal.h14
-rw-r--r--sql/mysqld.cc30
-rw-r--r--sql/opt_range.cc38
-rw-r--r--sql/records.cc23
-rw-r--r--sql/slave.cc193
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_head.cc40
-rw-r--r--sql/sql_acl.cc91
-rw-r--r--sql/sql_base.cc13
-rw-r--r--sql/sql_cache.cc15
-rw-r--r--sql/sql_class.cc65
-rw-r--r--sql/sql_class.h13
-rw-r--r--sql/sql_db.cc18
-rw-r--r--sql/sql_delete.cc8
-rw-r--r--sql/sql_insert.cc17
-rw-r--r--sql/sql_load.cc39
-rw-r--r--sql/sql_locale.cc4
-rw-r--r--sql/sql_parse.cc47
-rw-r--r--sql/sql_partition.cc8
-rw-r--r--sql/sql_plugin.cc6
-rw-r--r--sql/sql_prepare.cc28
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_select.cc223
-rw-r--r--sql/sql_select.h8
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_table.cc20
-rw-r--r--sql/sql_tablespace.cc2
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_udf.cc4
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy5
-rw-r--r--sql/structs.h14
-rw-r--r--sql/time.cc16
-rw-r--r--storage/blackhole/ha_blackhole.cc12
-rw-r--r--storage/innobase/handler/ha_innodb.cc59
-rw-r--r--storage/innobase/handler/ha_innodb.h7
-rw-r--r--storage/innobase/os/os0proc.c1
-rw-r--r--storage/innobase/row/row0mysql.c2
-rw-r--r--storage/innodb_plugin/ChangeLog90
-rw-r--r--storage/innodb_plugin/buf/buf0buf.c5
-rw-r--r--storage/innodb_plugin/buf/buf0flu.c42
-rw-r--r--storage/innodb_plugin/buf/buf0lru.c69
-rw-r--r--storage/innodb_plugin/fil/fil0fil.c3
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc116
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.h25
-rw-r--r--storage/innodb_plugin/handler/handler0alter.cc12
-rw-r--r--storage/innodb_plugin/include/buf0buf.h5
-rw-r--r--storage/innodb_plugin/include/buf0buf.ic17
-rw-r--r--storage/innodb_plugin/include/page0page.ic2
-rw-r--r--storage/innodb_plugin/include/row0mysql.h2
-rw-r--r--storage/innodb_plugin/include/univ.i2
-rw-r--r--storage/innodb_plugin/os/os0file.c17
-rw-r--r--storage/innodb_plugin/os/os0proc.c1
-rw-r--r--storage/innodb_plugin/row/row0ins.c6
-rw-r--r--storage/innodb_plugin/row/row0mysql.c2
-rw-r--r--storage/innodb_plugin/srv/srv0start.c2
-rw-r--r--storage/myisam/ha_myisam.cc12
-rw-r--r--storage/myisam/mi_check.c7
-rw-r--r--storage/myisam/sort.c7
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp2
-rw-r--r--strings/ctype-uca.c3
-rw-r--r--tests/mysql_client_test.c94
-rw-r--r--vio/vio.c27
-rw-r--r--vio/vio_priv.h5
-rw-r--r--vio/viosocket.c120
-rw-r--r--vio/viosslfactories.c61
207 files changed, 4973 insertions, 1564 deletions
diff --git a/Makefile.am b/Makefile.am
index e71520bf887..49ab3103c25 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -196,6 +196,10 @@ test-bt-fast:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=stress --suite=stress
+test-bt-fast:
+ -cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl --force --comment=ps --ps-protocol --report-features
+
test-bt-debug:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=debug --force --timer \
@@ -203,6 +207,8 @@ test-bt-debug:
test-bt-debug-fast:
+test-bt-debug-fast:
+
# Keep these for a while
test-pl: test
test-full-pl: test-full
diff --git a/client/mysql.cc b/client/mysql.cc
index d46f18332ab..b76a3d624ab 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1280,21 +1280,35 @@ sig_handler handle_sigint(int sig)
MYSQL *kill_mysql= NULL;
/* terminate if no query being executed, or we already tried interrupting */
- if (!executing_query || interrupted_query)
+ /* terminate if no query being executed, or we already tried interrupting */
+ if (!executing_query || (interrupted_query == 2))
+ {
+ tee_fprintf(stdout, "Ctrl-C -- exit!\n");
goto err;
+ }
kill_mysql= mysql_init(kill_mysql);
if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
"", opt_mysql_port, opt_mysql_unix_port,0))
+ {
+ tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n");
goto err;
+ }
+
+ interrupted_query++;
+
+ /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */
+ if ((interrupted_query == 1) && (mysql_get_server_version(&mysql) < 50000))
+ interrupted_query= 2;
/* kill_buffer is always big enough because max length of %lu is 15 */
- sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
- mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
+ sprintf(kill_buffer, "KILL %s%lu",
+ (interrupted_query == 1) ? "QUERY " : "",
+ mysql_thread_id(&mysql));
+ tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer);
+ mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer));
mysql_close(kill_mysql);
- tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
-
- interrupted_query= 1;
+ tee_fprintf(stdout, "Ctrl-C -- query aborted.\n");
return;
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 894a3ac9146..cf56713ec0d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -78,6 +78,9 @@ static const char* host = 0;
static int port= 0;
static uint my_end_arg;
static const char* sock= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static const char* user = 0;
static char* pass = 0;
static char *charset= 0;
@@ -1009,13 +1012,13 @@ static struct my_option my_long_options[] =
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
"statements: 'never' disables it and works only for binlogs without "
- "row-based events; 'auto' is the default and prints base64 only when "
- "necessary (i.e., for row-based events and format description events); "
- "'decode-rows' suppresses BINLOG statements for row events, but does "
- "not exit as an error if a row event is found, unlike 'never'; "
- "'always' prints base64 whenever possible. 'always' is for debugging "
- "only and should not be used in a production system. The default is "
- "'auto'. --base64-output is a short form for --base64-output=always."
+ "row-based events; 'decode-rows' decodes row events into commented SQL "
+ "statements if the --verbose option is also given; 'auto' prints base64 "
+ "only when necessary (i.e., for row-based events and format description "
+ "events); 'always' prints base64 whenever possible. 'always' is for "
+ "debugging only and should not be used in a production system. If this "
+ "argument is not given, the default is 'auto'; if it is given with no "
+ "argument, 'always' is used."
,(uchar**) &opt_base64_output_mode_str,
(uchar**) &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1094,6 +1097,12 @@ static struct my_option my_long_options[] =
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES character_set' to the output.", (uchar**) &charset,
(uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"short-form", 's', "Just show regular queries: no extra info and no "
"row-based events. This is for testing only, and should not be used in "
"production systems. If you want to suppress base64-output, consider "
@@ -1395,6 +1404,11 @@ static Exit_status safe_connect()
if (opt_protocol)
mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+ shared_memory_base_name);
+#endif
if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 8de2f0c79b0..cb1d21ebe8a 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -81,6 +81,9 @@ enum {
static int record= 0, opt_sleep= -1;
static char *opt_db= 0, *opt_pass= 0;
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
@@ -4896,6 +4899,8 @@ do_handle_error:
<opts> - options to use for the connection
* SSL - use SSL if available
* COMPRESS - use compression if available
+ * SHM - use shared memory if available
+ * PIPE - use named pipe if available
*/
@@ -4904,6 +4909,7 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
+ my_bool con_pipe= 0, con_shm= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
@@ -4914,6 +4920,9 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_port;
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
+#ifdef HAVE_SMEM
+ static DYNAMIC_STRING ds_shm;
+#endif
const struct command_arg connect_args[] = {
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
@@ -4941,6 +4950,11 @@ void do_connect(struct st_command *command)
die("Illegal argument for port: '%s'", ds_port.str);
}
+#ifdef HAVE_SMEM
+ /* Shared memory */
+ init_dynamic_string(&ds_shm, ds_sock.str, 0, 0);
+#endif
+
/* Sock */
if (ds_sock.length)
{
@@ -4979,6 +4993,10 @@ void do_connect(struct st_command *command)
con_ssl= 1;
else if (!strncmp(con_options, "COMPRESS", 8))
con_compress= 1;
+ else if (!strncmp(con_options, "PIPE", 4))
+ con_pipe= 1;
+ else if (!strncmp(con_options, "SHM", 3))
+ con_shm= 1;
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
@@ -5026,6 +5044,31 @@ void do_connect(struct st_command *command)
}
#endif
+#ifdef __WIN__
+ if (con_pipe)
+ {
+ uint protocol= MYSQL_PROTOCOL_PIPE;
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+#endif
+
+#ifdef HAVE_SMEM
+ if (con_shm)
+ {
+ uint protocol= MYSQL_PROTOCOL_MEMORY;
+ if (!ds_shm.length)
+ die("Missing shared memory base name");
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+ else if(shared_memory_base_name)
+ {
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+ shared_memory_base_name);
+ }
+#endif
+
+
/* Use default db name */
if (ds_database.length == 0)
dynstr_set(&ds_database, opt_db);
@@ -5058,6 +5101,9 @@ void do_connect(struct st_command *command)
dynstr_free(&ds_port);
dynstr_free(&ds_sock);
dynstr_free(&ds_options);
+#ifdef HAVE_SMEM
+ dynstr_free(&ds_shm);
+#endif
DBUG_VOID_RETURN;
}
@@ -5724,6 +5770,12 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+#endif
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
@@ -6913,35 +6965,39 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
Need to grab affected rows information before getting
warnings here
*/
- if (!disable_info)
- affected_rows= mysql_affected_rows(mysql);
-
- if (!disable_warnings)
{
- /* Get the warnings from execute */
+ ulonglong affected_rows;
+ LINT_INIT(affected_rows);
+
+ if (!disable_info)
+ affected_rows= mysql_affected_rows(mysql);
- /* Append warnings to ds - if there are any */
- if (append_warnings(&ds_execute_warnings, mysql) ||
- ds_execute_warnings.length ||
- ds_prepare_warnings.length ||
- ds_warnings->length)
+ if (!disable_warnings)
{
- dynstr_append_mem(ds, "Warnings:\n", 10);
- if (ds_warnings->length)
- dynstr_append_mem(ds, ds_warnings->str,
- ds_warnings->length);
- if (ds_prepare_warnings.length)
- dynstr_append_mem(ds, ds_prepare_warnings.str,
- ds_prepare_warnings.length);
- if (ds_execute_warnings.length)
- dynstr_append_mem(ds, ds_execute_warnings.str,
- ds_execute_warnings.length);
- }
- }
+ /* Get the warnings from execute */
- if (!disable_info)
- append_info(ds, affected_rows, mysql_info(mysql));
+ /* Append warnings to ds - if there are any */
+ if (append_warnings(&ds_execute_warnings, mysql) ||
+ ds_execute_warnings.length ||
+ ds_prepare_warnings.length ||
+ ds_warnings->length)
+ {
+ dynstr_append_mem(ds, "Warnings:\n", 10);
+ if (ds_warnings->length)
+ dynstr_append_mem(ds, ds_warnings->str,
+ ds_warnings->length);
+ if (ds_prepare_warnings.length)
+ dynstr_append_mem(ds, ds_prepare_warnings.str,
+ ds_prepare_warnings.length);
+ if (ds_execute_warnings.length)
+ dynstr_append_mem(ds, ds_execute_warnings.str,
+ ds_execute_warnings.length);
+ }
+ }
+ if (!disable_info)
+ append_info(ds, affected_rows, mysql_info(mysql));
+ }
}
end:
@@ -7673,6 +7729,11 @@ int main(int argc, char **argv)
}
#endif
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+
if (!(con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
diff --git a/configure.in b/configure.in
index d479088356b..fb5517659ba 100644
--- a/configure.in
+++ b/configure.in
@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
#
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
-AM_INIT_AUTOMAKE(mysql, 5.1.41)
+AM_INIT_AUTOMAKE(mysql, 5.1.42)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp
index 89fd5f7c7bc..2bbc0a85e8b 100644
--- a/extra/yassl/taocrypt/src/random.cpp
+++ b/extra/yassl/taocrypt/src/random.cpp
@@ -27,7 +27,6 @@
#include <time.h>
#if defined(_WIN32)
- #define _WIN32_WINNT 0x0400
#include <windows.h>
#include <wincrypt.h>
#else
diff --git a/include/myisam.h b/include/myisam.h
index 02251eeacb4..19b35538c65 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -432,6 +432,10 @@ typedef struct st_mi_check_param
const char *db_name, *table_name;
const char *op_name;
enum_mi_stats_method stats_method;
+#ifdef THREAD
+ pthread_mutex_t print_msg_mutex;
+ my_bool need_print_msg_lock;
+#endif
} MI_CHECK;
typedef struct st_sort_ft_buf
diff --git a/include/mysql.h b/include/mysql.h
index d114afb6c93..68cce3196a0 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -557,6 +557,16 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void STDCALL mysql_debug(const char *debug);
+char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void);
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 633cde41130..bd4c79916dd 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -518,6 +518,16 @@ unsigned long mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void mysql_debug(const char *debug);
+char * mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);
diff --git a/include/violite.h b/include/violite.h
index f833606233c..3f68ccde10f 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -44,7 +44,7 @@ enum enum_vio_type
Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
-Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
+Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
HANDLE handle_map,
HANDLE event_server_wrote,
HANDLE event_server_read,
@@ -221,7 +221,11 @@ struct st_vio
HANDLE event_conn_closed;
size_t shared_memory_remain;
char *shared_memory_pos;
- NET *net;
#endif /* HAVE_SMEM */
+#ifdef _WIN32
+ OVERLAPPED pipe_overlapped;
+ DWORD read_timeout_millis;
+ DWORD write_timeout_millis;
+#endif
};
#endif /* vio_violite_h_ */
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 1264f2765ba..77ff2a01d7c 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1629,6 +1629,20 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}
+
+char * STDCALL
+mysql_odbc_escape_string(MYSQL *mysql __attribute__((unused)),
+ char *to __attribute__((unused)),
+ ulong to_length __attribute__((unused)),
+ const char *from __attribute__((unused)),
+ ulong from_length __attribute__((unused)),
+ void *param __attribute__((unused)),
+ char * (*extend_buffer)(void *, char *, ulong *)
+ __attribute__((unused)))
+{
+ return NULL;
+}
+
void STDCALL
myodbc_remove_escape(MYSQL *mysql,char *name)
{
diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def
index 81f86dc8726..8c6b71d9553 100644
--- a/libmysql/libmysql.def
+++ b/libmysql/libmysql.def
@@ -78,6 +78,7 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
+ mysql_odbc_escape_string
mysql_options
mysql_stmt_param_count
mysql_stmt_param_metadata
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
index 047cfe0fe57..e0f02003963 100644
--- a/libmysqld/libmysqld.def
+++ b/libmysqld/libmysqld.def
@@ -50,6 +50,7 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
+ mysql_odbc_escape_string
mysql_options
mysql_ping
mysql_query
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index f3163d8e84d..b4e934735a6 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -18,6 +18,7 @@ main.plugin_load @solaris # Bug#42144
ndb.* # joro : NDB tests marked as experimental as agreed with bochklin
+rpl.rpl_cross_version* # Bug #43913 2009-10-26 joro rpl_cross_version can't pass on conflicts complainig clash with --slave-load-tm
rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31
rpl.rpl_innodb_bug28430* @solaris # Bug#46029
rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2
diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test
index 5616fb4a643..63833c10c14 100644
--- a/mysql-test/extra/binlog_tests/drop_temp_table.test
+++ b/mysql-test/extra/binlog_tests/drop_temp_table.test
@@ -48,6 +48,16 @@ DROP TABLE IF EXISTS tmp2, t;
--enable_warnings
SELECT GET_LOCK("a",10);
+
+#
+# BUG48216 Replication fails on all slaves after upgrade to 5.0.86 on master
+#
+# When the session is closed, any temporary tables of the session are dropped
+# and are binlogged. But it will be binlogged with a wrong database name when
+# the length of the database name('drop-temp-table-test') is greater than the
+# current database name('test').
+#
+USE test;
disconnect con1;
connection con2;
diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test
index 129a39ac509..e159242ed10 100644
--- a/mysql-test/extra/rpl_tests/rpl_loaddata.test
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test
@@ -158,4 +158,65 @@ LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
DROP TABLE IF EXISTS t1;
+# BUG#48297: Schema name is ignored when LOAD DATA is written into binlog,
+# replication aborts
+-- source include/master-slave-reset.inc
+
+-- let $db1= b48297_db1
+-- let $db2= b42897_db2
+
+-- connection master
+
+-- disable_warnings
+-- eval drop database if exists $db1
+-- eval drop database if exists $db2
+-- enable_warnings
+
+-- eval create database $db1
+-- eval create database $db2
+
+-- eval use $db1
+-- eval CREATE TABLE t1 (c1 VARCHAR(256)) engine=$engine_type;
+
+-- eval use $db2
+
+-- echo ### assertion: works with cross-referenced database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+
+-- eval use $db1
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- echo ### assertion: works with fully qualified name on current database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+
+-- echo ### assertion: works without fully qualified name on current database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1
+
+-- echo ### create connection without default database
+-- echo ### connect (conn2,localhost,root,,*NO-ONE*);
+connect (conn2,localhost,root,,*NO-ONE*);
+-- connection conn2
+-- echo ### assertion: works without stating the default database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+-- echo ### disconnect and switch back to master connection
+-- disconnect conn2
+-- connection master
+
+-- sync_slave_with_master
+-- eval use $db1
+
+let $diff_table_1=master:$db1.t1;
+let $diff_table_2=slave:$db1.t1;
+source include/diff_tables.inc;
+
+-- connection master
+
+-- eval DROP DATABASE $db1
+-- eval DROP DATABASE $db2
+
+-- sync_slave_with_master
+
# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_stm_000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
index 61d443158d0..323d626c95f 100644
--- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
@@ -93,7 +93,7 @@ kill @id;
# We don't drop t3 as this is a temporary table
drop table t2;
connection master;
---error 1053,2013
+--error 1317,2013
reap;
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
diff --git a/mysql-test/include/have_case_insensitive_fs.inc b/mysql-test/include/have_case_insensitive_fs.inc
new file mode 100644
index 00000000000..de4ad73d780
--- /dev/null
+++ b/mysql-test/include/have_case_insensitive_fs.inc
@@ -0,0 +1,4 @@
+--require r/case_insensitive_fs.require
+--disable_query_log
+show variables like 'lower_case_file_system';
+--enable_query_log
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index c1e8f7cd826..c4d68e7127c 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -7,6 +7,7 @@ use Carp;
use My::Config;
use My::Find;
+use My::Platform;
use File::Basename;
@@ -218,7 +219,13 @@ my @mysqld_rules=
{ 'ssl-key' => \&fix_ssl_server_key },
);
-
+if (IS_WINDOWS)
+{
+ # For simplicity, we use the same names for shared memory and
+ # named pipes.
+ push(@mysqld_rules, {'shared-memory-base-name' => \&fix_socket});
+}
+
sub fix_ndb_mgmd_port {
my ($self, $config, $group_name, $group)= @_;
my $hostname= $group->value('HostName');
@@ -347,6 +354,16 @@ sub post_check_client_group {
}
$config->insert($client_group_name, $name_to, $option->value())
}
+
+ if (IS_WINDOWS)
+ {
+ # Shared memory base may or may not be defined (e.g not defined in embedded)
+ my $shm = $group_to_copy_from->option("shared-memory-base-name");
+ if (defined $shm)
+ {
+ $config->insert($client_group_name,"shared-memory-base-name", $shm->value());
+ }
+ }
}
@@ -393,6 +410,7 @@ sub post_check_embedded_group {
(
'#log-error', # Embedded server writes stderr to mysqltest's log file
'slave-net-timeout', # Embedded server are not build with replication
+ 'shared-memory-base-name', # No shared memory for embedded
);
foreach my $option ( $mysqld->options(), $first_mysqld->options() ) {
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 455262b29f5..aa9093fb2b4 100755
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -50,9 +50,6 @@
is killed.
*/
-/* Requires Windows 2000 or higher */
-#define _WIN32_WINNT 0x0500
-
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index ea05b4b23c0..bf73b45ecdf 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -518,10 +518,8 @@ sub collect_one_suite($)
next if ($test->{'name'} eq 'sys_vars.innodb_lock_wait_timeout_basic');
# Diff around innodb_thread_concurrency variable
next if ($test->{'name'} eq 'sys_vars.innodb_thread_concurrency_basic');
- # Disable for Innodb Plugin until the fix for Plugin is received
+ # Can't work with InnoPlug. Test framework needs to be re-designed.
next if ($test->{'name'} eq 'main.innodb_bug46000');
- # Disable for Innodb Plugin until the fix for Plugin is received
- next if ($test->{'name'} eq 'main.innodb_bug44369');
# Copy test options
my $new_test= My::Test->new();
while (my ($key, $value) = each(%$test))
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index db7173d0b47..06f4e7fbe8a 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1330,4 +1330,12 @@ ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9',
affected rows: 2
info: Records: 2 Duplicates: 0 Warnings: 0
DROP TABLE t1;
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+this should affect no rows as there is no real change
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index 6eaa8731dc6..1820782d2f8 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -19,81 +19,10 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
create table t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
-test.t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
-test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
-test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
-test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
-drop table t1,t2;
+ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
+drop table t1;
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
-create table t1 (a int not null);
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t1 where 0=1 procedure analyse();
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t1 values(1);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.a 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
-insert into t1 values(2);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.a 1 2 1 1 0 0 1.5000 0.5000 ENUM('1','2') NOT NULL
-drop table t1,t2;
create table t1 (v varchar(128));
insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd');
select * from t1 procedure analyse();
@@ -157,3 +86,40 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
DROP TABLE t1;
End of 4.1 tests
+#
+# Bug #48293: crash with procedure analyse, view with > 10 columns,
+# having clause...
+#
+CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
+f INT, g INT, h INT, i INT, j INT,k INT);
+INSERT INTO t1 VALUES (),();
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+#should have a derived table
+EXPLAIN SELECT * FROM v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+#should not crash
+SELECT * FROM v1 PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and view
+#should not crash
+SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and view
+#should not crash
+SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+#should not crash
+SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+#should not crash
+SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
+ERROR HY000: Can't use ORDER clause with this procedure
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+# should not crash
+CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
+ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/bug40113.result b/mysql-test/r/bug40113.result
deleted file mode 100644
index 289037a3f35..00000000000
--- a/mysql-test/r/bug40113.result
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# 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/case_insensitive_fs.require b/mysql-test/r/case_insensitive_fs.require
new file mode 100644
index 00000000000..062ac610ddd
--- /dev/null
+++ b/mysql-test/r/case_insensitive_fs.require
@@ -0,0 +1,2 @@
+Variable_name Value
+lower_case_file_system ON
diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result
index fe870f82743..d5585dcfad9 100644
--- a/mysql-test/r/ctype_ldml.result
+++ b/mysql-test/r/ctype_ldml.result
@@ -41,6 +41,14 @@ efgh efgh
ijkl ijkl
DROP TABLE t1;
#
+# Bug#45645 Mysql server close all connection and restart using lower function
+#
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+a
+DROP TABLE t1;
+#
# Bug#43827 Server closes connections and restarts
#
CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 96fcbc33d3f..5a1bf1a1290 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -194,4 +194,20 @@ dt
2001-01-01 01:01:01
2001-01-01 01:01:01
drop tables t1, t2;
+#
+# Bug#48295:
+# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
+#
+CREATE TABLE t1 (f1 INT);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED SELECT 1 FROM t1
+WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
+ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
+SHOW WARNINGS;
+Level Code Message
+Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
+Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index b030139e40e..68c4a6a13e5 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -1487,4 +1487,43 @@ MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
COUNT(*)
2
DROP TABLE t1;
+#
+# Bug #48258: Assertion failed when using a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index a3708d06a1c..b40ff6be160 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -972,6 +972,18 @@ select min(`col002`) from t1 union select `col002` from t1;
min(`col002`)
NULL
drop table t1;
+#
+# Bug #47780: crash when comparing GIS items from subquery
+#
+CREATE TABLE t1(a INT, b MULTIPOLYGON);
+INSERT INTO t1 VALUES
+(0,
+GEOMFROMTEXT(
+'multipolygon(((1 2,3 4,5 6,7 8,9 8),(7 6,5 4,3 2,1 2,3 4)))'));
+# must not crash
+SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1);
+1
+DROP TABLE t1;
End of 5.0 tests
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index a677d71b266..92beccd2a9e 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1007,8 +1007,8 @@ DROP TABLE mysqltest1.t2;
SHOW GRANTS;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
RENAME TABLE t2 TO t1;
ALTER TABLE t1 RENAME TO t2;
@@ -1018,8 +1018,8 @@ REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost;
SHOW GRANTS;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
ALTER TABLE t1 RENAME TO t2;
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index f38848111ad..59c64ee84ae 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -154,4 +154,42 @@ SELECT * FROM mysqltest_1.t1;
a
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+#
+# Bug#41597 - After rename of user, there are additional grants
+# when grants are reapplied.
+#
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+# Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+# Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+# Connect as the renamed user
+SHOW GRANTS;
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+SELECT a FROM temp.t1;
+a
+1
+2
+3
+# Check for additional privileges by accessing a
+# non privileged column. We shouldn't be able to
+# access this column.
+SELECT b FROM temp.t1;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1'
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
End of 5.0 tests
diff --git a/mysql-test/r/grant_lowercase_fs.result b/mysql-test/r/grant_lowercase_fs.result
new file mode 100644
index 00000000000..5a3087ed5cd
--- /dev/null
+++ b/mysql-test/r/grant_lowercase_fs.result
@@ -0,0 +1,16 @@
+create database db1;
+GRANT CREATE ON db1.* to user_1@localhost;
+GRANT SELECT ON db1.* to USER_1@localhost;
+CREATE TABLE t1(f1 int);
+SELECT * FROM t1;
+ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
+SELECT * FROM t1;
+f1
+CREATE TABLE t2(f1 int);
+ERROR 42000: CREATE command denied to user 'USER_1'@'localhost' for table 't2'
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result
index d2e8eb19e0c..a40a13dbe9f 100644
--- a/mysql-test/r/innodb-autoinc.result
+++ b/mysql-test/r/innodb-autoinc.result
@@ -867,6 +867,7 @@ INSERT INTO t2 SELECT NULL FROM t1;
Got one of the listed errors
DROP TABLE t1;
DROP TABLE t2;
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
@@ -882,6 +883,12 @@ d1
INSERT INTO t1 VALUES(null);
Got one of the listed errors
ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `d1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`d1`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
d1
@@ -889,3 +896,233 @@ d1
3
4
DROP TABLE t1;
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+SHOW VARIABLES LIKE "%auto_inc%";
+Variable_name Value
+auto_increment_increment 1
+auto_increment_offset 1
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyint(4) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-127 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-127, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32767, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` smallint(6) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-32767 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-32757, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` mediumint(9) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-8388607 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-2147483647 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-9223372036854775807 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on T1(c2);
+SHOW CREATE TABLE T1;
+Table Create Table
+T1 CREATE TABLE `T1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `i1` (`c2`)
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
+INSERT INTO T1 (c2) values (0);
+SELECT * FROM T1;
+c1 c2
+10 0
+DROP TABLE T1;
diff --git a/mysql-test/r/innodb_bug44369.result b/mysql-test/r/innodb_bug44369.result
index e4b84ecac19..9cf79aeffab 100644
--- a/mysql-test/r/innodb_bug44369.result
+++ b/mysql-test/r/innodb_bug44369.result
@@ -2,13 +2,13 @@ create table bug44369 (DB_ROW_ID int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
create table bug44369 (db_row_id int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
-show errors;
+show warnings;
Level Code Message
-Error 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
+Warning 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
Error 1005 Can't create table 'test.bug44369' (errno: -1)
create table bug44369 (db_TRX_Id int) engine=innodb;
ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
-show errors;
+show warnings;
Level Code Message
-Error 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
+Warning 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
Error 1005 Can't create table 'test.bug44369' (errno: -1)
diff --git a/mysql-test/r/innodb_bug46000.result b/mysql-test/r/innodb_bug46000.result
index ccff888a48d..ccf7cc56859 100644
--- a/mysql-test/r/innodb_bug46000.result
+++ b/mysql-test/r/innodb_bug46000.result
@@ -2,16 +2,16 @@ create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
-show errors;
+show warnings;
Level Code Message
-Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Warning 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
Error 1005 Can't create table 'test.bug46000' (errno: -1)
create table bug46000(id int) engine=innodb;
create index GEN_CLUST_INDEX on bug46000(id);
ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
-show errors;
+show warnings;
Level Code Message
-Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Warning 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
Error 1005 Can't create table '#sql-temporary' (errno: -1)
create index idx on bug46000(id);
drop table bug46000;
diff --git a/mysql-test/r/innodb_bug47777.result b/mysql-test/r/innodb_bug47777.result
new file mode 100644
index 00000000000..fbba47edcfc
--- /dev/null
+++ b/mysql-test/r/innodb_bug47777.result
@@ -0,0 +1,13 @@
+create table bug47777(c2 linestring not null, primary key (c2(1))) engine=innodb;
+insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+count(*)
+1
+update bug47777 set c2=GeomFromText('POINT(1 1)');
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+count(*)
+0
+select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+count(*)
+1
+drop table bug47777;
diff --git a/mysql-test/r/innodb_lock_wait_timeout_1.result b/mysql-test/r/innodb_lock_wait_timeout_1.result
new file mode 100644
index 00000000000..a635b0d527a
--- /dev/null
+++ b/mysql-test/r/innodb_lock_wait_timeout_1.result
@@ -0,0 +1,357 @@
+#
+# 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
+#
+# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
+# FOR UPDATE
+#
+drop table if exists t1;
+create table t1 (a int primary key auto_increment,
+b int, index(b)) engine=innodb;
+insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+set autocommit=0;
+begin;
+select * from t1 where b=5 for update;
+a b
+5 5
+insert ignore into t1 (b) select a as b from t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Cleanup
+#
+commit;
+set autocommit=default;
+drop table t1;
+#
+# Bug#41756 Strange error messages about locks from InnoDB
+#
+drop table if exists t1;
+# In the default transaction isolation mode, and/or with
+# innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
+# in InnoDB does nothing.
+# Thus in order to reproduce the condition that led to the
+# warning, one needs to relax isolation by either
+# setting a weaker tx_isolation value, or by turning on
+# the unsafe replication switch.
+# For testing purposes, choose to tweak the isolation level,
+# since it's settable at runtime, unlike
+# innodb_locks_unsafe_for_binlog, which is
+# only a command-line switch.
+#
+set @@session.tx_isolation="read-committed";
+# Prepare data. We need a table with a unique index,
+# for join_read_key to be used. The other column
+# allows to control what passes WHERE clause filter.
+create table t1 (a int primary key, b int) engine=innodb;
+# Let's make sure t1 has sufficient amount of rows
+# to exclude JT_ALL access method when reading it,
+# i.e. make sure that JT_EQ_REF(a) is always preferred.
+insert into t1 values (1,1), (2,null), (3,1), (4,1),
+(5,1), (6,1), (7,1), (8,1), (9,1), (10,1),
+(11,1), (12,1), (13,1), (14,1), (15,1),
+(16,1), (17,1), (18,1), (19,1), (20,1);
+#
+# Demonstrate that for the SELECT statement
+# used later in the test JT_EQ_REF access method is used.
+#
+explain
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+id 1
+select_type PRIMARY
+table <derived2>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra
+id 1
+select_type PRIMARY
+table t1
+type eq_ref
+possible_keys PRIMARY
+key PRIMARY
+key_len 4
+ref t2.a
+rows 1
+Extra Using where
+id 2
+select_type DERIVED
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id 3
+select_type UNION
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id NULL
+select_type UNION RESULT
+table <union2,3>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra
+#
+# Demonstrate that the reported SELECT statement
+# no longer produces warnings.
+#
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+1
+commit;
+#
+# Demonstrate that due to lack of inter-sweep "reset" function,
+# we keep some non-matching records locked, even though we know
+# we could unlock them.
+# To do that, show that if there is only one distinct value
+# for a in t2 (a=2), we will keep record (2,null) in t1 locked.
+# But if we add another value for "a" to t2, say 6,
+# join_read_key cache will be pruned at least once,
+# and thus record (2, null) in t1 will get unlocked.
+#
+begin;
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+1
+#
+# Switching to connection con1
+# We should be able to delete all records from t1 except (2, null),
+# since they were not locked.
+begin;
+# Delete in series of 3 records so that full scan
+# is not used and we're not blocked on record (2,null)
+delete from t1 where a in (1,3,4);
+delete from t1 where a in (5,6,7);
+delete from t1 where a in (8,9,10);
+delete from t1 where a in (11,12,13);
+delete from t1 where a in (14,15,16);
+delete from t1 where a in (17,18);
+delete from t1 where a in (19,20);
+#
+# Record (2, null) is locked. This is actually unnecessary,
+# because the previous select returned no rows.
+# Just demonstrate the effect.
+#
+delete from t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+#
+# Switching to connection default
+#
+# Show that the original contents of t1 is intact:
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+commit;
+#
+# Have a one more record in t2 to show that
+# if join_read_key cache is purned, the current
+# row under the cursor is unlocked (provided, this row didn't
+# match the partial WHERE clause, of course).
+# Sic: the result of this test dependent on the order of retrieval
+# of records --echo # from the derived table, if !
+# We use DELETE to disable the JOIN CACHE. This DELETE modifies no
+# records. It also should leave no InnoDB row locks.
+#
+begin;
+delete t1.* from t1 natural join (select 2 as a, 2 as b union all
+select 0 as a, 0 as b) as t2;
+# Demonstrate that nothing was deleted form t1
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+#
+# Switching to connection con1
+begin;
+# Since there is another distinct record in the derived table
+# the previous matching record in t1 -- (2,null) -- was unlocked.
+delete from t1;
+# We will need the contents of the table again.
+rollback;
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+commit;
+#
+# Switching to connection default
+rollback;
+begin;
+#
+# Before this patch, we could wrongly unlock a record
+# that was cached and later used in a join. Demonstrate that
+# this is no longer the case.
+# Sic: this test is also order-dependent (i.e. the
+# the bug would show up only if the first record in the union
+# is retreived and processed first.
+#
+# Verify that JT_EQ_REF is used.
+explain
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+select 3 as a, 1 as b) as t2 for update;
+id 1
+select_type PRIMARY
+table <derived2>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra
+id 1
+select_type PRIMARY
+table t1
+type eq_ref
+possible_keys PRIMARY
+key PRIMARY
+key_len 4
+ref t2.a
+rows 1
+Extra Using where
+id 2
+select_type DERIVED
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id 3
+select_type UNION
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id NULL
+select_type UNION RESULT
+table <union2,3>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra
+# Lock the record.
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+select 3 as a, 1 as b) as t2 for update;
+1
+1
+# Switching to connection con1
+#
+# We should not be able to delete record (3,1) from t1,
+# (previously it was possible).
+#
+delete from t1 where a=3;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Switching to connection default
+commit;
+set @@session.tx_isolation=default;
+drop table t1;
+#
+# End of 5.1 tests
+#
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index b112bde4f27..c882d2af1ed 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -2209,4 +2209,46 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 128 Using where
DROP TABLE t1;
+#
+# Bug #47963: Wrong results when index is used
+#
+CREATE TABLE t1(
+a VARCHAR(5) NOT NULL,
+b VARCHAR(5) NOT NULL,
+c DATETIME NOT NULL,
+KEY (c)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00');
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+a b c
+EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 77f73532474..baabf48cb2f 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1063,6 +1063,60 @@ a b c d
127 NULL 127 NULL
128 NULL 128 NULL
DROP TABLE IF EXISTS t1,t2;
+#
+# Bug #42116: Mysql crash on specific query
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+INSERT INTO t1 VALUES (1), (1), (1);
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+EXPLAIN
+SELECT *
+FROM
+t1 JOIN t2 ON t1.a = t2.a
+LEFT JOIN
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+)
+LEFT JOIN
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+)
+ON t4.a = t5.a
+)
+ON t1.a = t3.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t3 ref a a 5 test.t1.a 2 Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0
+1 SIMPLE t5 ALL NULL NULL NULL NULL 0
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
+SELECT *
+FROM
+t1 JOIN t2 ON t1.a = t2.a
+LEFT JOIN
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+)
+LEFT JOIN
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+)
+ON t4.a = t5.a
+)
+ON t1.a = t3.a;
+a a a a a a
+DROP TABLE t1,t2,t3,t4,t5,t6;
End of 5.0 tests.
CREATE TABLE t1 (f1 int);
CREATE TABLE t2 (f1 int);
diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result
new file mode 100644
index 00000000000..89883b070d2
--- /dev/null
+++ b/mysql-test/r/locale.result
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS t1;
+Start of 5.4 tests
+#
+# Bug#43207 wrong LC_TIME names for romanian locale
+#
+SET NAMES utf8;
+SET lc_time_names=ro_RO;
+SELECT DATE_FORMAT('2001-01-01', '%w %a %W');
+DATE_FORMAT('2001-01-01', '%w %a %W')
+1 Lu Luni
+SELECT DATE_FORMAT('2001-01-02', '%w %a %W');
+DATE_FORMAT('2001-01-02', '%w %a %W')
+2 Ma Marţi
+SELECT DATE_FORMAT('2001-01-03', '%w %a %W');
+DATE_FORMAT('2001-01-03', '%w %a %W')
+3 Mi Miercuri
+SELECT DATE_FORMAT('2001-01-04', '%w %a %W');
+DATE_FORMAT('2001-01-04', '%w %a %W')
+4 Jo Joi
+SELECT DATE_FORMAT('2001-01-05', '%w %a %W');
+DATE_FORMAT('2001-01-05', '%w %a %W')
+5 Vi Vineri
+SELECT DATE_FORMAT('2001-01-06', '%w %a %W');
+DATE_FORMAT('2001-01-06', '%w %a %W')
+6 Sâ Sâmbătă
+SELECT DATE_FORMAT('2001-01-07', '%w %a %W');
+DATE_FORMAT('2001-01-07', '%w %a %W')
+0 Du Duminică
+End of 5.4 tests
diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result
index ecb21261987..4a59801692d 100644
--- a/mysql-test/r/lowercase_fs_off.result
+++ b/mysql-test/r/lowercase_fs_off.result
@@ -10,3 +10,48 @@ create database D1;
ERROR 42000: Access denied for user 'sample'@'localhost' to database 'D1'
drop user 'sample'@'localhost';
drop database if exists d1;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE T1(f1 INT);
+CREATE TABLE t1(f1 INT);
+GRANT SELECT ON T1 to user_1@localhost;
+select * from t1;
+ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
+select * from T1;
+f1
+GRANT SELECT ON t1 to user_1@localhost;
+select * from information_schema.table_privileges;
+GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
+'user_1'@'localhost' NULL d1 T1 SELECT NO
+'user_1'@'localhost' NULL d1 t1 SELECT NO
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+DROP USER user_1@localhost;
+DROP DATABASE d1;
+USE test;
+CREATE DATABASE db1;
+USE db1;
+CREATE PROCEDURE p1() BEGIN END;
+CREATE FUNCTION f1(i INT) RETURNS INT RETURN i+1;
+GRANT USAGE ON db1.* to user_1@localhost;
+GRANT EXECUTE ON PROCEDURE db1.P1 to user_1@localhost;
+GRANT EXECUTE ON FUNCTION db1.f1 to user_1@localhost;
+GRANT UPDATE ON db1.* to USER_1@localhost;
+call p1();
+call P1();
+select f1(1);
+f1(1)
+2
+call p1();
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1'
+call P1();
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1'
+select f1(1);
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.f1'
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP FUNCTION f1;
+DROP PROCEDURE p1;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index f5050ccf1c0..95fdc4fb93d 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from 0 to 7168
test.t1 repair status OK
+SET myisam_repair_threads=2;
+REPAIR TABLE t1;
+SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/myisam_crash_before_flush_keys.result b/mysql-test/r/myisam_crash_before_flush_keys.result
index 372f2e41590..d3545ea47d0 100644
--- a/mysql-test/r/myisam_crash_before_flush_keys.result
+++ b/mysql-test/r/myisam_crash_before_flush_keys.result
@@ -15,31 +15,13 @@ SET SESSION debug="d,crash_before_flush_keys";
# Run the crashing query
FLUSH TABLE t1;
ERROR HY000: Lost connection to MySQL server during query
-# Run MYISAMCHK tool to check the table t1 and repair
-myisamchk: MyISAM file MYSQLD_DATADIR/test/t1
-myisamchk: warning: 1 client is using or hasn't closed the table properly
-myisamchk: error: Size of indexfile is: 1024 Should be: 3072
-MYISAMCHK: Unknown error 126
-myisamchk: error: Can't read indexpage from filepos: 1024
-MyISAM-table 'MYSQLD_DATADIR/test/t1' is corrupted
-Fix it using switch "-r" or "-o"
# Write file to make mysql-test-run.pl start the server
# Turn on reconnect
# Call script that will poll the server waiting for
# it to be back online again
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) NOT NULL DEFAULT '0',
- `b` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`a`,`b`),
- KEY `b` (`b`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-a b
-1 2
-2 3
-3 4
-4 5
-5 6
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check warning 1 client is using or hasn't closed the table properly
+test.t1 check error Size of indexfile is: 1024 Should be: 3072
+test.t1 check error Corrupt
DROP TABLE t1;
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index 4540c9d5218..a7516d97888 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -733,4 +733,24 @@ SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
1
1
DROP TABLE t1;
+#
+# Bug #48131: crash group by with rollup, distinct,
+# filesort, with temporary tables
+#
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+a b
+1 100
+1 NULL
+2 100
+2 NULL
+NULL NULL
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+b
+100
+NULL
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 769d499fc0a..3128c57b2cf 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -1272,10 +1272,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL);
# test with an invalid date, which lead to item->null_value is set.
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Warning 1292 Incorrect datetime value: '2009-04-99'
-Warning 1292 Incorrect datetime value: '2009-04-99'
DROP TABLE t1;
CREATE TABLE t1
(a INT NOT NULL AUTO_INCREMENT,
diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result
index 8b16123ccea..672db74d9c0 100644
--- a/mysql-test/r/ps_grant.result
+++ b/mysql-test/r/ps_grant.result
@@ -32,19 +32,19 @@ identified by 'looser' ;
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
drop table mysqltest.t9 ;
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
prepare s_t1 from 'select a as my_col from t1' ;
execute s_t1 ;
my_col
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 6cabc24d0eb..2817bec2198 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -1708,6 +1708,7 @@ Qcache_hits 2
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
End of 5.0 tests
+SET GLOBAL query_cache_size=1024*1024*512;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
@@ -1722,4 +1723,5 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
+SET GLOBAL query_cache_size= default;
End of 5.1 tests
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index c98a7696ea6..2306f8b501e 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1398,3 +1398,209 @@ a < 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
DROP TABLE t1, t2, t3;
+#
+# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+a
+DROP TABLE t1;
+#
+# Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+#
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+# Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+('2009-09-23 12:00:00');
+# DATE vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# DATE vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923120000';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923120000;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923000000';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923000000;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# Test of the new get_date_from_str implementation
+# Behavior differs slightly between the trunk and mysql-pe.
+# The former may give errors for the truncated values, while the latter
+# gives warnings. The purpose of this test is not to interfere, and only
+# preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= ''
+NULL
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('', '%Y-%m-%d');
+str_to_date('', '%Y-%m-%d')
+0000-00-00
+DROP TABLE t1, t2;
+End of 5.1 tests
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 50b5c3c13fb..1b615233a14 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4386,6 +4386,47 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
+#
+# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+# forcing a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+1
+1
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+1
+1
+1
+1
+1
+DROP TABLE t1;
+#
+# Bug #48291 : crash with row() operator,select into @var, and
+# subquery returning multiple rows
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+# Should not crash
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
End of 5.0 tests
create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result
new file mode 100644
index 00000000000..14c5311bbe5
--- /dev/null
+++ b/mysql-test/r/sp-bugs.result
@@ -0,0 +1,47 @@
+#
+# Bug #47412: Valgrind warnings / user can read uninitalized memory
+# using SP variables
+#
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+# should not return valgrind warnings
+SELECT f2 ();
+f2 ()
+NULL
+DROP SCHEMA testdb;
+End of 5.1 tests
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 8a8cbd751a0..ef51f5e37fb 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1652,3 +1652,19 @@ NULL
SELECT non_existent (a) FROM t1 WHERE b = 999999;
ERROR 42000: FUNCTION test.non_existent does not exist
DROP TABLE t1;
+#
+# Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
+# SP + MERGE + ALTER
+#
+CREATE TABLE t1 (pk INT, b INT, KEY (b));
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a;
+CALL p1(5);
+ERROR HY000: The target table v1 of the UPDATE is not updatable
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+CALL p1(7);
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index c60ac9790c5..665473df3ef 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-ERROR HY000: Incorrect usage of PROCEDURE and subquery
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
@@ -4403,8 +4403,7 @@ FROM t1
WHERE a = 230;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY st1 index NULL a 5 NULL 2 Using index
-2 DEPENDENT SUBQUERY st2 index b b 5 NULL 2 Using where; Using index; Using join buffer
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
FROM t1
WHERE a = 230;
@@ -4564,4 +4563,18 @@ id g v s
51 50 NULL l
61 60 NULL l
drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index f055b40116a..d5fb1a7bbde 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -895,3 +895,72 @@ t1.a < (select t4.a+10
from t4, t5 limit 2));
ERROR 21000: Subquery returns more than 1 row
drop table t0, t1, t2, t3, t4, t5;
+#
+# BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+# values return too many records
+#
+CREATE TABLE t1 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+CREATE TABLE t2 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+Data in t1
+SELECT i1, i2 FROM t1;
+i1 i2
+1 NULL
+2 3
+4 NULL
+4 0
+NULL NULL
+
+Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+i1 i2
+4 NULL
+5 0
+FLUSH STATUS;
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Check that the subquery only has to be evaluated once
+# for all-NULL values even though there are two (NULL,NULL) records
+# Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 17
+
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Handler_read_rnd_next should be one more than baseline
+# (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 18
+DROP TABLE t1,t2;
+End of 5.1 tests
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index e252331cd1a..17fd95ab1c8 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -161,7 +161,7 @@ procs_priv CREATE TABLE `procs_priv` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
- `Routine_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
+ `Routine_name` char(64) CHARACTER SET utf8 NOT NULL DEFAULT '',
`Routine_type` enum('FUNCTION','PROCEDURE') COLLATE utf8_bin NOT NULL,
`Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '',
`Proc_priv` set('Execute','Alter Routine','Grant') CHARACTER SET utf8 NOT NULL DEFAULT '',
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index c3d1e400b23..748aadee4fb 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1495,9 +1495,9 @@ CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
aa SUM(b)
-2.00000000000000000000000000000 10
-3.00000000000000000000000000000 10
-4.00000000000000000000000000000 30
+2.000000000000000000000000000000 10
+3.000000000000000000000000000000 10
+4.000000000000000000000000000000 30
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
DROP TABLE t1;
@@ -1521,13 +1521,13 @@ f1
DROP TABLE t1;
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
Warnings:
-Note 1265 Data truncated for column 'f1' at row 1
+Warning 1264 Out of range value for column 'f1' at row 1
DESC t1;
Field Type Null Key Default Extra
-f1 decimal(65,20) NO 0.00000000000000000000
+f1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT f1 FROM t1;
f1
-123451234512345123451234512345123451234512345.67890678906789067891
+99999999999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000);
@@ -1595,7 +1595,7 @@ Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
-my_col decimal(32,30) NO 0.000000000000000000000000000000
+my_col decimal(65,30) NO 0.000000000000000000000000000000
SELECT my_col FROM t1;
my_col
1.123456789123456789123456789123
@@ -1625,212 +1625,8 @@ Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
-my_col decimal(30,30) YES NULL
+my_col decimal(65,30) YES NULL
SELECT my_col FROM t1;
my_col
0.012345687012345687012345687012
DROP TABLE t1;
-#
-# Bug#45261: Crash, stored procedure + decimal
-#
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
-AS c1;
-Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,25) NO 0.0000000000000000000000000
-SELECT * FROM t1;
-c1
-1000000000000000000000000000000000000001.1000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(31,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(31,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(30,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-0.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,20) NO 0.00000000000000000000
-SELECT * FROM t1;
-c1
-123456789012345678901234567890123456789012345.12345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-12345678901234567890123456789012345678901234567890123456789012345
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(30,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-0.123456789012345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(33,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-123.123456789012345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,29) NO 0.00000000000000000000000000000
-SELECT * FROM t1;
-c1
-2.10000000000000000000000000000
-DROP TABLE t1;
-#
-# Test that the integer and decimal parts are properly calculated.
-#
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 3
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-Note 1265 Data truncated for column 'c1' at row 2
-Note 1265 Data truncated for column 'c1' at row 3
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(31,30) YES NULL
-DROP TABLE t1,t2;
-#
-# Test that variables get maximum precision.
-#
-SET @decimal= 1.1;
-CREATE TABLE t1 SELECT @decimal AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,30) YES NULL
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 7a51649fac5..d859579e835 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -503,3 +503,14 @@ ERROR HY000: Recursive stored functions and triggers are not allowed.
DROP TABLE t1;
DROP FUNCTION f1;
End of 5.0 tests
+#
+# Bug #47919 assert in open_table during ALTER temporary table
+#
+CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
+CREATE TEMPORARY TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 COMMENT = 'ABC';
+UPDATE t2, t1 SET t2.f1 = 2, t1.f1 = 9;
+ALTER TABLE t2 COMMENT = 'DEF';
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index a9d4164cda4..83cacc315d8 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -1218,3 +1218,22 @@ Warnings:
Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
DROP TABLE t1;
DROP VIEW v1;
+#
+# Bug #46019: ERROR 1356 When selecting from within another
+# view that has Group By
+#
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+CREATE TABLE t1 (a INT);
+CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT a FROM t1 GROUP BY a;
+CREATE SQL SECURITY INVOKER VIEW v2 AS SELECT a FROM v1;
+CREATE USER mysqluser1;
+GRANT SELECT ON TABLE t1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO mysqluser1;
+SELECT a FROM v1;
+a
+SELECT a FROM v2;
+a
+DROP USER mysqluser1;
+DROP DATABASE mysqltest1;
diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result
index a597806d897..d23c8e672b0 100644
--- a/mysql-test/r/xa.result
+++ b/mysql-test/r/xa.result
@@ -89,3 +89,28 @@ xa start 'a';
xa end 'a';
xa prepare 'a';
xa commit 'a';
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+BEGIN;
+UPDATE t1 SET a=4 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+ROLLBACK;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+XA START 'xid1';
+UPDATE t1 SET a=4 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+XA END 'xid1';
+ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected
+XA ROLLBACK 'xid1';
+XA START 'xid1';
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result
new file mode 100644
index 00000000000..036ccf131bb
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result
@@ -0,0 +1,50 @@
+RESET MASTER;
+CREATE TABLE t1 (a int);
+### assertion: index file contains regular entries
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000001
+
+### assertion: show original binlogs
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+### assertion: binlog contents from regular entries
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
+FLUSH LOGS;
+### assertion: index file contains renamed binlog and the new one
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin-b34582.000001
+master-bin.000002
+
+### assertion: original binlog content still exists, despite we
+### renamed and changed the index file
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin-b34582.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
+### assertion: user changed binlog index shows correct entries
+show binary logs;
+Log_name File_size
+master-bin-b34582.000001 #
+master-bin.000002 #
+DROP TABLE t1;
+### assertion: purging binlogs up to binlog created after instrumenting index file should work
+PURGE BINARY LOGS TO 'master-bin.000002';
+### assertion: show binary logs should only contain latest binlog
+show binary logs;
+Log_name File_size
+master-bin.000002 #
+### assertion: assert that binlog files were indeed purged (using file_exists calls)
+### assertion: assert that not purged binlog file exists
+### assertion: show index file contents and these should match show binary logs issued above
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000002
+
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
index 0a6ff1d4400..75c088e595d 100644
--- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
@@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t;
SELECT GET_LOCK("a",10);
GET_LOCK("a",10)
1
+USE test;
SELECT GET_LOCK("a",10);
GET_LOCK("a",10)
1
diff --git a/mysql-test/suite/binlog/r/binlog_stm_do_db.result b/mysql-test/suite/binlog/r/binlog_stm_do_db.result
new file mode 100644
index 00000000000..ab4ba7cdca1
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_stm_do_db.result
@@ -0,0 +1,42 @@
+SET @old_isolation_level= @@session.tx_isolation;
+SET @@session.tx_isolation= 'READ-COMMITTED';
+CREATE DATABASE b42829;
+use b42829;
+CREATE TABLE t1 (x int, y int) engine=InnoDB;
+CREATE TABLE t2 (x int, y int) engine=InnoDB;
+CREATE DATABASE b42829_filtered;
+use b42829_filtered;
+CREATE TABLE t1 (x int, y int) engine=InnoDB;
+CREATE TABLE t2 (x int, y int) engine=InnoDB;
+SET @@session.sql_log_bin= 0;
+INSERT INTO b42829_filtered.t1 VALUES (100,100);
+INSERT INTO b42829.t1 VALUES (100,100);
+SET @@session.sql_log_bin= 1;
+### assertion: the inserts will not raise log error because
+### binlog-do-db is filtering used database
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+INSERT INTO t1 SELECT * FROM t2;
+### assertion: assert that despite updating a not filtered
+### database this wont trigger an error as the
+### used database is the filtered one.
+UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2;
+use b42829;
+### assertion: the statements *will* raise log error because
+### binlog-do-db is not filtering used database
+BEGIN;
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2;
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+INSERT INTO t1 SELECT * FROM t2;
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+COMMIT;
+### assertion: filtered events did not make into the binlog
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE b42829
+master-bin.000001 # Query # # use `b42829`; CREATE TABLE t1 (x int, y int) engine=InnoDB
+master-bin.000001 # Query # # use `b42829`; CREATE TABLE t2 (x int, y int) engine=InnoDB
+DROP DATABASE b42829;
+DROP DATABASE b42829_filtered;
+SET @@session.tx_isolation= @old_isolation_level;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
index 8bbf1bccc63..19ddcf49080 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
@@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t;
SELECT GET_LOCK("a",10);
GET_LOCK("a",10)
1
+USE test;
SELECT GET_LOCK("a",10);
GET_LOCK("a",10)
1
diff --git a/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
new file mode 100644
index 00000000000..84c83687486
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
@@ -0,0 +1,114 @@
+# BUG#34582: FLUSH LOGS does not close and reopen the binlog index
+# file
+#
+# WHAT
+# ====
+#
+# We want to test that FLUSH LOGS closes and reopens binlog index
+# file.
+#
+# HOW
+# ===
+#
+# PREPARE:
+# 1. create some binlog events
+# 2. show index content, binlog events and binlog contents
+# for mysql-bin.000001
+# 3. copy the mysql-bin.000001 to mysql-bin-b34582.000001
+# 4. change the index file so that mysql-bin.000001 is replaced
+# with mysql-bin-b34582.000001
+# 5. FLUSH the logs so that new index is closed and reopened
+#
+# ASSERTIONS:
+# 1. index file contents shows mysql-bin-b34582.000001 and
+# mysql-bin.000002
+# 1. show binary logs shows current index entries
+# 2. binlog contents for mysql-bin-b34582.000001 are displayed
+# 3. Purge binlogs up to the latest one succeeds
+# 4. SHOW BINARY LOGS presents the latest one only after purging
+# 5. Purged binlogs files don't exist in the filesystem
+# 6. Not purged binlog file exists in the filesystem
+#
+# CLEAN UP:
+# 1. RESET MASTER
+#
+
+-- source include/have_log_bin.inc
+
+RESET MASTER;
+
+-- let $datadir= `SELECT @@datadir`
+-- let $index=$datadir/master-bin.index
+-- chmod 0644 $index
+
+# action: issue one command so that binlog gets some event
+CREATE TABLE t1 (a int);
+
+-- echo ### assertion: index file contains regular entries
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo ### assertion: show original binlogs
+-- source include/show_binary_logs.inc
+
+--echo ### assertion: binlog contents from regular entries
+-- source include/show_binlog_events.inc
+
+# action: copy binlogs to other names and change entries in index file
+-- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001
+let INDEX_FILE=$index;
+perl;
+$file= $ENV{'INDEX_FILE'};
+open(FILE, ">$file") || die "Unable to open $file.";
+truncate(FILE,0);
+close ($file);
+EOF
+
+-- append_file $index
+master-bin-b34582.000001
+EOF
+
+# action: should cause rotation, and creation of new binlogs
+FLUSH LOGS;
+
+# file is not used anymore - remove it (mysql closed on flush logs).
+-- remove_file $datadir/master-bin.000001
+
+-- echo ### assertion: index file contains renamed binlog and the new one
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+-- echo ### assertion: original binlog content still exists, despite we
+-- echo ### renamed and changed the index file
+-- source include/show_binlog_events.inc
+
+-- echo ### assertion: user changed binlog index shows correct entries
+-- source include/show_binary_logs.inc
+
+DROP TABLE t1;
+
+-- echo ### assertion: purging binlogs up to binlog created after instrumenting index file should work
+-- let $current_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
+-- eval PURGE BINARY LOGS TO '$current_binlog'
+
+-- echo ### assertion: show binary logs should only contain latest binlog
+-- source include/show_binary_logs.inc
+
+-- echo ### assertion: assert that binlog files were indeed purged (using file_exists calls)
+-- error 1
+-- file_exists $datadir/master-bin-b34852.000001
+
+-- echo ### assertion: assert that not purged binlog file exists
+-- file_exists $datadir/$current_binlog
+
+-- echo ### assertion: show index file contents and these should match show binary logs issued above
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
new file mode 100644
index 00000000000..e2cfcb299cf
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
@@ -0,0 +1 @@
+--binlog-do-db=b42829
diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db.test b/mysql-test/suite/binlog/t/binlog_stm_do_db.test
new file mode 100644
index 00000000000..858bc8cc683
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_do_db.test
@@ -0,0 +1,90 @@
+# BUG#42829: binlogging enabled for all schemas regardless of
+# binlog-db-db / binlog-ignore-db
+#
+# WHAT
+# ====
+#
+# We want to test whether filtered events from binlog will cause
+# raising an error mentioning that statement is unable to be logged or
+# not, when:
+#
+# 1. isolation level READ-COMMITTED; AND
+#
+# 2. using InnoDB engine; AND
+#
+# 3. using SBL (in which case InnoDB will only allow RBL).
+#
+# HOW
+# ===
+#
+# The test is implemented as follows:
+#
+# i) set tx_isolation to read-committed.
+#
+# ii) create two databases (one filtered other not - using
+# binlog-do-db)
+#
+# iii) Create statements that are to be filtered on filtered db
+#
+# - At this point, before fix, an error would be raised
+#
+# iv) do the same thing for not the filtered database and check
+# that events throw an error:
+#
+# - Error: ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
+#
+
+-- source include/have_log_bin.inc
+-- source include/have_innodb.inc
+-- source include/have_binlog_format_statement.inc
+
+SET @old_isolation_level= @@session.tx_isolation;
+SET @@session.tx_isolation= 'READ-COMMITTED';
+
+-- let $engine= InnoDB
+-- let $filtered= b42829_filtered
+-- let $not_filtered= b42829
+
+-- eval CREATE DATABASE $not_filtered
+-- eval use $not_filtered
+-- eval CREATE TABLE t1 (x int, y int) engine=$engine
+-- eval CREATE TABLE t2 (x int, y int) engine=$engine
+
+-- eval CREATE DATABASE $filtered
+-- eval use $filtered
+-- eval CREATE TABLE t1 (x int, y int) engine=$engine
+-- eval CREATE TABLE t2 (x int, y int) engine=$engine
+
+SET @@session.sql_log_bin= 0;
+-- eval INSERT INTO $filtered.t1 VALUES (100,100)
+-- eval INSERT INTO $not_filtered.t1 VALUES (100,100)
+SET @@session.sql_log_bin= 1;
+
+-- echo ### assertion: the inserts will not raise log error because
+-- echo ### binlog-do-db is filtering used database
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+INSERT INTO t1 SELECT * FROM t2;
+
+-- echo ### assertion: assert that despite updating a not filtered
+-- echo ### database this wont trigger an error as the
+-- echo ### used database is the filtered one.
+-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2
+
+-- eval use $not_filtered
+-- echo ### assertion: the statements *will* raise log error because
+-- echo ### binlog-do-db is not filtering used database
+BEGIN;
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+INSERT INTO t1 SELECT * FROM t2;
+COMMIT;
+
+-- echo ### assertion: filtered events did not make into the binlog
+source include/show_binlog_events.inc;
+
+-- eval DROP DATABASE $not_filtered
+-- eval DROP DATABASE $filtered
+SET @@session.tx_isolation= @old_isolation_level;
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index 2f1f61c0525..98eeacdb74c 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -130,7 +130,7 @@ NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references
-NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
@@ -411,7 +411,7 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql procs_priv User char 16 48 utf8 utf8_bin char(16)
-3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_bin char(64)
+3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql procs_priv Routine_type enum 9 27 utf8 utf8_bin enum('FUNCTION','PROCEDURE')
3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77)
3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant')
diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result
index 989fd9dc4e6..8452536d4ed 100644
--- a/mysql-test/suite/funcs_1/r/is_statistics.result
+++ b/mysql-test/suite/funcs_1/r/is_statistics.result
@@ -166,8 +166,8 @@ NULL db_datadict_2 t4 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
-GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
+GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost';
Grants for testuser2@localhost
GRANT USAGE ON *.* TO 'testuser2'@'localhost'
@@ -185,8 +185,8 @@ NULL db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
-GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
+GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost';
ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql'
# Switch to connection testuser2
diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result
index b26c4112826..21396d81ba8 100644
--- a/mysql-test/suite/innodb/r/innodb-zip.result
+++ b/mysql-test/suite/innodb/r/innodb-zip.result
@@ -196,15 +196,15 @@ drop table t1;
set innodb_strict_mode = on;
create table t1 (id int primary key) engine = innodb key_block_size = 0;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 9;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 1;
create table t4 (id int primary key) engine = innodb key_block_size = 2;
@@ -233,30 +233,30 @@ key_block_size = 8 row_format = compressed;
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t5' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -266,26 +266,26 @@ drop table t1;
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -293,45 +293,45 @@ table_schema table_name row_format
set global innodb_file_per_table = off;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -345,45 +345,45 @@ set global innodb_file_per_table = on;
set global innodb_file_format = `0`;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def
index 176963df340..baf8c89f539 100644
--- a/mysql-test/suite/innodb/t/disabled.def
+++ b/mysql-test/suite/innodb/t/disabled.def
@@ -1,2 +1 @@
innodb-index: InnoDB: Error: table `test`.`t1#1` already exists in InnoDB internal
-innodb_information_schema: Bug #47808 joro : innodb_information_schema.test fails when run under valgrind
diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test
index 09320570546..c27392ac4fa 100644
--- a/mysql-test/suite/innodb/t/innodb-zip.test
+++ b/mysql-test/suite/innodb/t/innodb-zip.test
@@ -175,11 +175,11 @@ set innodb_strict_mode = on;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 0;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 9;
-show errors;
+show warnings;
create table t3 (id int primary key) engine = innodb key_block_size = 1;
@@ -205,22 +205,22 @@ key_block_size = 8 row_format = compressed;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -230,17 +230,17 @@ drop table t1;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -250,25 +250,25 @@ set global innodb_file_per_table = off;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -282,25 +282,25 @@ set global innodb_file_format = `0`;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema.test b/mysql-test/suite/innodb/t/innodb_information_schema.test
index df65139448c..599215e9ca4 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema.test
+++ b/mysql-test/suite/innodb/t/innodb_information_schema.test
@@ -110,14 +110,18 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE;
-- send
SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE;
-# Give time to the above 2 queries to execute before continuing.
-# Without this sleep it sometimes happens that the SELECT from innodb_locks
-# executes before some of them, resulting in less than expected number
-# of rows being selected from innodb_locks.
--- sleep 0.1
-
-- enable_result_log
-- connection con_verify_innodb_locks
+# Wait for the above queries to execute before continuing.
+# Without this, it sometimes happens that the SELECT from innodb_locks
+# executes before some of them, resulting in less than expected number
+# of rows being selected from innodb_locks. If there is a bug and there
+# are no 14 rows in innodb_locks then this test will fail with timeout.
+let $count = 14;
+let $table = INFORMATION_SCHEMA.INNODB_LOCKS;
+-- source include/wait_until_rows_count.inc
+# the above enables the query log, re-disable it
+-- disable_query_log
SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data
FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data;
diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
index ae3554a5420..5f2a55b5e35 100644
--- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
+++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
@@ -4,8 +4,10 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'");
+call mtr.add_suppression("Get master clock failed with error: ");
+call mtr.add_suppression("Get master SERVER_ID failed with error: ");
call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1
diff --git a/mysql-test/suite/rpl/r/rpl_loaddata.result b/mysql-test/suite/rpl/r/rpl_loaddata.result
index 4c6fd43da13..4e81d90a970 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddata.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddata.result
@@ -200,3 +200,32 @@ CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY'
DROP TABLE IF EXISTS t1;
+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;
+drop database if exists b48297_db1;
+drop database if exists b42897_db2;
+create database b48297_db1;
+create database b42897_db2;
+use b48297_db1;
+CREATE TABLE t1 (c1 VARCHAR(256)) engine=MyISAM;;
+use b42897_db2;
+### assertion: works with cross-referenced database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+use b48297_db1;
+### assertion: works with fully qualified name on current database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### assertion: works without fully qualified name on current database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1;
+### create connection without default database
+### connect (conn2,localhost,root,,*NO-ONE*);
+### assertion: works without stating the default database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### disconnect and switch back to master connection
+use b48297_db1;
+Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1
+DROP DATABASE b48297_db1;
+DROP DATABASE b42897_db2;
diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
index 4a6741a2db6..a955de02c0f 100644
--- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
+++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
@@ -46,7 +46,7 @@ kill @id;
drop table t2,t3;
insert into t4 values (3),(4);
connection master;
---error 0,1053,2013
+--error 0,1317,2013
reap;
connection master1;
sync_slave_with_master;
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt
new file mode 100644
index 00000000000..f9aa8c0367e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt
@@ -0,0 +1 @@
+--master-retry-count=60
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
index a391b1f5344..69c63eaa69f 100644
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
@@ -16,8 +16,10 @@
source include/master-slave.inc;
source include/have_debug.inc;
-call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'");
+call mtr.add_suppression("Get master clock failed with error: ");
+call mtr.add_suppression("Get master SERVER_ID failed with error: ");
call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection
connection slave;
let $debug_saved= `select @@global.debug`;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 17549745203..5534aa0a234 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1046,4 +1046,19 @@ ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9',
--disable_info
DROP TABLE t1;
+#
+# Bug#43508: Renaming timestamp or date column triggers table copy
+#
+
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+ f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+
+--echo this should affect no rows as there is no real change
+--enable_info
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+--disable_info
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index d8466df14bf..05f739bfd69 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -10,37 +10,14 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6
select count(*) from t1 procedure analyse();
select * from t1 procedure analyse();
select * from t1 procedure analyse(2);
+--error ER_WRONG_USAGE
create table t2 select * from t1 procedure analyse();
-select * from t2;
-drop table t1,t2;
+drop table t1;
--error ER_WRONG_USAGE
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
#
-# Test with impossible where
-#
-create table t1 (a int not null);
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t1 where 0=1 procedure analyse();
-insert into t1 values(1);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t2;
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-insert into t1 values(2);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t2;
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-drop table t1,t2;
-
-#
# Bug#2813 - analyse does not quote string values in enums from string
#
@@ -113,3 +90,46 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
DROP TABLE t1;
--echo End of 4.1 tests
+
+--echo #
+--echo # Bug #48293: crash with procedure analyse, view with > 10 columns,
+--echo # having clause...
+--echo #
+
+CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
+ f INT, g INT, h INT, i INT, j INT,k INT);
+INSERT INTO t1 VALUES (),();
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+--echo #should have a derived table
+EXPLAIN SELECT * FROM v1;
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM v1 PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
+--echo #should not crash
+--error ER_ORDER_WITH_PROC
+SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+
+--echo # should not crash
+--error ER_WRONG_USAGE
+CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
+
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/bug40113.test b/mysql-test/t/bug40113.test
deleted file mode 100644
index 6d35d0b73d3..00000000000
--- a/mysql-test/t/bug40113.test
+++ /dev/null
@@ -1,46 +0,0 @@
---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/ctype_ldml.test b/mysql-test/t/ctype_ldml.test
index bc04b93a935..0395de273de 100644
--- a/mysql-test/t/ctype_ldml.test
+++ b/mysql-test/t/ctype_ldml.test
@@ -38,6 +38,14 @@ SELECT * FROM t1 WHERE col1=col2 ORDER BY col1;
DROP TABLE t1;
--echo #
+--echo # Bug#45645 Mysql server close all connection and restart using lower function
+--echo #
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+DROP TABLE t1;
+
+--echo #
--echo # Bug#43827 Server closes connections and restarts
--echo #
# Crash happened with a user-defined utf8 collation,
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 6f0b1716d38..ad7617b9403 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -10,7 +10,8 @@
#
##############################################################################
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
-innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently"
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
+innodb-autoinc : Bug#48482 2009-11-02 svoj innodb-autoinc.test fails with results difference
+rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 18f1145a25d..77b49a8b1a5 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -167,4 +167,24 @@ flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
drop tables t1, t2;
+--echo #
+--echo # Bug#48295:
+--echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
+--echo #
+
+CREATE TABLE t1 (f1 INT);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
+--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
+EXPLAIN EXTENDED SELECT 1 FROM t1
+ WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
+SHOW WARNINGS;
+
+SET SESSION sql_mode=@old_sql_mode;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test
index aeb09d52460..2d359383949 100644
--- a/mysql-test/t/flush_read_lock_kill.test
+++ b/mysql-test/t/flush_read_lock_kill.test
@@ -57,7 +57,7 @@ connection con1;
# debug build running without our --debug=make_global..., will be
# error 0 (no error). The only important thing to test is that on
# debug builds with our --debug=make_global... we don't hang forever.
---error 0,1053,2013
+--error 0,1317,2013
reap;
connection con2;
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index 19bbcf19cca..c325b3bd223 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -881,4 +881,25 @@ SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE
DROP TABLE t1;
+
+--echo #
+--echo # Bug #48258: Assertion failed when using a spatial index
+--echo #
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+DROP TABLE t1;
+
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 4a60e777cc7..2d10c3bf1e1 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -655,6 +655,22 @@ insert into t1 values (),(),();
select min(`col002`) from t1 union select `col002` from t1;
drop table t1;
+--echo #
+--echo # Bug #47780: crash when comparing GIS items from subquery
+--echo #
+
+CREATE TABLE t1(a INT, b MULTIPOLYGON);
+INSERT INTO t1 VALUES
+ (0,
+ GEOMFROMTEXT(
+ 'multipolygon(((1 2,3 4,5 6,7 8,9 8),(7 6,5 4,3 2,1 2,3 4)))'));
+
+--echo # must not crash
+SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1);
+
+DROP TABLE t1;
+
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index 9a635048774..437fc9a278f 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -163,6 +163,41 @@ connection default;
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+--echo #
+--echo # Bug#41597 - After rename of user, there are additional grants
+--echo # when grants are reapplied.
+--echo #
+
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+
+
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+--echo # Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+--echo # Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+
+--echo # Connect as the renamed user
+connect (conn1, localhost, user2,,);
+connection conn1;
+SHOW GRANTS;
+SELECT a FROM temp.t1;
+--echo # Check for additional privileges by accessing a
+--echo # non privileged column. We shouldn't be able to
+--echo # access this column.
+--error ER_COLUMNACCESS_DENIED_ERROR
+SELECT b FROM temp.t1;
+disconnect conn1;
+
+connection default;
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant_lowercase_fs.test b/mysql-test/t/grant_lowercase_fs.test
new file mode 100644
index 00000000000..f57f950ec8c
--- /dev/null
+++ b/mysql-test/t/grant_lowercase_fs.test
@@ -0,0 +1,30 @@
+-- source include/have_case_insensitive_fs.inc
+-- source include/not_embedded.inc
+
+
+#
+# Bug#41049 does syntax "grant" case insensitive?
+#
+create database db1;
+GRANT CREATE ON db1.* to user_1@localhost;
+GRANT SELECT ON db1.* to USER_1@localhost;
+
+connect (con1,localhost,user_1,,db1);
+CREATE TABLE t1(f1 int);
+--error 1142
+SELECT * FROM t1;
+connect (con2,localhost,USER_1,,db1);
+SELECT * FROM t1;
+--error 1142
+CREATE TABLE t2(f1 int);
+
+connection default;
+disconnect con1;
+disconnect con2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test
index 61c42f45733..3f45bb9d003 100644
--- a/mysql-test/t/innodb-autoinc.test
+++ b/mysql-test/t/innodb-autoinc.test
@@ -482,6 +482,7 @@ DROP TABLE t2;
# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
# the index (PRIMARY)
# This test requires a restart of the server
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (null);
INSERT INTO t1 VALUES (null);
@@ -492,9 +493,130 @@ SELECT * FROM t1;
# The MySQL and InnoDB data dictionaries should now be out of sync.
# The select should print message to the error log
SELECT * FROM t1;
+# MySQL have made a change (http://lists.mysql.com/commits/75268) that no
+# longer results in the two data dictionaries being out of sync. If they
+# revert their changes then this check for ER_AUTOINC_READ_FAILED will need
+# to be enabled.
-- error ER_AUTOINC_READ_FAILED,1467
INSERT INTO t1 VALUES(null);
ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES(null);
SELECT * FROM t1;
DROP TABLE t1;
+
+# If the user has specified negative values for an AUTOINC column then
+# InnoDB should ignore those values when setting the table's max value.
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+SHOW VARIABLES LIKE "%auto_inc%";
+# TINYINT
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# SMALLINT
+#
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32767, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32757, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# MEDIUMINT
+#
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# INT
+#
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# BIGINT
+#
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# End negative number check
+
+##
+# 47125: auto_increment start value is ignored if an index is created
+# and engine=innodb
+#
+CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on T1(c2);
+SHOW CREATE TABLE T1;
+INSERT INTO T1 (c2) values (0);
+SELECT * FROM T1;
+DROP TABLE T1;
diff --git a/mysql-test/t/innodb_bug34300.test b/mysql-test/t/innodb_bug34300.test
index ecec381da14..432ddd03547 100644
--- a/mysql-test/t/innodb_bug34300.test
+++ b/mysql-test/t/innodb_bug34300.test
@@ -9,7 +9,6 @@
-- disable_result_log
# set packet size and reconnect
-let $max_packet=`select @@global.max_allowed_packet`;
SET @@global.max_allowed_packet=16777216;
--connect (newconn, localhost, root,,)
diff --git a/mysql-test/t/innodb_bug39438.test b/mysql-test/t/innodb_bug39438.test
index 4dc3d957c39..2a51e5fcbb8 100644
--- a/mysql-test/t/innodb_bug39438.test
+++ b/mysql-test/t/innodb_bug39438.test
@@ -9,6 +9,10 @@
-- source include/have_innodb.inc
+--disable_query_log
+call mtr.add_suppression("InnoDB: Error: table 'test/bug39438'");
+--enable_query_log
+
SET storage_engine=InnoDB;
# we care only that the following SQL commands do not crash the server
diff --git a/mysql-test/t/innodb_bug44369.test b/mysql-test/t/innodb_bug44369.test
index 495059eb5e6..238dc3d8fb1 100644
--- a/mysql-test/t/innodb_bug44369.test
+++ b/mysql-test/t/innodb_bug44369.test
@@ -13,9 +13,9 @@ create table bug44369 (DB_ROW_ID int) engine=innodb;
--error ER_CANT_CREATE_TABLE
create table bug44369 (db_row_id int) engine=innodb;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table bug44369 (db_TRX_Id int) engine=innodb;
-show errors;
+show warnings;
diff --git a/mysql-test/t/innodb_bug46000.test b/mysql-test/t/innodb_bug46000.test
index 80c18c58ef0..eb10d866e54 100644
--- a/mysql-test/t/innodb_bug46000.test
+++ b/mysql-test/t/innodb_bug46000.test
@@ -14,7 +14,7 @@ create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
--error ER_CANT_CREATE_TABLE
create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
-show errors;
+show warnings;
create table bug46000(id int) engine=innodb;
@@ -24,7 +24,7 @@ create table bug46000(id int) engine=innodb;
create index GEN_CLUST_INDEX on bug46000(id);
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
-show errors;
+show warnings;
# This 'create index' operation should succeed, no
# temp table left from last failed create index
diff --git a/mysql-test/t/innodb_bug47777.test b/mysql-test/t/innodb_bug47777.test
new file mode 100644
index 00000000000..8f2985b2cf0
--- /dev/null
+++ b/mysql-test/t/innodb_bug47777.test
@@ -0,0 +1,24 @@
+# This is the test for bug 47777. GEOMETRY
+# data is treated as BLOB data in innodb.
+# Consequently, its key value generation/storing
+# should follow the process for the BLOB
+# datatype as well.
+
+--source include/have_innodb.inc
+
+create table bug47777(c2 linestring not null, primary key (c2(1))) engine=innodb;
+
+insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
+
+# Verify correct row get inserted.
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+
+# Update table bug47777 should be successful.
+update bug47777 set c2=GeomFromText('POINT(1 1)');
+
+# Verify the row get updated successfully. The original
+# c2 value should be changed to GeomFromText('POINT(1 1)').
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+
+drop table bug47777;
diff --git a/mysql-test/t/bug40113-master.opt b/mysql-test/t/innodb_lock_wait_timeout_1-master.opt
index 462f8fbe828..462f8fbe828 100644
--- a/mysql-test/t/bug40113-master.opt
+++ b/mysql-test/t/innodb_lock_wait_timeout_1-master.opt
diff --git a/mysql-test/t/innodb_lock_wait_timeout_1.test b/mysql-test/t/innodb_lock_wait_timeout_1.test
new file mode 100644
index 00000000000..e42e9f3e37c
--- /dev/null
+++ b/mysql-test/t/innodb_lock_wait_timeout_1.test
@@ -0,0 +1,230 @@
+--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
+
+--echo #
+--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
+--echo # FOR UPDATE
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int primary key auto_increment,
+ b int, index(b)) engine=innodb;
+insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+set autocommit=0;
+begin;
+select * from t1 where b=5 for update;
+connect (con1, localhost, root,,);
+connection con1;
+--error ER_LOCK_WAIT_TIMEOUT
+insert ignore into t1 (b) select a as b from t1;
+connection default;
+--echo # Cleanup
+--echo #
+disconnect con1;
+commit;
+set autocommit=default;
+drop table t1;
+
+--echo #
+--echo # Bug#41756 Strange error messages about locks from InnoDB
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+--echo # In the default transaction isolation mode, and/or with
+--echo # innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
+--echo # in InnoDB does nothing.
+--echo # Thus in order to reproduce the condition that led to the
+--echo # warning, one needs to relax isolation by either
+--echo # setting a weaker tx_isolation value, or by turning on
+--echo # the unsafe replication switch.
+--echo # For testing purposes, choose to tweak the isolation level,
+--echo # since it's settable at runtime, unlike
+--echo # innodb_locks_unsafe_for_binlog, which is
+--echo # only a command-line switch.
+--echo #
+set @@session.tx_isolation="read-committed";
+
+--echo # Prepare data. We need a table with a unique index,
+--echo # for join_read_key to be used. The other column
+--echo # allows to control what passes WHERE clause filter.
+create table t1 (a int primary key, b int) engine=innodb;
+--echo # Let's make sure t1 has sufficient amount of rows
+--echo # to exclude JT_ALL access method when reading it,
+--echo # i.e. make sure that JT_EQ_REF(a) is always preferred.
+insert into t1 values (1,1), (2,null), (3,1), (4,1),
+ (5,1), (6,1), (7,1), (8,1), (9,1), (10,1),
+ (11,1), (12,1), (13,1), (14,1), (15,1),
+ (16,1), (17,1), (18,1), (19,1), (20,1);
+--echo #
+--echo # Demonstrate that for the SELECT statement
+--echo # used later in the test JT_EQ_REF access method is used.
+--echo #
+--vertical_results
+explain
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+--horizontal_results
+--echo #
+--echo # Demonstrate that the reported SELECT statement
+--echo # no longer produces warnings.
+--echo #
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+commit;
+--echo #
+--echo # Demonstrate that due to lack of inter-sweep "reset" function,
+--echo # we keep some non-matching records locked, even though we know
+--echo # we could unlock them.
+--echo # To do that, show that if there is only one distinct value
+--echo # for a in t2 (a=2), we will keep record (2,null) in t1 locked.
+--echo # But if we add another value for "a" to t2, say 6,
+--echo # join_read_key cache will be pruned at least once,
+--echo # and thus record (2, null) in t1 will get unlocked.
+--echo #
+begin;
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+connect (con1,localhost,root,,);
+--echo #
+--echo # Switching to connection con1
+connection con1;
+--echo # We should be able to delete all records from t1 except (2, null),
+--echo # since they were not locked.
+begin;
+--echo # Delete in series of 3 records so that full scan
+--echo # is not used and we're not blocked on record (2,null)
+delete from t1 where a in (1,3,4);
+delete from t1 where a in (5,6,7);
+delete from t1 where a in (8,9,10);
+delete from t1 where a in (11,12,13);
+delete from t1 where a in (14,15,16);
+delete from t1 where a in (17,18);
+delete from t1 where a in (19,20);
+--echo #
+--echo # Record (2, null) is locked. This is actually unnecessary,
+--echo # because the previous select returned no rows.
+--echo # Just demonstrate the effect.
+--echo #
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1;
+rollback;
+--echo #
+--echo # Switching to connection default
+connection default;
+--echo #
+--echo # Show that the original contents of t1 is intact:
+select * from t1;
+commit;
+--echo #
+--echo # Have a one more record in t2 to show that
+--echo # if join_read_key cache is purned, the current
+--echo # row under the cursor is unlocked (provided, this row didn't
+--echo # match the partial WHERE clause, of course).
+--echo # Sic: the result of this test dependent on the order of retrieval
+--echo # of records --echo # from the derived table, if !
+--echo # We use DELETE to disable the JOIN CACHE. This DELETE modifies no
+--echo # records. It also should leave no InnoDB row locks.
+--echo #
+begin;
+delete t1.* from t1 natural join (select 2 as a, 2 as b union all
+ select 0 as a, 0 as b) as t2;
+--echo # Demonstrate that nothing was deleted form t1
+select * from t1;
+--echo #
+--echo # Switching to connection con1
+connection con1;
+begin;
+--echo # Since there is another distinct record in the derived table
+--echo # the previous matching record in t1 -- (2,null) -- was unlocked.
+delete from t1;
+--echo # We will need the contents of the table again.
+rollback;
+select * from t1;
+commit;
+--echo #
+--echo # Switching to connection default
+connection default;
+rollback;
+begin;
+--echo #
+--echo # Before this patch, we could wrongly unlock a record
+--echo # that was cached and later used in a join. Demonstrate that
+--echo # this is no longer the case.
+--echo # Sic: this test is also order-dependent (i.e. the
+--echo # the bug would show up only if the first record in the union
+--echo # is retreived and processed first.
+--echo #
+--echo # Verify that JT_EQ_REF is used.
+--vertical_results
+explain
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+ select 3 as a, 1 as b) as t2 for update;
+--horizontal_results
+--echo # Lock the record.
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+ select 3 as a, 1 as b) as t2 for update;
+--echo # Switching to connection con1
+connection con1;
+--echo #
+--echo # We should not be able to delete record (3,1) from t1,
+--echo # (previously it was possible).
+--echo #
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1 where a=3;
+--echo # Switching to connection default
+connection default;
+commit;
+
+disconnect con1;
+set @@session.tx_isolation=default;
+drop table t1;
+
+--echo #
+--echo # End of 5.1 tests
+--echo #
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index c643465b2f3..7055879ce1a 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -461,4 +461,33 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a;
DROP TABLE t1;
+--echo #
+--echo # Bug #47963: Wrong results when index is used
+--echo #
+CREATE TABLE t1(
+ a VARCHAR(5) NOT NULL,
+ b VARCHAR(5) NOT NULL,
+ c DATETIME NOT NULL,
+ KEY (c)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00');
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+DROP TABLE t1;
+
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 1cd05c8cb65..dbf36dedec8 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -730,6 +730,60 @@ SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
DROP TABLE IF EXISTS t1,t2;
+
+--echo #
+--echo # Bug #42116: Mysql crash on specific query
+--echo #
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+
+INSERT INTO t1 VALUES (1), (1), (1);
+
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+
+EXPLAIN
+SELECT *
+FROM
+ t1 JOIN t2 ON t1.a = t2.a
+ LEFT JOIN
+ (
+ (
+ t3 LEFT JOIN t4 ON t3.a = t4.a
+ )
+ LEFT JOIN
+ (
+ t5 LEFT JOIN t6 ON t5.a = t6.a
+ )
+ ON t4.a = t5.a
+ )
+ ON t1.a = t3.a;
+
+SELECT *
+FROM
+ t1 JOIN t2 ON t1.a = t2.a
+ LEFT JOIN
+ (
+ (
+ t3 LEFT JOIN t4 ON t3.a = t4.a
+ )
+ LEFT JOIN
+ (
+ t5 LEFT JOIN t6 ON t5.a = t6.a
+ )
+ ON t4.a = t5.a
+ )
+ ON t1.a = t3.a;
+
+DROP TABLE t1,t2,t3,t4,t5,t6;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 8ef668f542b..02b033df2e5 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -97,7 +97,7 @@ select ((@id := kill_id) - kill_id) from t3;
kill @id;
connection conn1;
--- error 1053,2013
+-- error 1317,2013
reap;
connection default;
diff --git a/mysql-test/t/locale.test b/mysql-test/t/locale.test
new file mode 100644
index 00000000000..7ceb49fd1f4
--- /dev/null
+++ b/mysql-test/t/locale.test
@@ -0,0 +1,18 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo Start of 5.4 tests
+--echo #
+--echo # Bug#43207 wrong LC_TIME names for romanian locale
+--echo #
+SET NAMES utf8;
+SET lc_time_names=ro_RO;
+SELECT DATE_FORMAT('2001-01-01', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-02', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-03', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-04', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-05', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-06', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-07', '%w %a %W');
+--echo End of 5.4 tests
diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test
index 878564c32ab..86d1e084c29 100644
--- a/mysql-test/t/lowercase_fs_off.test
+++ b/mysql-test/t/lowercase_fs_off.test
@@ -29,3 +29,65 @@ disconnect master;
connection default;
# End of 4.1 tests
+
+#
+# Bug#41049 does syntax "grant" case insensitive?
+#
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE T1(f1 INT);
+CREATE TABLE t1(f1 INT);
+GRANT SELECT ON T1 to user_1@localhost;
+
+connect (con1,localhost,user_1,,d1);
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from t1;
+select * from T1;
+connection default;
+GRANT SELECT ON t1 to user_1@localhost;
+connection con1;
+select * from information_schema.table_privileges;
+connection default;
+disconnect con1;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+DROP USER user_1@localhost;
+DROP DATABASE d1;
+USE test;
+
+CREATE DATABASE db1;
+USE db1;
+CREATE PROCEDURE p1() BEGIN END;
+CREATE FUNCTION f1(i INT) RETURNS INT RETURN i+1;
+
+GRANT USAGE ON db1.* to user_1@localhost;
+GRANT EXECUTE ON PROCEDURE db1.P1 to user_1@localhost;
+GRANT EXECUTE ON FUNCTION db1.f1 to user_1@localhost;
+GRANT UPDATE ON db1.* to USER_1@localhost;
+
+connect (con1,localhost,user_1,,db1);
+call p1();
+call P1();
+select f1(1);
+connect (con2,localhost,USER_1,,db1);
+--error ER_PROCACCESS_DENIED_ERROR
+call p1();
+--error ER_PROCACCESS_DENIED_ERROR
+call P1();
+--error ER_PROCACCESS_DENIED_ERROR
+select f1(1);
+
+connection default;
+disconnect con1;
+disconnect con2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP FUNCTION f1;
+DROP PROCEDURE p1;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index e4ea939f348..56fe103adc9 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1539,14 +1539,14 @@ INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
REPAIR TABLE t1;
-# !!! Disabled until additional fix for BUG#47073 is pushed.
-#SET myisam_repair_threads=2;
+SET myisam_repair_threads=2;
# May report different values depending on threads activity.
-#--replace_regex /changed from [0-9]+/changed from #/
-#REPAIR TABLE t1;
-#SET myisam_repair_threads=@@global.myisam_repair_threads;
-
+--disable_result_log
+REPAIR TABLE t1;
+--enable_result_log
+SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+CHECK TABLE t1;
DROP TABLE t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/myisam_crash_before_flush_keys.test b/mysql-test/t/myisam_crash_before_flush_keys.test
index d6559f7760d..1860ddd27e3 100644
--- a/mysql-test/t/myisam_crash_before_flush_keys.test
+++ b/mysql-test/t/myisam_crash_before_flush_keys.test
@@ -26,12 +26,6 @@ SET SESSION debug="d,crash_before_flush_keys";
--error 2013
FLUSH TABLE t1;
---echo # Run MYISAMCHK tool to check the table t1 and repair
---replace_result $MYISAMCHK MYISAMCHK $MYSQLD_DATADIR MYSQLD_DATADIR
---error 255
---exec $MYISAMCHK -cs $MYSQLD_DATADIR/test/t1 2>&1
---exec $MYISAMCHK -rs $MYSQLD_DATADIR/test/t1
-
--echo # Write file to make mysql-test-run.pl start the server
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@@ -42,8 +36,6 @@ FLUSH TABLE t1;
--echo # it to be back online again
--source include/wait_until_connected_again.inc
-SHOW CREATE TABLE t1;
-
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-
+# Must report that the table wasn't closed properly
+CHECK TABLE t1;
DROP TABLE t1;
diff --git a/mysql-test/t/named_pipe.test b/mysql-test/t/named_pipe.test
index e3dfd24bb52..e88fd8e1ef8 100644
--- a/mysql-test/t/named_pipe.test
+++ b/mysql-test/t/named_pipe.test
@@ -9,6 +9,11 @@ if (`SELECT '$nmp' != 'ON'`){
skip No named pipe support;
}
+# Connect using named pipe for testing
+connect(pipe_con,localhost,root,,,,,PIPE);
+
# Source select test case
-- source include/common-tests.inc
+connection default;
+disconnect pipe_con;
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
index d1e40024733..8f672af40a3 100644
--- a/mysql-test/t/olap.test
+++ b/mysql-test/t/olap.test
@@ -375,4 +375,19 @@ INSERT INTO t1 VALUES(0);
SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
DROP TABLE t1;
+--echo #
+--echo # Bug #48131: crash group by with rollup, distinct,
+--echo # filesort, with temporary tables
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 7841e7274dd..0edc9cca385 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -1294,7 +1294,7 @@ SET GLOBAL query_cache_size= default;
# Bug #31157: Crash when select+order by the avg of some field within the
# group by
#
-
+SET GLOBAL query_cache_size=1024*1024*512;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
@@ -1305,6 +1305,7 @@ INSERT INTO t1 SET a = 'aaaa';
SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
+SET GLOBAL query_cache_size= default;
--echo End of 5.1 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index dc119b6a77e..3a845471cd0 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1171,3 +1171,93 @@ a < 5 OR
a < 10;
DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+--echo #
+
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+--echo #
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+
+--echo # Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+ ('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+ ('2009-09-23 12:00:00');
+
+--echo # DATE vs DATE
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+SELECT * FROM t1 WHERE a >= '20090923';
+SELECT * FROM t1 WHERE a >= 20090923;
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+
+--echo # DATE vs DATETIME
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '20090923';
+SELECT * FROM t2 WHERE a >= 20090923;
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+
+--echo # DATETIME vs DATETIME
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+SELECT * FROM t2 WHERE a >= '20090923120000';
+SELECT * FROM t2 WHERE a >= 20090923120000;
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+
+--echo # DATETIME vs DATE
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '20090923000000';
+SELECT * FROM t1 WHERE a >= 20090923000000;
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+
+--echo # Test of the new get_date_from_str implementation
+--echo # Behavior differs slightly between the trunk and mysql-pe.
+--echo # The former may give errors for the truncated values, while the latter
+--echo # gives warnings. The purpose of this test is not to interfere, and only
+--echo # preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+ str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+ str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+
+SELECT str_to_date('', '%Y-%m-%d');
+
+DROP TABLE t1, t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 7d3785ecccc..51f0cd73374 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3739,7 +3739,40 @@ EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+--echo # forcing a spatial index
+--echo #
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug #48291 : crash with row() operator,select into @var, and
+--echo # subquery returning multiple rows
+--echo #
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+
+--echo # Should not crash
+--error ER_SUBQUERY_NO_1_ROW
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test
new file mode 100644
index 00000000000..7b94e65a5e9
--- /dev/null
+++ b/mysql-test/t/sp-bugs.test
@@ -0,0 +1,61 @@
+# Test file for stored procedure bugfixes
+
+--echo #
+--echo # Bug #47412: Valgrind warnings / user can read uninitalized memory
+--echo # using SP variables
+--echo #
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+SELECT f2 ();
+
+DROP SCHEMA testdb;
+
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 63b92451a65..f61088086b9 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -2431,3 +2431,27 @@ SELECT AVG (a) FROM t1 WHERE b = 999999;
--error ER_SP_DOES_NOT_EXIST
SELECT non_existent (a) FROM t1 WHERE b = 999999;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
+--echo # SP + MERGE + ALTER
+--echo #
+
+CREATE TABLE t1 (pk INT, b INT, KEY (b));
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a;
+
+--error ER_NON_UPDATABLE_TABLE
+CALL p1(5);
+
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+
+--error ER_VIEW_INVALID
+CALL p1(7);
+
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 544017ebb97..7f2dba00ba8 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -30,7 +30,7 @@ SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
-- error ER_WRONG_USAGE
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
--- error ER_WRONG_USAGE
+-- error ER_WRONG_PARAMETERS_TO_PROCEDURE
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -3544,4 +3544,19 @@ where v in(select v
where t1.g=t2.g) is unknown;
drop table t1, t2;
+#
+# Bug #31157: Crash when select+order by the avg of some field within the
+# group by
+#
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+ (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 7a2a9f328ef..fab0a462157 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -728,3 +728,69 @@ where
from t4, t5 limit 2));
drop table t0, t1, t2, t3, t4, t5;
+
+--echo #
+--echo # BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+--echo # values return too many records
+--echo #
+
+CREATE TABLE t1 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+
+CREATE TABLE t2 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+--echo
+--echo Data in t1
+SELECT i1, i2 FROM t1;
+
+--echo
+--echo Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Check that the subquery only has to be evaluated once
+--echo # for all-NULL values even though there are two (NULL,NULL) records
+--echo # Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+--echo
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Handler_read_rnd_next should be one more than baseline
+--echo # (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+
+DROP TABLE t1,t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 65bafaae77e..cd3c3f81510 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1286,137 +1286,3 @@ CREATE TABLE t1 SELECT 1 % .1234567891234567891234567891234567891234567891234567
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
-
---echo #
---echo # Bug#45261: Crash, stored procedure + decimal
---echo #
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- .100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- .123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
---echo # Test that the integer and decimal parts are properly calculated.
---echo #
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
---echo #
---echo # Test that variables get maximum precision.
---echo #
-
-SET @decimal= 1.1;
-CREATE TABLE t1 SELECT @decimal AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 7d56df259ba..02e8763a630 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -452,3 +452,18 @@ DROP TABLE t1;
DROP FUNCTION f1;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug #47919 assert in open_table during ALTER temporary table
+--echo #
+
+CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
+CREATE TEMPORARY TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+ALTER TABLE t2 COMMENT = 'ABC';
+UPDATE t2, t1 SET t2.f1 = 2, t1.f1 = 9;
+ALTER TABLE t2 COMMENT = 'DEF';
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 2ad488b7529..175468db702 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -1506,3 +1506,29 @@ DROP VIEW v1;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+--echo #
+--echo # Bug #46019: ERROR 1356 When selecting from within another
+--echo # view that has Group By
+--echo #
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+
+CREATE TABLE t1 (a INT);
+
+CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT a FROM t1 GROUP BY a;
+CREATE SQL SECURITY INVOKER VIEW v2 AS SELECT a FROM v1;
+
+CREATE USER mysqluser1;
+
+GRANT SELECT ON TABLE t1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO mysqluser1;
+
+--connect (mysqluser1, localhost, mysqluser1,,mysqltest1)
+SELECT a FROM v1;
+SELECT a FROM v2;
+
+--connection default
+--disconnect mysqluser1
+DROP USER mysqluser1;
+DROP DATABASE mysqltest1;
diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test
index 7b1c6a268d5..f84d822170f 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -149,6 +149,68 @@ xa end 'a';
xa prepare 'a';
xa commit 'a';
+#
+# BUG#43171 - Assertion failed: thd->transaction.xid_state.xid.is_null()
+#
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+connect(con1,localhost,root,,);
+
+# Part 1: Prepare to test XA START after regular transaction deadlock
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+
+connection default;
+BEGIN;
+UPDATE t1 SET a=4 WHERE a=2;
+
+connection con1;
+let $conn_id= `SELECT CONNECTION_ID()`;
+SEND UPDATE t1 SET a=5 WHERE a=2;
+
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID=$conn_id AND STATE='Searching rows for update';
+--source include/wait_condition.inc
+
+--error ER_LOCK_DEADLOCK
+UPDATE t1 SET a=5 WHERE a=1;
+ROLLBACK;
+
+# Part 2: Prepare to test XA START after XA transaction deadlock
+connection con1;
+REAP;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+
+connection default;
+XA START 'xid1';
+UPDATE t1 SET a=4 WHERE a=2;
+
+connection con1;
+SEND UPDATE t1 SET a=5 WHERE a=2;
+
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID=$conn_id AND STATE='Searching rows for update';
+--source include/wait_condition.inc
+
+--error ER_LOCK_DEADLOCK
+UPDATE t1 SET a=5 WHERE a=1;
+--error ER_XA_RBDEADLOCK
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+
+XA START 'xid1';
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+
+disconnect con1;
+DROP TABLE t1;
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 22b1216f99c..f444e0f0c94 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -1041,9 +1041,11 @@ static void init_one_value(const struct my_option *option, uchar* *variable,
*((longlong*) variable)= (longlong) getopt_ll_limit_value((longlong) value, option, NULL);
break;
case GET_ULL:
- case GET_SET:
*((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL);
break;
+ case GET_SET:
+ *((ulonglong*) variable)= (ulonglong) value;
+ break;
case GET_DOUBLE:
*((double*) variable)= (double) value;
break;
diff --git a/mysys/typelib.c b/mysys/typelib.c
index 92ffe9316ff..a0fe8a96a89 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -182,7 +182,10 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
{
(*err)++;
i= x;
- while (*x && *x != field_separator) x++;
+ while (*x && *x != field_separator)
+ x++;
+ if (x[0] && x[1]) // skip separator if found
+ x++;
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
DBUG_RETURN(0);
result|= (ULL(1) << find);
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 1d7e80658fd..a81c0964fdd 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint sign
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
-CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
-- Create general_log if CSV is enabled.
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 6f5e385f87d..3ebfc4b1941 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -337,6 +337,10 @@ ALTER TABLE procs_priv
MODIFY Proc_priv set('Execute','Alter Routine','Grant')
COLLATE utf8_general_ci DEFAULT '' NOT NULL;
+ALTER IGNORE TABLE procs_priv
+ MODIFY Routine_name char(64)
+ COLLATE utf8_general_ci DEFAULT '' NOT NULL;
+
ALTER TABLE procs_priv
ADD Routine_type enum('FUNCTION','PROCEDURE')
COLLATE utf8_general_ci NOT NULL AFTER Routine_name;
diff --git a/sql-common/client.c b/sql-common/client.c
index cbed3a5e2a8..a4a2e518edf 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -389,7 +389,7 @@ HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
0,
NULL,
OPEN_EXISTING,
- 0,
+ FILE_FLAG_OVERLAPPED,
NULL )) != INVALID_HANDLE_VALUE)
break;
if (GetLastError() != ERROR_PIPE_BUSY)
@@ -623,7 +623,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
err2:
if (error_allow == 0)
{
- net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
+ net->vio= vio_new_win32shared_memory(handle_file_map,handle_map,
event_server_wrote,
event_server_read,event_client_wrote,
event_client_read,event_conn_closed);
@@ -2030,7 +2030,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
}
else
{
- net->vio=vio_new_win32pipe(hPipe);
+ net->vio= vio_new_win32pipe(hPipe);
my_snprintf(host_info=buff, sizeof(buff)-1,
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
}
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index dba32cac6b2..f2ec0e8cf64 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1433,7 +1433,7 @@ Event_job_data::execute(THD *thd, bool drop)
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
{
- Parser_state parser_state(thd, thd->query, thd->query_length);
+ Parser_state parser_state(thd, thd->query(), thd->query_length());
lex_start(thd);
if (parse_sql(thd, & parser_state, creation_ctx))
diff --git a/sql/events.cc b/sql/events.cc
index 34da0e185b7..458ad61718d 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -465,7 +465,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
if (!dropped)
{
/* Binlog the create event. */
- DBUG_ASSERT(thd->query && thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
String log_query;
if (create_query_string(thd, &log_query))
{
@@ -595,8 +595,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
event_queue->update_event(thd, parse_data->dbname, parse_data->name,
new_element);
/* Binlog the alter event. */
- DBUG_ASSERT(thd->query && thd->query_length);
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
@@ -670,8 +670,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (event_queue)
event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */
- DBUG_ASSERT(thd->query && thd->query_length);
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
pthread_mutex_unlock(&LOCK_event_metadata);
DBUG_RETURN(ret);
diff --git a/sql/field.cc b/sql/field.cc
index 0df9b0fc2e4..354c911e1c0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2480,97 +2480,12 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
{
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
- DBUG_ASSERT(precision >= dec);
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
(dec <= DECIMAL_MAX_SCALE));
bin_size= my_decimal_get_binary_size(precision, dec);
}
-/**
- Create a field to hold a decimal value from an item.
-
- @remark The MySQL DECIMAL data type has a characteristic that needs to be
- taken into account when deducing the type from a Item_decimal.
-
- But first, let's briefly recap what is the new MySQL DECIMAL type:
-
- The declaration syntax for a decimal is DECIMAL(M,D), where:
-
- * M is the maximum number of digits (the precision).
- It has a range of 1 to 65.
- * D is the number of digits to the right of the decimal separator (the scale).
- It has a range of 0 to 30 and must be no larger than M.
-
- D and M are used to determine the storage requirements for the integer
- and fractional parts of each value. The integer part is to the left of
- the decimal separator and to the right is the fractional part. Hence:
-
- M is the number of digits for the integer and fractional part.
- D is the number of digits for the fractional part.
-
- Consequently, M - D is the number of digits for the integer part. For
- example, a DECIMAL(20,10) column has ten digits on either side of
- the decimal separator.
-
- The characteristic that needs to be taken into account is that the
- backing type for Item_decimal is a my_decimal that has a higher
- precision (DECIMAL_MAX_POSSIBLE_PRECISION, see my_decimal.h) than
- DECIMAL.
-
- Drawing a comparison between my_decimal and DECIMAL:
-
- * M has a range of 1 to 81.
- * D has a range of 0 to 81.
-
- There can be a difference in range if the decimal contains a integer
- part. This is because the fractional part must always be on a group
- boundary, leaving at least one group for the integer part. Since each
- group is 9 (DIG_PER_DEC1) digits and there are 9 (DECIMAL_BUFF_LENGTH)
- groups, the fractional part is limited to 72 digits if there is at
- least one digit in the integral part.
-
- Although the backing type for a DECIMAL is also my_decimal, every
- time a my_decimal is stored in a DECIMAL field, the precision and
- scale are explicitly capped at 65 (DECIMAL_MAX_PRECISION) and 30
- (DECIMAL_MAX_SCALE) digits, following my_decimal truncation procedure
- (FIX_INTG_FRAC_ERROR).
-*/
-
-Field_new_decimal *
-Field_new_decimal::new_decimal_field(const Item *item)
-{
- uint32 len;
- uint intg= item->decimal_int_part(), scale= item->decimals;
-
- DBUG_ASSERT(item->decimal_precision() >= item->decimals);
-
- /*
- Employ a procedure along the lines of the my_decimal truncation process:
- - If the integer part is equal to or bigger than the maximum precision:
- Truncate integer part to fit and the fractional becomes zero.
- - Otherwise:
- Truncate fractional part to fit.
- */
- if (intg >= DECIMAL_MAX_PRECISION)
- {
- intg= DECIMAL_MAX_PRECISION;
- scale= 0;
- }
- else
- {
- uint room= min(DECIMAL_MAX_PRECISION - intg, DECIMAL_MAX_SCALE);
- if (scale > room)
- scale= room;
- }
-
- len= my_decimal_precision_to_length(intg + scale, scale, item->unsigned_flag);
-
- return new Field_new_decimal(len, item->maybe_null, item->name, scale,
- item->unsigned_flag);
-}
-
-
int Field_new_decimal::reset(void)
{
store_value(&decimal_zero);
@@ -6550,20 +6465,9 @@ uint Field::is_equal(Create_field *new_field)
}
-/* If one of the fields is binary and the other one isn't return 1 else 0 */
-
-bool Field_str::compare_str_field_flags(Create_field *new_field, uint32 flag_arg)
-{
- return (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
- !(flag_arg & (BINCMP_FLAG | BINARY_FLAG))) ||
- (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
- (flag_arg & (BINCMP_FLAG | BINARY_FLAG))));
-}
-
-
uint Field_str::is_equal(Create_field *new_field)
{
- if (compare_str_field_flags(new_field, flags))
+ if (field_flags_are_binary() != new_field->field_flags_are_binary())
return 0;
return ((new_field->sql_type == real_type()) &&
@@ -8329,7 +8233,7 @@ uint Field_blob::max_packed_col_length(uint max_length)
uint Field_blob::is_equal(Create_field *new_field)
{
- if (compare_str_field_flags(new_field, flags))
+ if (field_flags_are_binary() != new_field->field_flags_are_binary())
return 0;
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
@@ -8889,7 +8793,7 @@ uint Field_enum::is_equal(Create_field *new_field)
The fields are compatible if they have the same flags,
type, charset and have the same underlying length.
*/
- if (compare_str_field_flags(new_field, flags) ||
+ if (new_field->field_flags_are_binary() != field_flags_are_binary() ||
new_field->sql_type != real_type() ||
new_field->charset != field_charset ||
new_field->pack_length != pack_length())
@@ -9658,7 +9562,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
if (length == 0)
- fld_length= 0; /* purecov: inspected */
+ fld_length= NULL; /* purecov: inspected */
}
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
@@ -9810,8 +9714,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
case MYSQL_TYPE_TIMESTAMP:
if (fld_length == NULL)
{
- /* Compressed date YYYYMMDDHHMMSS */
- length= MAX_DATETIME_COMPRESSED_WIDTH;
+ length= MAX_DATETIME_WIDTH;
}
else if (length != MAX_DATETIME_WIDTH)
{
@@ -9876,7 +9779,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
sql_type= MYSQL_TYPE_NEWDATE;
/* fall trough */
case MYSQL_TYPE_NEWDATE:
- length= 10;
+ length= MAX_DATE_WIDTH;
break;
case MYSQL_TYPE_TIME:
length= 10;
@@ -9957,6 +9860,17 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
DBUG_RETURN(TRUE);
}
+ switch (fld_type) {
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ charset= &my_charset_bin;
+ flags|= BINCMP_FLAG;
+ default: break;
+ }
+
DBUG_RETURN(FALSE); /* success */
}
diff --git a/sql/field.h b/sql/field.h
index 51397cad7b1..18b017516a7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,7 +1,7 @@
#ifndef FIELD_INCLUDED
#define FIELD_INCLUDED
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -613,15 +613,17 @@ protected:
handle_int64(to, from, low_byte_first_from, table->s->db_low_byte_first);
return from + sizeof(int64);
}
+
+ bool field_flags_are_binary()
+ {
+ return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+ }
+
};
class Field_num :public Field {
public:
- /**
- The scale of the Field's value, i.e. the number of digits to the right
- of the decimal point.
- */
const uint8 dec;
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
@@ -672,7 +674,6 @@ public:
friend class Create_field;
my_decimal *val_decimal(my_decimal *);
virtual bool str_needs_quotes() { return TRUE; }
- bool compare_str_field_flags(Create_field *new_field, uint32 flags);
uint is_equal(Create_field *new_field);
};
@@ -780,11 +781,6 @@ public:
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
const char *field_name_arg, uint8 dec_arg,
bool unsigned_arg);
- /*
- Create a field to hold a decimal value from an item.
- Truncates the precision and/or scale if necessary.
- */
- static Field_new_decimal *new_decimal_field(const Item *item);
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
Item_result result_type () const { return DECIMAL_RESULT; }
@@ -1287,12 +1283,12 @@ public:
Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{}
Field_date(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
+ :Field_str((uchar*) 0, MAX_DATE_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
@@ -1402,12 +1398,12 @@ public:
Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{}
Field_datetime(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str((uchar*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
+ :Field_str((uchar*) 0, MAX_DATETIME_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
#ifdef HAVE_LONG_LONG
@@ -2079,6 +2075,11 @@ public:
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type);
+
+ bool field_flags_are_binary()
+ {
+ return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+ }
};
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index dfd7ddc4d6c..9fdb8b628ca 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -5525,7 +5525,7 @@ int ha_ndbcluster::create(const char *name,
if (share && !do_event_op)
share->flags|= NSF_NO_BINLOG;
ndbcluster_log_schema_op(thd, share,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
share->db, share->table_name,
m_table->getObjectId(),
m_table->getObjectVersion(),
@@ -5967,7 +5967,8 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
*/
if (!is_old_table_tmpfile)
ndbcluster_log_schema_op(current_thd, share,
- current_thd->query, current_thd->query_length,
+ current_thd->query(),
+ current_thd->query_length(),
old_dbname, m_tabname,
ndb_table_id, ndb_table_version,
SOT_RENAME_TABLE,
@@ -6162,7 +6163,7 @@ retry_temporary_error1:
current_thd->lex->sql_command != SQLCOM_TRUNCATE)
{
ndbcluster_log_schema_op(thd, share,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
share->db, share->table_name,
ndb_table_id, ndb_table_version,
SOT_DROP_TABLE, 0, 0, 1);
@@ -6884,7 +6885,7 @@ static void ndbcluster_drop_database(handlerton *hton, char *path)
THD *thd= current_thd;
ha_ndbcluster::set_dbname(path, db);
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, "", 0, 0, SOT_DROP_DB, 0, 0, 0);
#endif
DBUG_VOID_RETURN;
@@ -10251,13 +10252,13 @@ int ndbcluster_alter_tablespace(handlerton *hton,
#ifdef HAVE_NDB_BINLOG
if (is_tablespace)
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
"", alter_info->tablespace_name,
0, 0,
SOT_TABLESPACE, 0, 0, 0);
else
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
"", alter_info->logfile_group_name,
0, 0,
SOT_LOGFILE_GROUP, 0, 0, 0);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 2a87697c7fa..27af3f2cf2f 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -241,8 +241,8 @@ static void dbug_print_table(const char *info, TABLE *table)
static void run_query(THD *thd, char *buf, char *end,
const int *no_print_error, my_bool disable_binlog)
{
- ulong save_thd_query_length= thd->query_length;
- char *save_thd_query= thd->query;
+ ulong save_thd_query_length= thd->query_length();
+ char *save_thd_query= thd->query();
ulong save_thread_id= thd->variables.pseudo_thread_id;
struct system_status_var save_thd_status_var= thd->status_var;
THD_TRANS save_thd_transaction_all= thd->transaction.all;
@@ -259,12 +259,12 @@ static void run_query(THD *thd, char *buf, char *end,
if (disable_binlog)
thd->options&= ~OPTION_BIN_LOG;
- DBUG_PRINT("query", ("%s", thd->query));
+ DBUG_PRINT("query", ("%s", thd->query()));
DBUG_ASSERT(!thd->in_sub_stmt);
DBUG_ASSERT(!thd->prelocked_mode);
- mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
if (no_print_error && thd->is_slave_error)
{
diff --git a/sql/handler.cc b/sql/handler.cc
index 0a7ea682313..2414ba64196 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1331,7 +1331,8 @@ int ha_rollback_trans(THD *thd, bool all)
}
trans->ha_list= 0;
trans->no_2pc=0;
- if (is_real_trans && thd->transaction_rollback_request)
+ if (is_real_trans && thd->transaction_rollback_request &&
+ thd->transaction.xid_state.xa_state != XA_NOTR)
thd->transaction.xid_state.rm_error= thd->main_da.sql_errno();
if (all)
thd->variables.tx_isolation=thd->session_tx_isolation;
diff --git a/sql/handler.h b/sql/handler.h
index 577b239fba1..4fe38b659bb 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -408,7 +408,6 @@ struct xid_t {
my_xid get_my_xid()
{
return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
- !memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) &&
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
quick_get_my_xid() : 0;
}
diff --git a/sql/item.cc b/sql/item.cc
index 86e4551e55b..8f487872f1b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -435,26 +435,17 @@ Item::Item(THD *thd, Item *item):
}
-/**
- Decimal precision of the item.
-
- @remark The precision must not be capped as it can be used in conjunction
- with Item::decimals to determine the size of the integer part when
- constructing a decimal data type.
-
- @see Item::decimal_int_part()
- @see Item::decimals
-*/
-
uint Item::decimal_precision() const
{
- uint precision= max_length;
Item_result restype= result_type();
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
- precision= my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
-
- return precision;
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+ return min(prec, DECIMAL_MAX_PRECISION);
+ }
+ return min(max_length, DECIMAL_MAX_PRECISION);
}
@@ -4908,7 +4899,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
switch (field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- field= Field_new_decimal::new_decimal_field(this);
+ field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
+ Field::NONE, name, decimals, 0,
+ unsigned_flag);
break;
case MYSQL_TYPE_TINY:
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@@ -6866,52 +6859,61 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
}
/**
- Compare the value stored in field, with the original item.
+ Compare the value stored in field with the expression from the query.
- @param field field which the item is converted and stored in
- @param item original item
+ @param field Field which the Item is stored in after conversion
+ @param item Original expression from query
- @return Return an integer greater than, equal to, or less than 0 if
- the value stored in the field is greater than, equal to,
- or less than the original item
+ @return Returns an integer greater than, equal to, or less than 0 if
+ the value stored in the field is greater than, equal to,
+ or less than the original Item. A 0 may also be returned if
+ out of memory.
@note We only use this on the range optimizer/partition pruning,
because in some cases we can't store the value in the field
without some precision/character loss.
*/
-int stored_field_cmp_to_item(Field *field, Item *item)
+int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
{
-
Item_result res_type=item_cmp_type(field->result_type(),
item->result_type());
if (res_type == STRING_RESULT)
{
char item_buff[MAX_FIELD_WIDTH];
char field_buff[MAX_FIELD_WIDTH];
- String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin),*item_result;
+
+ String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin);
String field_tmp(field_buff,sizeof(field_buff),&my_charset_bin);
- enum_field_types field_type;
- item_result=item->val_str(&item_tmp);
+ String *item_result= item->val_str(&item_tmp);
+ /*
+ Some implementations of Item::val_str(String*) actually modify
+ the field Item::null_value, hence we can't check it earlier.
+ */
if (item->null_value)
return 0;
- field->val_str(&field_tmp);
+ String *field_result= field->val_str(&field_tmp);
- /*
- If comparing DATE with DATETIME, append the time-part to the DATE.
- So that the strings are equally formatted.
- A DATE converted to string is 10 characters, and a DATETIME converted
- to string is 19 characters.
- */
- field_type= field->type();
- if (field_type == MYSQL_TYPE_DATE &&
- item_result->length() == 19)
- field_tmp.append(" 00:00:00");
- else if (field_type == MYSQL_TYPE_DATETIME &&
- item_result->length() == 10)
- item_result->append(" 00:00:00");
-
- return stringcmp(&field_tmp,item_result);
+ enum_field_types field_type= field->type();
+
+ if (field_type == MYSQL_TYPE_DATE || field_type == MYSQL_TYPE_DATETIME)
+ {
+ enum_mysql_timestamp_type type= MYSQL_TIMESTAMP_ERROR;
+
+ if (field_type == MYSQL_TYPE_DATE)
+ type= MYSQL_TIMESTAMP_DATE;
+
+ if (field_type == MYSQL_TYPE_DATETIME)
+ type= MYSQL_TIMESTAMP_DATETIME;
+
+ const char *field_name= field->field_name;
+ MYSQL_TIME field_time, item_time;
+ get_mysql_time_from_str(thd, field_result, type, field_name, &field_time);
+ get_mysql_time_from_str(thd, item_result, type, field_name, &item_time);
+
+ return my_time_compare(&field_time, &item_time);
+ }
+ return stringcmp(field_result, item_result);
}
if (res_type == INT_RESULT)
return 0; // Both are of type int
diff --git a/sql/item.h b/sql/item.h
index b44e84f4b15..e83634843be 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -765,10 +765,9 @@ public:
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
- /** Returns the uncapped decimal precision of this item. */
virtual uint decimal_precision() const;
inline int decimal_int_part() const
- { return decimal_precision() - decimals; }
+ { return my_decimal_int_part(decimal_precision(), decimals); }
/*
Returns true if this is constant (during query execution, i.e. its value
will not change until next fix_fields) and its value is known.
@@ -3128,6 +3127,6 @@ void mark_select_range_as_dependent(THD *thd,
extern Cached_item *new_Cached_item(THD *thd, Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
-extern int stored_field_cmp_to_item(Field *field, Item *item);
-
+extern int stored_field_cmp_to_item(THD *thd, Field *field, Item *item);
#endif /* ITEM_INCLUDED */
+
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c29031d25b5..c6b88cd8188 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -636,56 +636,51 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
return 0;
}
-
/**
- @brief Convert date provided in a string to the int representation.
-
- @param[in] thd thread handle
- @param[in] str a string to convert
- @param[in] warn_type type of the timestamp for issuing the warning
- @param[in] warn_name field name for issuing the warning
- @param[out] error_arg could not extract a DATE or DATETIME
-
- @details Convert date provided in the string str to the int
- representation. If the string contains wrong date or doesn't
- contain it at all then a warning is issued. The warn_type and
- the warn_name arguments are used as the name and the type of the
- field when issuing the warning. If any input was discarded
- (trailing or non-timestampy characters), was_cut will be non-zero.
- was_type will return the type str_to_datetime() could correctly
- extract.
-
- @return
- converted value. 0 on error and on zero-dates -- check 'failure'
+ Parse date provided in a string to a MYSQL_TIME.
+
+ @param[in] thd Thread handle
+ @param[in] str A string to convert
+ @param[in] warn_type Type of the timestamp for issuing the warning
+ @param[in] warn_name Field name for issuing the warning
+ @param[out] l_time The MYSQL_TIME objects is initialized.
+
+ Parses a date provided in the string str into a MYSQL_TIME object. If the
+ string contains an incorrect date or doesn't correspond to a date at all
+ then a warning is issued. The warn_type and the warn_name arguments are used
+ as the name and the type of the field when issuing the warning. If any input
+ was discarded (trailing or non-timestamp-y characters), return value will be
+ TRUE.
+
+ @return Status flag
+ @retval FALSE Success.
+ @retval True Indicates failure.
*/
-static ulonglong
-get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
- char *warn_name, bool *error_arg)
+bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
+ const char *warn_name, MYSQL_TIME *l_time)
{
- ulonglong value= 0;
+ bool value;
int error;
- MYSQL_TIME l_time;
- enum_mysql_timestamp_type ret;
+ enum_mysql_timestamp_type timestamp_type;
- ret= str_to_datetime(str->ptr(), str->length(), &l_time,
- (TIME_FUZZY_DATE | MODE_INVALID_DATES |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
- &error);
+ timestamp_type=
+ str_to_datetime(str->ptr(), str->length(), l_time,
+ (TIME_FUZZY_DATE | MODE_INVALID_DATES |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
+ &error);
- if (ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE)
- {
+ if (timestamp_type == MYSQL_TIMESTAMP_DATETIME ||
+ timestamp_type == MYSQL_TIMESTAMP_DATE)
/*
Do not return yet, we may still want to throw a "trailing garbage"
warning.
*/
- *error_arg= FALSE;
- value= TIME_to_ulonglong_datetime(&l_time);
- }
+ value= FALSE;
else
{
- *error_arg= TRUE;
+ value= TRUE;
error= 1; /* force warning */
}
@@ -698,6 +693,37 @@ get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
}
+/**
+ @brief Convert date provided in a string to the int representation.
+
+ @param[in] thd thread handle
+ @param[in] str a string to convert
+ @param[in] warn_type type of the timestamp for issuing the warning
+ @param[in] warn_name field name for issuing the warning
+ @param[out] error_arg could not extract a DATE or DATETIME
+
+ @details Convert date provided in the string str to the int
+ representation. If the string contains wrong date or doesn't
+ contain it at all then a warning is issued. The warn_type and
+ the warn_name arguments are used as the name and the type of the
+ field when issuing the warning.
+
+ @return
+ converted value. 0 on error and on zero-dates -- check 'failure'
+*/
+static ulonglong get_date_from_str(THD *thd, String *str,
+ timestamp_type warn_type,
+ const char *warn_name, bool *error_arg)
+{
+ MYSQL_TIME l_time;
+ *error_arg= get_mysql_time_from_str(thd, str, warn_type, warn_name, &l_time);
+
+ if (*error_arg)
+ return 0;
+ return TIME_to_ulonglong_datetime(&l_time);
+}
+
+
/*
Check whether compare_datetime() can be used to compare items.
@@ -1559,61 +1585,73 @@ longlong Item_in_optimizer::val_int()
if (cache->null_value)
{
+ /*
+ We're evaluating
+ "<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)"
+ where one or more of the outer values is NULL.
+ */
if (((Item_in_subselect*)args[1])->is_top_level_item())
{
/*
- We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
- FALSE, and we can return one instead of another. Just return NULL.
+ We're evaluating a top level item, e.g.
+ "<outer_value_list> IN (SELECT <inner_value_list>...)",
+ and in this case a NULL value in the outer_value_list means
+ that the result shall be NULL/FALSE (makes no difference for
+ top level items). The cached value is NULL, so just return
+ NULL.
*/
null_value= 1;
}
else
{
- if (!((Item_in_subselect*)args[1])->is_correlated &&
- result_for_null_param != UNKNOWN)
+ /*
+ We're evaluating an item where a NULL value in either the
+ outer or inner value list does not automatically mean that we
+ can return NULL/FALSE. An example of such a query is
+ "<outer_value_list> NOT IN (SELECT <inner_value_list>...)"
+ The result when there is at least one NULL value is: NULL if the
+ SELECT evaluated over the non-NULL values produces at least
+ one row, FALSE otherwise
+ */
+ Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
+ bool all_left_cols_null= true;
+ const uint ncols= cache->cols();
+
+ /*
+ Turn off the predicates that are based on column compares for
+ which the left part is currently NULL
+ */
+ for (uint i= 0; i < ncols; i++)
{
- /* Use cached value from previous execution */
- null_value= result_for_null_param;
+ if (cache->element_index(i)->null_value)
+ item_subs->set_cond_guard_var(i, FALSE);
+ else
+ all_left_cols_null= false;
}
- else
+
+ if (!((Item_in_subselect*)args[1])->is_correlated &&
+ all_left_cols_null && result_for_null_param != UNKNOWN)
{
- /*
- We're evaluating "NULL IN (SELECT ...)". The result is:
- FALSE if SELECT produces an empty set, or
- NULL otherwise.
- We disable the predicates we've pushed down into subselect, run the
- subselect and see if it has produced any rows.
+ /*
+ This is a non-correlated subquery, all values in the outer
+ value list are NULL, and we have already evaluated the
+ subquery for all NULL values: Return the same result we
+ did last time without evaluating the subquery.
*/
- Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
- if (cache->cols() == 1)
- {
- item_subs->set_cond_guard_var(0, FALSE);
- (void) args[1]->val_bool_result();
- result_for_null_param= null_value= !item_subs->engine->no_rows();
- item_subs->set_cond_guard_var(0, TRUE);
- }
- else
- {
- uint i;
- uint ncols= cache->cols();
- /*
- Turn off the predicates that are based on column compares for
- which the left part is currently NULL
- */
- for (i= 0; i < ncols; i++)
- {
- if (cache->element_index(i)->null_value)
- item_subs->set_cond_guard_var(i, FALSE);
- }
-
- (void) args[1]->val_bool_result();
- result_for_null_param= null_value= !item_subs->engine->no_rows();
-
- /* Turn all predicates back on */
- for (i= 0; i < ncols; i++)
- item_subs->set_cond_guard_var(i, TRUE);
- }
+ null_value= result_for_null_param;
+ }
+ else
+ {
+ /* The subquery has to be evaluated */
+ (void) args[1]->val_bool_result();
+ null_value= !item_subs->engine->no_rows();
+ if (all_left_cols_null)
+ result_for_null_param= null_value;
}
+
+ /* Turn all predicates back on */
+ for (uint i= 0; i < ncols; i++)
+ item_subs->set_cond_guard_var(i, TRUE);
}
return 0;
}
@@ -2191,7 +2229,7 @@ uint Item_func_ifnull::decimal_precision() const
int arg1_int_part= args[1]->decimal_int_part();
int max_int_part= max(arg0_int_part, arg1_int_part);
int precision= max_int_part + decimals;
- return precision;
+ return min(precision, DECIMAL_MAX_PRECISION);
}
@@ -2375,7 +2413,7 @@ uint Item_func_if::decimal_precision() const
int arg1_prec= args[1]->decimal_int_part();
int arg2_prec= args[2]->decimal_int_part();
int precision=max(arg1_prec,arg2_prec) + decimals;
- return precision;
+ return min(precision, DECIMAL_MAX_PRECISION);
}
@@ -2783,7 +2821,7 @@ uint Item_func_case::decimal_precision() const
if (else_expr_num != -1)
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
- return max_int_part + decimals;
+ return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 3462bed94a2..ec703d0a9f9 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1725,4 +1725,6 @@ inline Item *and_conds(Item *a, Item *b)
Item *and_expressions(Item *a, Item *b, Item **org_item);
+bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
+ const char *warn_name, MYSQL_TIME *l_time);
#endif /* ITEM_CMPFUNC_INCLUDED */
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d9e6f76dd6b..ac52f36474a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -451,8 +451,45 @@ Field *Item_func::tmp_table_field(TABLE *table)
return make_string_field(table);
break;
case DECIMAL_RESULT:
- field= Field_new_decimal::new_decimal_field(this);
+ {
+ uint8 dec= decimals;
+ uint8 intg= decimal_precision() - dec;
+ uint32 len= max_length;
+
+ /*
+ Trying to put too many digits overall in a DECIMAL(prec,dec)
+ will always throw a warning. We must limit dec to
+ DECIMAL_MAX_SCALE however to prevent an assert() later.
+ */
+
+ if (dec > 0)
+ {
+ int overflow;
+
+ dec= min(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+ we'll throw out decimals rather than integers. This is still
+ bad and of course throws a truncation warning.
+ */
+
+ const int required_length=
+ my_decimal_precision_to_length(intg + dec, dec,
+ unsigned_flag);
+
+ overflow= required_length - len;
+
+ if (overflow > 0)
+ dec= max(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+ }
+
+ field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
break;
+ }
case ROW_RESULT:
default:
// This case should never be chosen
@@ -4739,19 +4776,6 @@ void Item_func_get_user_var::fix_length_and_dec()
}
-uint Item_func_get_user_var::decimal_precision() const
-{
- uint precision= max_length;
- Item_result restype= result_type();
-
- /* Default to maximum as the precision is unknown a priori. */
- if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
- precision= DECIMAL_MAX_PRECISION;
-
- return precision;
-}
-
-
bool Item_func_get_user_var::const_item() const
{
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
diff --git a/sql/item_func.h b/sql/item_func.h
index 628878bcaed..6f2b3f0bfc2 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1396,7 +1396,6 @@ public:
table_map used_tables() const
{ return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
- uint decimal_precision() const;
private:
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index a34204b7181..3c5990eb359 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -84,7 +84,9 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY)
{
- return args[0]->val_str(str);
+ String *str_ret= args[0]->val_str(str);
+ null_value= args[0]->null_value;
+ return str_ret;
}
wkb= args[0]->val_str(&arg_val);
@@ -94,7 +96,10 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
str->set_charset(&my_charset_bin);
if (str->reserve(SRID_SIZE, 512))
- return 0;
+ {
+ null_value= TRUE; /* purecov: inspected */
+ return 0; /* purecov: inspected */
+ }
str->length(0);
str->q_append(srid);
if ((null_value=
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index da651cec70c..fa776ea3dca 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -311,9 +311,14 @@ void Item_subselect::update_used_tables()
void Item_subselect::print(String *str, enum_query_type query_type)
{
- str->append('(');
- engine->print(str, query_type);
- str->append(')');
+ if (engine)
+ {
+ str->append('(');
+ engine->print(str, query_type);
+ str->append(')');
+ }
+ else
+ str->append("(...)");
}
@@ -1949,6 +1954,7 @@ int subselect_single_select_engine::exec()
tab->read_record.record= tab->table->record[0];
tab->read_record.thd= join->thd;
tab->read_record.ref_length= tab->table->file->ref_length;
+ tab->read_record.unlock_row= rr_unlock_row;
*(last_changed_tab++)= tab;
break;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 08a48c6ce2f..38251294053 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -517,7 +517,8 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
name, table->s, collation.collation);
break;
case DECIMAL_RESULT:
- field= Field_new_decimal::new_decimal_field(this);
+ field= new Field_new_decimal(max_length, maybe_null, name,
+ decimals, unsigned_flag);
break;
case ROW_RESULT:
default:
diff --git a/sql/log.cc b/sql/log.cc
index 1ffb2e8b5c3..3d863583859 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1579,7 +1579,6 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0;
-end:
if (!all)
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
DBUG_RETURN(error);
@@ -1747,7 +1746,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
int const error=
thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query, thd->query_length, TRUE, FALSE, errcode);
+ thd->query(), thd->query_length(), TRUE, FALSE, errcode);
DBUG_RETURN(error);
}
@@ -1766,7 +1765,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
int error=
thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query, thd->query_length, TRUE, FALSE, errcode);
+ thd->query(), thd->query_length(), TRUE, FALSE, errcode);
DBUG_RETURN(error);
}
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
@@ -3689,7 +3688,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
}
old_name=name;
name=0; // Don't free name
- close(LOG_CLOSE_TO_BE_OPENED);
+ close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
/*
Note that at this point, log_state != LOG_CLOSED (important for is_open()).
@@ -3704,8 +3703,10 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
trigger temp tables deletion on slaves.
*/
- open(old_name, log_type, new_name_ptr,
- io_cache_type, no_auto_events, max_size, 1);
+ /* reopen index binlog file, BUG#34582 */
+ if (!open_index_file(index_file_name, 0))
+ open(old_name, log_type, new_name_ptr,
+ io_cache_type, no_auto_events, max_size, 1);
my_free(old_name,MYF(0));
end:
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d36b126fd2e..060b675b0e4 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3059,7 +3059,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
thd->query_id = next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->variables.pseudo_thread_id= thread_id; // for temp tables
- DBUG_PRINT("query",("%s",thd->query));
+ DBUG_PRINT("query",("%s", thd->query()));
if (ignored_error_code((expected_error= error_code)) ||
!unexpected_error_code(expected_error))
@@ -3153,7 +3153,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
/* Execute the query (note that we bypass dispatch_command()) */
const char* found_semicolon= NULL;
- mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
log_slow_statement(thd);
}
else
@@ -3165,7 +3165,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
we exit gracefully; otherwise we warn about the bad error and tell DBA
to check/fix it.
*/
- if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
+ if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
else
{
@@ -3175,7 +3175,7 @@ Query partially completed on the master (error on master: %d) \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the \
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
-START SLAVE; . Query: '%s'", expected_error, thd->query);
+START SLAVE; . Query: '%s'", expected_error, thd->query());
thd->is_slave_error= 1;
}
goto end;
@@ -3183,7 +3183,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query);
/* If the query was not ignored, it is printed to the general log */
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
- general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
+ general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
compare_errors:
@@ -4530,8 +4530,8 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
new_db.length= db_len;
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
thd->set_db(new_db.str, new_db.length);
- DBUG_ASSERT(thd->query == 0);
- thd->query_length= 0; // Should not be needed
+ DBUG_ASSERT(thd->query() == 0);
+ thd->set_query_inner(NULL, 0); // Should not be needed
thd->is_slave_error= 0;
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
@@ -7555,7 +7555,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
}
if (get_flags(STMT_END_F))
- if (error= rows_event_stmt_cleanup(rli, thd))
+ if ((error= rows_event_stmt_cleanup(rli, thd)))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 18e5284490c..7ed36ed33b0 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1814,7 +1814,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
are involved, commit the transaction and flush the pending event to the
binlog.
*/
- if (error= ha_autocommit_or_rollback(thd, 0))
+ if ((error= ha_autocommit_or_rollback(thd, 0)))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index b1df1395dcd..21669e82c44 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -48,12 +48,10 @@ C_MODE_END
digits * number of decimal digits in one our big digit - number of decimal
digits in one our big digit decreased by 1 (because we always put decimal
point on the border of our big digits))
-
- This value is 65 due to historical reasons partly due to it being used
- as the maximum allowed precision and not the actual maximum precision.
*/
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
#define DECIMAL_MAX_SCALE 30
+#define DECIMAL_NOT_SPECIFIED 31
/**
maximum length of string representation (number of maximum decimal
@@ -77,6 +75,12 @@ inline uint my_decimal_size(uint precision, uint scale)
}
+inline int my_decimal_int_part(uint precision, uint decimals)
+{
+ return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
+}
+
+
/**
my_decimal class limits 'decimal_t' type to what we need in MySQL.
@@ -180,7 +184,7 @@ inline uint my_decimal_length_to_precision(uint length, uint scale,
}
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
- uint scale,
+ uint8 scale,
bool unsigned_flag)
{
/*
@@ -192,7 +196,7 @@ inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
(unsigned_flag || !precision ? 0 : 1));
}
-inline uint32 my_decimal_precision_to_length(uint precision, uint scale,
+inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
bool unsigned_flag)
{
/*
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 035ab0e70cc..8468e7cf79a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1718,7 +1718,7 @@ static void network_init(void)
saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -2521,7 +2521,7 @@ terribly wrong...\n");
}
fprintf(stderr, "Trying to get some variables.\n\
Some pointers may be invalid and cause the dump to abort...\n");
- my_safe_print_str("thd->query", thd->query, 1024);
+ my_safe_print_str("thd->query", thd->query(), 1024);
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
fprintf(stderr, "thd->killed=%s\n", kreason);
}
@@ -5205,17 +5205,26 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
pthread_handler_t handle_connections_namedpipes(void *arg)
{
HANDLE hConnectedPipe;
- BOOL fConnected;
+ OVERLAPPED connectOverlapped = {0};
THD *thd;
my_thread_init();
DBUG_ENTER("handle_connections_namedpipes");
- (void) my_pthread_getprio(pthread_self()); // For debugging
+ connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DBUG_PRINT("general",("Waiting for named pipe connections."));
while (!abort_loop)
{
/* wait for named pipe connection */
- fConnected = ConnectNamedPipe(hPipe, NULL);
+ BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
+ if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
+ {
+ /*
+ ERROR_IO_PENDING says async IO has started but not yet finished.
+ GetOverlappedResult will wait for completion.
+ */
+ DWORD bytes;
+ fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
+ }
if (abort_loop)
break;
if (!fConnected)
@@ -5224,7 +5233,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
{
CloseHandle(hPipe);
if ((hPipe= CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5244,7 +5253,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
hConnectedPipe = hPipe;
/* create new pipe for new connection */
if ((hPipe = CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5266,7 +5275,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
CloseHandle(hConnectedPipe);
continue;
}
- if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
+ if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
my_net_init(&thd->net, thd->net.vio))
{
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
@@ -5277,7 +5286,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
create_new_thread(thd);
}
-
+ CloseHandle(connectOverlapped.hEvent);
decrement_handler_count();
DBUG_RETURN(0);
}
@@ -5454,8 +5463,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
errmsg= "Could not set client to read mode";
goto errorconn;
}
- if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
- handle_client_file_map,
+ if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
handle_client_map,
event_client_wrote,
event_client_read,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 119f90bc97a..5f9bae22c70 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -5709,6 +5709,27 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
!(conf_func->compare_collation()->state & MY_CS_BINSORT))
goto end;
+ if (key_part->image_type == Field::itMBR)
+ {
+ switch (type) {
+ case Item_func::SP_EQUALS_FUNC:
+ case Item_func::SP_DISJOINT_FUNC:
+ case Item_func::SP_INTERSECTS_FUNC:
+ case Item_func::SP_TOUCHES_FUNC:
+ case Item_func::SP_CROSSES_FUNC:
+ case Item_func::SP_WITHIN_FUNC:
+ case Item_func::SP_CONTAINS_FUNC:
+ case Item_func::SP_OVERLAPS_FUNC:
+ break;
+ default:
+ /*
+ We cannot involve spatial indexes for queries that
+ don't use MBREQUALS(), MBRDISJOINT(), etc. functions.
+ */
+ goto end;
+ }
+ }
+
if (param->using_real_indexes)
optimize_range= field->optimize_range(param->real_keynr[key_part->key],
key_part->part);
@@ -5891,6 +5912,17 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
goto end;
}
field->table->in_use->variables.sql_mode= orig_sql_mode;
+
+ /*
+ Any sargable predicate except "<=>" involving NULL as a constant is always
+ FALSE
+ */
+ if (type != Item_func::EQUAL_FUNC && field->is_real_null())
+ {
+ tree= &null_element;
+ goto end;
+ }
+
str= (uchar*) alloc_root(alloc, key_part->store_length+1);
if (!str)
goto end;
@@ -5936,7 +5968,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
switch (type) {
case Item_func::LT_FUNC:
- if (stored_field_cmp_to_item(field,value) == 0)
+ if (stored_field_cmp_to_item(param->thd, field, value) == 0)
tree->max_flag=NEAR_MAX;
/* fall through */
case Item_func::LE_FUNC:
@@ -5951,14 +5983,14 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
case Item_func::GT_FUNC:
/* Don't use open ranges for partial key_segments */
if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
- (stored_field_cmp_to_item(field, value) <= 0))
+ (stored_field_cmp_to_item(param->thd, field, value) <= 0))
tree->min_flag=NEAR_MIN;
tree->max_flag= NO_MAX_RANGE;
break;
case Item_func::GE_FUNC:
/* Don't use open ranges for partial key_segments */
if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
- (stored_field_cmp_to_item(field,value) < 0))
+ (stored_field_cmp_to_item(param->thd, field, value) < 0))
tree->min_flag= NEAR_MIN;
tree->max_flag=NO_MAX_RANGE;
break;
diff --git a/sql/records.cc b/sql/records.cc
index 9e040de3fda..b6faf0227f9 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -57,10 +57,12 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
{
empty_record(table);
bzero((char*) info,sizeof(*info));
+ info->thd= thd;
info->table= table;
info->file= table->file;
info->record= table->record[0];
info->print_error= print_error;
+ info->unlock_row= rr_unlock_row;
table->status=0; /* And it's always found */
if (!table->file->inited)
@@ -186,6 +188,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
info->select=select;
info->print_error=print_error;
+ info->unlock_row= rr_unlock_row;
info->ignore_not_found_rows= 0;
table->status=0; /* And it's always found */
@@ -292,6 +295,12 @@ void end_read_record(READ_RECORD *info)
static int rr_handle_error(READ_RECORD *info, int error)
{
+ if (info->thd->killed)
+ {
+ info->thd->send_kill_message();
+ return 1;
+ }
+
if (error == HA_ERR_END_OF_FILE)
error= -1;
else
@@ -312,12 +321,7 @@ static int rr_quick(READ_RECORD *info)
int tmp;
while ((tmp= info->select->quick->get_next()))
{
- if (info->thd->killed)
- {
- my_error(ER_SERVER_SHUTDOWN, MYF(0));
- return 1;
- }
- if (tmp != HA_ERR_RECORD_DELETED)
+ if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
{
tmp= rr_handle_error(info, tmp);
break;
@@ -380,16 +384,11 @@ int rr_sequential(READ_RECORD *info)
int tmp;
while ((tmp=info->file->rnd_next(info->record)))
{
- if (info->thd->killed)
- {
- info->thd->send_kill_message();
- return 1;
- }
/*
rnd_next can return RECORD_DELETED for MyISAM when one thread is
reading and another deleting without locks.
*/
- if (tmp != HA_ERR_RECORD_DELETED)
+ if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
{
tmp= rr_handle_error(info, tmp);
break;
diff --git a/sql/slave.cc b/sql/slave.cc
index 8e69066ed9b..40b476e4f17 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1458,6 +1458,199 @@ network_err:
DBUG_RETURN(2);
}
+/*
+ Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD
+ DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it
+ from the dump. Honours replication inclusion/exclusion rules.
+ db must be non-zero (guarded by assertion).
+
+ RETURN VALUES
+ 0 success
+ 1 error
+*/
+
+static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
+ const char* table_name, bool overwrite)
+{
+ ulong packet_len;
+ char *query, *save_db;
+ uint32 save_db_length;
+ Vio* save_vio;
+ HA_CHECK_OPT check_opt;
+ TABLE_LIST tables;
+ int error= 1;
+ handler *file;
+ ulonglong save_options;
+ NET *net= &mysql->net;
+ const char *found_semicolon= NULL;
+ DBUG_ENTER("create_table_from_dump");
+
+ packet_len= my_net_read(net); // read create table statement
+ if (packet_len == packet_error)
+ {
+ my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
+ DBUG_RETURN(1);
+ }
+ if (net->read_pos[0] == 255) // error from master
+ {
+ char *err_msg;
+ err_msg= (char*) net->read_pos + ((mysql->server_capabilities &
+ CLIENT_PROTOCOL_41) ?
+ 3+SQLSTATE_LENGTH+1 : 3);
+ my_error(ER_MASTER, MYF(0), err_msg);
+ DBUG_RETURN(1);
+ }
+ thd->command = COM_TABLE_DUMP;
+ 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->set_query(query, packet_len);
+ thd->is_slave_error = 0;
+
+ bzero((char*) &tables,sizeof(tables));
+ tables.db = (char*)db;
+ tables.alias= tables.table_name= (char*)table_name;
+
+ /* Drop the table if 'overwrite' is true */
+ if (overwrite)
+ {
+ if (mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
+ {
+ sql_print_error("create_table_from_dump: failed to drop the table");
+ goto err;
+ }
+ else
+ {
+ /* Clear the OK result of mysql_rm_table(). */
+ thd->main_da.reset_diagnostics_area();
+ }
+ }
+
+ /* Create the table. We do not want to log the "create table" statement */
+ save_options = thd->options;
+ thd->options &= ~ (OPTION_BIN_LOG);
+ thd_proc_info(thd, "Creating table from master dump");
+ // save old db in case we are creating in a different database
+ save_db = thd->db;
+ save_db_length= thd->db_length;
+ thd->db = (char*)db;
+ DBUG_ASSERT(thd->db != 0);
+ thd->db_length= strlen(thd->db);
+ /* run create table */
+ mysql_parse(thd, thd->query(), packet_len, &found_semicolon);
+ thd->db = save_db; // leave things the way the were before
+ thd->db_length= save_db_length;
+ thd->options = save_options;
+
+ if (thd->is_slave_error)
+ goto err; // mysql_parse took care of the error send
+
+ thd_proc_info(thd, "Opening master dump table");
+ thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */
+ /*
+ Note: If this function starts to fail for MERGE tables,
+ change the next two lines to these:
+ tables.table= NULL; // was set by mysql_rm_table()
+ if (!open_n_lock_single_table(thd, &tables, TL_WRITE))
+ */
+ tables.lock_type = TL_WRITE;
+ if (!open_ltable(thd, &tables, TL_WRITE, 0))
+ {
+ sql_print_error("create_table_from_dump: could not open created table");
+ goto err;
+ }
+
+ file = tables.table->file;
+ thd_proc_info(thd, "Reading master dump table data");
+ /* Copy the data file */
+ if (file->net_read_dump(net))
+ {
+ my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
+ sql_print_error("create_table_from_dump: failed in\
+ handler::net_read_dump()");
+ goto err;
+ }
+
+ check_opt.init();
+ check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
+ thd_proc_info(thd, "Rebuilding the index on master dump table");
+ /*
+ We do not want repair() to spam us with messages
+ just send them to the error log, and report the failure in case of
+ problems.
+ */
+ save_vio = thd->net.vio;
+ thd->net.vio = 0;
+ /* Rebuild the index file from the copied data file (with REPAIR) */
+ error=file->ha_repair(thd,&check_opt) != 0;
+ thd->net.vio = save_vio;
+ if (error)
+ my_error(ER_INDEX_REBUILD, MYF(0), tables.table->s->table_name.str);
+
+err:
+ close_thread_tables(thd);
+ DBUG_RETURN(error);
+}
+
+
+int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
+ Master_info *mi, MYSQL *mysql, bool overwrite)
+{
+ int error= 1;
+ const char *errmsg=0;
+ bool called_connected= (mysql != NULL);
+ DBUG_ENTER("fetch_master_table");
+ DBUG_PRINT("enter", ("db_name: '%s' table_name: '%s'",
+ db_name,table_name));
+
+ if (!called_connected)
+ {
+ if (!(mysql = mysql_init(NULL)))
+ {
+ DBUG_RETURN(1);
+ }
+ if (connect_to_master(thd, mysql, mi))
+ {
+ my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql));
+ /*
+ We need to clear the active VIO since, theoretically, somebody
+ might issue an awake() on this thread. If we are then in the
+ middle of closing and destroying the VIO inside the
+ mysql_close(), we will have a problem.
+ */
+#ifdef SIGNAL_WITH_VIO_CLOSE
+ thd->clear_active_vio();
+#endif
+ mysql_close(mysql);
+ DBUG_RETURN(1);
+ }
+ if (thd->killed)
+ goto err;
+ }
+
+ if (request_table_dump(mysql, db_name, table_name))
+ {
+ error= ER_UNKNOWN_ERROR;
+ errmsg= "Failed on table dump request";
+ goto err;
+ }
+ if (create_table_from_dump(thd, mysql, db_name,
+ table_name, overwrite))
+ goto err; // create_table_from_dump have sent the error already
+ error = 0;
+
+ err:
+ if (!called_connected)
+ mysql_close(mysql);
+ if (errmsg && thd->vio_ok())
+ my_message(error, errmsg, MYF(0));
+ DBUG_RETURN(test(error)); // Return 1 on error
+}
+
+
static bool wait_for_relay_log_space(Relay_log_info* rli)
{
bool slave_killed=0;
diff --git a/sql/sp.cc b/sql/sp.cc
index 4d840f53e2f..fd420732628 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -997,7 +997,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
sp_cache_invalidate();
}
@@ -1067,7 +1067,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
sp_cache_invalidate();
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8ab91222bcc..6a0ab4bfc46 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -332,16 +332,18 @@ bool
sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
{
Item *expr_item;
+ enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
+ bool save_abort_on_warning= thd->abort_on_warning;
+ bool save_stmt_modified_non_trans_table=
+ thd->transaction.stmt.modified_non_trans_table;
DBUG_ENTER("sp_eval_expr");
if (!*expr_item_ptr)
- DBUG_RETURN(TRUE);
+ goto error;
if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
- DBUG_RETURN(TRUE);
-
- bool err_status= FALSE;
+ goto error;
/*
Set THD flags to emit warnings/errors in case of overflow/type errors
@@ -350,10 +352,6 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
Save original values and restore them after save.
*/
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
- bool save_abort_on_warning= thd->abort_on_warning;
- bool save_stmt_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
-
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
thd->variables.sql_mode &
@@ -368,13 +366,18 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->abort_on_warning= save_abort_on_warning;
thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
- if (thd->is_error())
- {
- /* Return error status if something went wrong. */
- err_status= TRUE;
- }
+ if (!thd->is_error())
+ DBUG_RETURN(FALSE);
- DBUG_RETURN(err_status);
+error:
+ /*
+ In case of error during evaluation, leave the result field set to NULL.
+ Sic: we can't do it in the beginning of the function because the
+ result field might be needed for its own re-evaluation, e.g. case of
+ set x = x + 1;
+ */
+ result_field->set_null();
+ DBUG_RETURN (TRUE);
}
@@ -2824,8 +2827,8 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
DBUG_ENTER("sp_instr_stmt::execute");
DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
- query= thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
/* This s-p instr is profilable and will be captured. */
thd->profiling.set_query_source(m_query.str, m_query.length);
@@ -2838,10 +2841,11 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
queries with SP vars can't be cached)
*/
if (unlikely((thd->options & OPTION_LOG_OFF)==0))
- general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
+ general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
if (query_cache_send_result_to_client(thd,
- thd->query, thd->query_length) <= 0)
+ thd->query(),
+ thd->query_length()) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d7d662f912d..0592bb3be1d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -263,8 +263,7 @@ my_bool acl_init(bool dont_read_acl_tables)
acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0,
(hash_get_key) acl_entry_get_key,
(hash_free_key) free,
- lower_case_file_system ?
- system_charset_info : &my_charset_bin);
+ &my_charset_utf8_bin);
if (dont_read_acl_tables)
{
DBUG_RETURN(0); /* purecov: tested */
@@ -2251,10 +2250,13 @@ public:
ulong sort;
size_t key_length;
GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p);
- GRANT_NAME (TABLE *form);
+ const char *t, ulong p, bool is_routine);
+ GRANT_NAME (TABLE *form, bool is_routine);
virtual ~GRANT_NAME() {};
virtual bool ok() { return privs != 0; }
+ void set_user_details(const char *h, const char *d,
+ const char *u, const char *t,
+ bool is_routine);
};
@@ -2272,38 +2274,48 @@ public:
};
-
-GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p)
- :privs(p)
+void GRANT_NAME::set_user_details(const char *h, const char *d,
+ const char *u, const char *t,
+ bool is_routine)
{
/* Host given by user */
update_hostname(&host, strdup_root(&memex, h));
- db = strdup_root(&memex,d);
+ if (db != d)
+ {
+ db= strdup_root(&memex, d);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, db);
+ }
user = strdup_root(&memex,u);
sort= get_sort(3,host.hostname,db,user);
- tname= strdup_root(&memex,t);
- if (lower_case_table_names)
+ if (tname != t)
{
- my_casedn_str(files_charset_info, db);
- my_casedn_str(files_charset_info, tname);
+ tname= strdup_root(&memex, t);
+ if (lower_case_table_names || is_routine)
+ my_casedn_str(files_charset_info, tname);
}
key_length= strlen(d) + strlen(u)+ strlen(t)+3;
hash_key= (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
}
+GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
+ const char *t, ulong p, bool is_routine)
+ :db(0), tname(0), privs(p)
+{
+ set_user_details(h, d, u, t, is_routine);
+}
GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
const char *t, ulong p, ulong c)
- :GRANT_NAME(h,d,u,t,p), cols(c)
+ :GRANT_NAME(h,d,u,t,p, FALSE), cols(c)
{
(void) hash_init2(&hash_columns,4,system_charset_info,
0,0,0, (hash_get_key) get_key_column,0,0);
}
-GRANT_NAME::GRANT_NAME(TABLE *form)
+GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine)
{
update_hostname(&host, get_field(&memex, form->field[0]));
db= get_field(&memex,form->field[1]);
@@ -2321,6 +2333,9 @@ GRANT_NAME::GRANT_NAME(TABLE *form)
if (lower_case_table_names)
{
my_casedn_str(files_charset_info, db);
+ }
+ if (lower_case_table_names || is_routine)
+ {
my_casedn_str(files_charset_info, tname);
}
key_length= (strlen(db) + strlen(user) + strlen(tname) + 3);
@@ -2332,7 +2347,7 @@ GRANT_NAME::GRANT_NAME(TABLE *form)
GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
- :GRANT_NAME(form)
+ :GRANT_NAME(form, FALSE)
{
uchar key[MAX_KEY_LENGTH];
@@ -3184,7 +3199,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (!result) /* success */
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3327,7 +3342,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
grant_name= new GRANT_NAME(Str->host.str, db_name,
Str->user.str, table_name,
- rights);
+ rights, TRUE);
if (!grant_name)
{
result= TRUE;
@@ -3349,7 +3364,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (write_to_binlog)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3461,7 +3476,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
if (!result)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3538,10 +3553,10 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
THR_MALLOC);
DBUG_ENTER("grant_load_procs_priv");
- (void) hash_init(&proc_priv_hash,system_charset_info,
+ (void) hash_init(&proc_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
0,0);
- (void) hash_init(&func_priv_hash,system_charset_info,
+ (void) hash_init(&func_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
0,0);
p_table->file->ha_index_init(0, 1);
@@ -3555,7 +3570,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
{
GRANT_NAME *mem_check;
HASH *hash;
- if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table)))
+ if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table, TRUE)))
{
/* This could only happen if we are out memory */
goto end_unlock;
@@ -3639,7 +3654,7 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables)
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
- (void) hash_init(&column_priv_hash,system_charset_info,
+ (void) hash_init(&column_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0);
@@ -5436,9 +5451,21 @@ static int handle_grant_struct(uint struct_no, bool drop,
case 2:
case 3:
- grant_name->user= strdup_root(&mem, user_to->user.str);
- update_hostname(&grant_name->host,
- strdup_root(&mem, user_to->host.str));
+ /*
+ Update the grant structure with the new user name and
+ host name
+ */
+ grant_name->set_user_details(user_to->host.str, grant_name->db,
+ user_to->user.str, grant_name->tname,
+ TRUE);
+
+ /*
+ Since username is part of the hash key, when the user name
+ is renamed, the hash key is changed. Update the hash to
+ ensure that the position matches the new hash key value
+ */
+ hash_update(&column_priv_hash, (uchar*) grant_name,
+ (uchar*) grant_name->hash_key, grant_name->key_length);
break;
}
}
@@ -5663,7 +5690,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
if (some_users_created)
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -5736,7 +5763,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
if (some_users_deleted)
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -5821,7 +5848,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
if (some_users_renamed && mysql_bin_log.is_open())
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -6003,7 +6030,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -6117,7 +6144,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
for (counter= 0, revoked= 0 ; counter < hash->records ; )
{
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter);
- if (!my_strcasecmp(system_charset_info, grant_proc->db, sp_db) &&
+ if (!my_strcasecmp(&my_charset_utf8_bin, grant_proc->db, sp_db) &&
!my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
{
LEX_USER lex_user;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ed64242e4b1..776fea20676 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -25,6 +25,7 @@
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
+#include "rpl_filter.h"
#ifdef __WIN__
#include <io.h>
#endif
@@ -1547,6 +1548,7 @@ void close_temporary_tables(THD *thd)
s_query.length() - 1 /* to remove trailing ',' */,
0, FALSE, 0);
qinfo.db= db.ptr();
+ qinfo.db_len= db.length();
thd->variables.character_set_client= cs_save;
mysql_bin_log.write(&qinfo);
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
@@ -5098,7 +5100,16 @@ static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
int decide_logging_format(THD *thd, TABLE_LIST *tables)
{
- if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+ /*
+ In SBR mode, we are only proceeding if we are binlogging this
+ statement, ie, the filtering rules won't later filter this out.
+
+ This check here is needed to prevent some spurious error to be
+ raised in some cases (See BUG#42829).
+ */
+ if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
+ (thd->variables.binlog_format != BINLOG_FORMAT_STMT ||
+ binlog_filter->db_ok(thd->db)))
{
/*
Compute the starting vectors for the computations by creating a
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index a41b7bd40bb..861bd97928d 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1119,8 +1119,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
DBUG_VOID_RETURN;
uint8 tables_type= 0;
- if ((local_tables= is_cacheable(thd, thd->query_length,
- thd->query, thd->lex, tables_used,
+ if ((local_tables= is_cacheable(thd, thd->query_length(),
+ thd->query(), thd->lex, tables_used,
&tables_type)))
{
NET *net= &thd->net;
@@ -1210,7 +1210,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Key is query + database + flag */
if (thd->db_length)
{
- memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length);
+ memcpy(thd->query() + thd->query_length() + 1, thd->db,
+ thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u",
thd->db, (unsigned) thd->db_length));
}
@@ -1218,24 +1219,24 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
DBUG_PRINT("qcache", ("No active database"));
}
- tot_length= thd->query_length + thd->db_length + 1 +
+ tot_length= thd->query_length() + thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE;
/*
We should only copy structure (don't use it location directly)
because of alignment issue
*/
- memcpy((void *)(thd->query + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
+ memcpy((void*) (thd->query() + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
&flags, QUERY_CACHE_FLAGS_SIZE);
/* Check if another thread is processing the same query? */
Query_cache_block *competitor = (Query_cache_block *)
- hash_search(&queries, (uchar*) thd->query, tot_length);
+ hash_search(&queries, (uchar*) thd->query(), tot_length);
DBUG_PRINT("qcache", ("competitor 0x%lx", (ulong) competitor));
if (competitor == 0)
{
/* Query is not in cache and no one is working with it; Store it */
Query_cache_block *query_block;
- query_block= write_block_data(tot_length, (uchar*) thd->query,
+ query_block= write_block_data(tot_length, (uchar*) thd->query(),
ALIGN_SIZE(sizeof(Query_cache_query)),
Query_cache_block::QUERY, local_tables);
if (query_block != 0)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 179be88442c..a041df23cc5 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -412,14 +412,14 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
str.append(proc_info);
}
- if (thd->query)
+ if (thd->query())
{
if (max_query_len < 1)
- len= thd->query_length;
+ len= thd->query_length();
else
- len= min(thd->query_length, max_query_len);
+ len= min(thd->query_length(), max_query_len);
str.append('\n');
- str.append(thd->query, len);
+ str.append(thd->query(), len);
}
if (str.c_ptr_safe() == buffer)
return buffer;
@@ -2467,12 +2467,12 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
id(id_arg),
mark_used_columns(MARK_COLUMNS_READ),
lex(lex_arg),
- query(0),
- query_length(0),
cursor(0),
db(NULL),
db_length(0)
{
+ query_string.length= 0;
+ query_string.str= NULL;
name.str= NULL;
}
@@ -2488,8 +2488,7 @@ void Statement::set_statement(Statement *stmt)
id= stmt->id;
mark_used_columns= stmt->mark_used_columns;
lex= stmt->lex;
- query= stmt->query;
- query_length= stmt->query_length;
+ query_string= stmt->query_string;
cursor= stmt->cursor;
}
@@ -2513,6 +2512,15 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
}
+/** Assign a new value to thd->query. */
+
+void Statement::set_query_inner(char *query_arg, uint32 query_length_arg)
+{
+ query_string.str= query_arg;
+ query_string.length= query_length_arg;
+}
+
+
void THD::end_statement()
{
/* Cleanup SQL processing state to reuse this statement in next query. */
@@ -2748,9 +2756,11 @@ bool select_dumpvar::send_data(List<Item> &items)
else
{
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
- suv->fix_fields(thd, 0);
+ if (suv->fix_fields(thd, 0))
+ DBUG_RETURN (1);
suv->save_item_result(item);
- suv->update();
+ if (suv->update())
+ DBUG_RETURN (1);
}
}
DBUG_RETURN(thd->is_error());
@@ -3026,9 +3036,24 @@ extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
return(thd->charset());
}
+/**
+ OBSOLETE : there's no way to ensure the string is null terminated.
+ Use thd_query_string instead()
+*/
extern "C" char **thd_query(MYSQL_THD thd)
{
- return(&thd->query);
+ return(&thd->query_string.str);
+}
+
+/**
+ Get the current query string for the thread.
+
+ @param The MySQL internal thread pointer
+ @return query string and length. May be non-null-terminated.
+*/
+extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
+{
+ return(&thd->query_string);
}
extern "C" int thd_slave_thread(const MYSQL_THD thd)
@@ -3053,6 +3078,11 @@ extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
{
mark_transaction_to_rollback(thd, all);
}
+
+extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
+{
+ return binlog_filter->db_ok(thd->db);
+}
#endif // INNODB_COMPATIBILITY_HOOKS */
/****************************************************************************
@@ -3207,8 +3237,7 @@ void THD::set_statement(Statement *stmt)
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;
+ set_query_inner(query_arg, query_length_arg);
pthread_mutex_unlock(&LOCK_thd_data);
}
@@ -3226,6 +3255,16 @@ void mark_transaction_to_rollback(THD *thd, bool all)
{
thd->is_fatal_sub_stmt_error= TRUE;
thd->transaction_rollback_request= all;
+ /*
+ Aborted transactions can not be IGNOREd.
+ Switch off the IGNORE flag for the current
+ SELECT_LEX. This should allow my_error()
+ to report the error and abort the execution
+ flow, even in presence
+ of IGNORE clause.
+ */
+ if (thd->lex->current_select)
+ thd->lex->current_select->no_error= FALSE;
}
}
/***************************************************************************
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 8c3a4f2e62d..05f2cb50ff6 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -97,6 +97,8 @@ extern char internal_table_name[2];
extern char empty_c_string[1];
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
+extern bool volatile shutdown_in_progress;
+
#define TC_LOG_PAGE_SIZE 8192
#define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
@@ -646,10 +648,13 @@ public:
This printing is needed at least in SHOW PROCESSLIST and SHOW
ENGINE INNODB STATUS.
*/
- char *query;
- uint32 query_length; // current query length
+ LEX_STRING query_string;
Server_side_cursor *cursor;
+ inline char *query() { return query_string.str; }
+ inline uint32 query_length() { return query_string.length; }
+ void set_query_inner(char *query_arg, uint32 query_length_arg);
+
/**
Name of the current (default) database.
@@ -2122,7 +2127,11 @@ public:
{
int err= killed_errno();
if (err)
+ {
+ if ((err == KILL_CONNECTION) && !shutdown_in_progress)
+ err = KILL_QUERY;
my_message(err, ER(err), MYF(0));
+ }
}
/* return TRUE if we will abort query if we make a warning now */
inline bool really_abort_on_warning()
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c19bfba9fc1..e6ccd9aa594 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -703,7 +703,7 @@ not_silent:
char *query;
uint query_length;
- if (!thd->query) // Only in replication
+ if (!thd->query()) // Only in replication
{
query= tmp_query;
query_length= (uint) (strxmov(tmp_query,"create database `",
@@ -711,8 +711,8 @@ not_silent:
}
else
{
- query= thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
}
ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
@@ -805,13 +805,13 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
}
ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, "");
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0,
/* suppress_use */ TRUE, errcode);
/*
@@ -948,7 +948,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
const char *query;
ulong query_length;
- if (!thd->query)
+ if (!thd->query())
{
/* The client used the old obsolete mysql_drop_db() call */
query= path;
@@ -957,8 +957,8 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
else
{
- query =thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
}
if (mysql_bin_log.is_open())
{
@@ -1964,7 +1964,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
- Query_log_event qinfo(thd, thd->query, thd->query_length,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, TRUE, errcode);
thd->clear_error();
mysql_bin_log.write(&qinfo);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a81a5f4641f..b80138af7f2 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -413,7 +413,7 @@ cleanup:
therefore be treated as a DDL.
*/
int log_result= thd->binlog_query(query_type,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
is_trans, FALSE, errcode);
if (log_result)
@@ -850,7 +850,7 @@ void multi_delete::abort()
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= true;
@@ -1024,7 +1024,7 @@ bool multi_delete::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode) &&
!normal_tables)
{
@@ -1166,7 +1166,7 @@ end:
TRUNCATE must always be statement-based binlogged (not row-based) so
we don't test current_stmt_binlog_row_based.
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 3ac40ae825a..6e2b3903b52 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -567,7 +567,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
Name_resolution_context *context;
Name_resolution_context_state ctx_state;
#ifndef EMBEDDED_LIBRARY
- char *query= thd->query;
+ char *query= thd->query();
/*
log_on is about delayed inserts only.
By default, both logs are enabled (this won't cause problems if the server
@@ -801,7 +801,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
{
- LEX_STRING const st_query = { query, thd->query_length };
+ LEX_STRING const st_query = { query, thd->query_length() };
error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
query=0;
}
@@ -894,7 +894,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_table, FALSE,
errcode))
{
@@ -1764,7 +1764,7 @@ public:
pthread_cond_destroy(&cond);
pthread_cond_destroy(&cond_client);
thd.unlink(); // Must be unlinked under lock
- x_free(thd.query);
+ x_free(thd.query());
thd.security_ctx->user= thd.security_ctx->host=0;
thread_count--;
delayed_insert_threads--;
@@ -1910,7 +1910,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_unlock(&LOCK_thread_count);
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
- if (di->thd.db == NULL || di->thd.query == NULL)
+ if (di->thd.db == NULL || di->thd.query() == NULL)
{
/* The error is reported */
delete di;
@@ -1919,7 +1919,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
}
di->table_list= *table_list; // Needed to open table
/* Replace volatile strings with local copies */
- di->table_list.alias= di->table_list.table_name= di->thd.query;
+ di->table_list.alias= di->table_list.table_name= di->thd.query();
di->table_list.db= di->thd.db;
di->lock();
pthread_mutex_lock(&di->mutex);
@@ -3250,7 +3250,7 @@ bool select_insert::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
trans_table, FALSE, errcode);
}
table->file->ha_release_auto_increment();
@@ -3320,7 +3320,8 @@ void select_insert::abort() {
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
+ thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
+ thd->query_length(),
transactional_table, FALSE, errcode);
}
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 5c278467179..8dda4a52466 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -84,7 +84,7 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
bool ignore_check_option_errors);
#ifndef EMBEDDED_LIBRARY
static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
- const char* db_arg,
+ const char* db_arg, /* table's database */
const char* table_name_arg,
enum enum_duplicates duplicates,
bool ignore,
@@ -502,7 +502,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, ex,
- tdb, table_list->table_name,
+ table_list->db,
+ table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
@@ -549,7 +550,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
write_execute_load_query_log_event(thd, ex,
- tdb, table_list->table_name,
+ table_list->db, table_list->table_name,
handle_duplicates, ignore,
transactional_table,
errcode);
@@ -574,7 +575,7 @@ err:
/* Not a very useful function; just to avoid duplication of code */
static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
- const char* db_arg,
+ const char* db_arg, /* table's database */
const char* table_name_arg,
enum enum_duplicates duplicates,
bool ignore,
@@ -591,8 +592,27 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
Item *item, *val;
String pfield, pfields;
int n;
+ const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
+ String string_buf;
- Load_log_event lle(thd, ex, db_arg, table_name_arg, fv, duplicates,
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+ If used database differs from table's database,
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+ string_buf.set_charset(system_charset_info);
+ string_buf.append(db_arg);
+ string_buf.append("`");
+ string_buf.append(".");
+ string_buf.append("`");
+ string_buf.append(table_name_arg);
+ tbl= string_buf.c_ptr_safe();
+ }
+
+ Load_log_event lle(thd, ex, tdb, tbl, fv, duplicates,
ignore, transactional_table);
/*
@@ -655,13 +675,12 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
strcpy(end, p);
end += pl;
- thd->query_length= end - load_data_query;
- thd->query= load_data_query;
+ thd->set_query_inner(load_data_query, end - load_data_query);
Execute_load_query_log_event
- e(thd, thd->query, thd->query_length,
- (uint) ((char*)fname_start - (char*)thd->query - 1),
- (uint) ((char*)fname_end - (char*)thd->query),
+ e(thd, thd->query(), thd->query_length(),
+ (uint) ((char*) fname_start - (char*) thd->query() - 1),
+ (uint) ((char*) fname_end - (char*) thd->query()),
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE, errcode);
diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc
index 3def9864c29..5ddf65cd1b7 100644
--- a/sql/sql_locale.cc
+++ b/sql/sql_locale.cc
@@ -1309,9 +1309,9 @@ static const char *my_locale_month_names_ro_RO[13] =
static const char *my_locale_ab_month_names_ro_RO[13] =
{"ian","feb","mar","apr","mai","iun","iul","aug","sep","oct","nov","dec", NullS };
static const char *my_locale_day_names_ro_RO[8] =
- {"Luni","Marţi","Miercuri","Joi","Vineri","SîmbĂtĂ","DuminicĂ", NullS };
+ {"Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă","Duminică", NullS };
static const char *my_locale_ab_day_names_ro_RO[8] =
- {"Lu","Ma","Mi","Jo","Vi","Sî","Du", NullS };
+ {"Lu","Ma","Mi","Jo","Vi","Sâ","Du", NullS };
static TYPELIB my_locale_typelib_month_names_ro_RO =
{ array_elements(my_locale_month_names_ro_RO)-1, "", my_locale_month_names_ro_RO, NULL };
static TYPELIB my_locale_typelib_ab_month_names_ro_RO =
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7c19cd7f82a..80f366d774a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -123,6 +123,14 @@ static bool xa_trans_rolled_back(XID_STATE *xid_state)
*/
static bool xa_trans_rollback(THD *thd)
{
+ /*
+ Resource Manager error is meaningless at this point, as we perform
+ explicit rollback request by user. We must reset rm_error before
+ calling ha_rollback(), so thd->transaction.xid structure gets reset
+ by ha_rollback()/THD::transaction::cleanup().
+ */
+ thd->transaction.xid_state.rm_error= 0;
+
bool status= test(ha_rollback(thd));
thd->options&= ~(ulong) OPTION_BEGIN;
@@ -130,7 +138,6 @@ static bool xa_trans_rollback(THD *thd)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
- thd->transaction.xid_state.rm_error= 0;
return status;
}
@@ -476,10 +483,10 @@ static void handle_bootstrap_impl(THD *thd)
thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE);
thd->set_query(query, length);
- DBUG_PRINT("query",("%-.4096s",thd->query));
+ DBUG_PRINT("query",("%-.4096s", thd->query()));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query();
- thd->profiling.set_query_source(thd->query, length);
+ thd->profiling.set_query_source(thd->query(), length);
#endif
/*
@@ -488,7 +495,7 @@ static void handle_bootstrap_impl(THD *thd)
*/
thd->query_id=next_query_id();
thd->set_time();
- mysql_parse(thd, thd->query, length, & found_semicolon);
+ mysql_parse(thd, thd->query(), length, & found_semicolon);
close_thread_tables(thd); // Free tables
bootstrap_error= thd->is_error();
@@ -1107,20 +1114,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
if (alloc_query(thd, packet, packet_length))
break; // fatal error is set
- char *packet_end= thd->query + thd->query_length;
+ char *packet_end= thd->query() + thd->query_length();
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
const char* end_of_stmt= NULL;
- general_log_write(thd, command, thd->query, thd->query_length);
- DBUG_PRINT("query",("%-.4096s",thd->query));
+ general_log_write(thd, command, thd->query(), thd->query_length());
+ DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
- thd->profiling.set_query_source(thd->query, thd->query_length);
+ thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
- mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
+ mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{
@@ -1563,7 +1570,8 @@ void log_slow_statement(THD *thd)
{
thd_proc_info(thd, "logging slow query");
thd->status_var.long_query_count++;
- slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query);
+ slow_log_print(thd, thd->query(), thd->query_length(),
+ end_utime_of_query);
}
}
DBUG_VOID_RETURN;
@@ -2816,7 +2824,7 @@ end_with_restore_list:
/*
Presumably, REPAIR and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -2848,7 +2856,7 @@ end_with_restore_list:
/*
Presumably, ANALYZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -2871,7 +2879,7 @@ end_with_restore_list:
/*
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3823,7 +3831,7 @@ end_with_restore_list:
*/
if (!lex->no_write_to_binlog && write_to_binlog)
{
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
}
my_ok(thd);
}
@@ -4400,7 +4408,7 @@ create_sp_error:
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
@@ -4930,8 +4938,6 @@ bool check_single_table_access(THD *thd, ulong privilege,
/* Show only 1 table for check_grant */
if (!(all_tables->belong_to_view &&
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
- !(all_tables->view &&
- all_tables->effective_algorithm == VIEW_ALGORITHM_TMPTABLE) &&
check_grant(thd, privilege, all_tables, 0, 1, no_errors))
goto deny;
@@ -5791,9 +5797,10 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
PROCESSLIST.
Note that we don't need LOCK_thread_count to modify query_length.
*/
- if (*found_semicolon &&
- (thd->query_length= (ulong)(*found_semicolon - thd->query)))
- thd->query_length--;
+ if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
+ thd->set_query_inner(thd->query(),
+ (uint32) (*found_semicolon -
+ thd->query() - 1));
/* Actually execute the query */
if (*found_semicolon)
{
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index a7b35caeb8a..5a622740638 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4081,7 +4081,7 @@ static int fast_end_partition(THD *thd, ulonglong copied,
if ((!is_empty) && (!written_bin_log) &&
(!thd->lex->no_write_to_binlog))
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
@@ -6239,7 +6239,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_drop_partition_6") ||
((frm_install= TRUE), FALSE) ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
@@ -6306,7 +6306,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_add_partition_6") ||
write_log_rename_frm(lpt) ||
(not_completed= FALSE) ||
@@ -6396,7 +6396,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_change_partition_6") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_change_partition_7") ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
ERROR_INJECT_CRASH("crash_change_partition_8") ||
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 5500e44d1b2..e4cecdecc7e 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -2061,7 +2061,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
const char *strvalue= "NULL", *str;
TYPELIB *typelib;
ulonglong result;
- uint error_len;
+ uint error_len= 0; // init as only set on error
bool not_used;
int length;
@@ -2660,7 +2660,9 @@ uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
{
if (!(value & mask))
continue;
- str.append(typelib->type_names[i], typelib->type_lengths[i]);
+ str.append(typelib->type_names[i], typelib->type_lengths
+ ? typelib->type_lengths[i]
+ : strlen(typelib->type_names[i]));
str.append(',');
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c1839b7220f..e2a24f7da1e 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -752,7 +752,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
const String *res;
DBUG_ENTER("insert_params_with_log");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (Item_param **it= begin; it < end; ++it)
@@ -914,7 +914,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt,
DBUG_ENTER("emb_insert_params_with_log");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (; it < end; ++it, ++client_param)
@@ -1065,7 +1065,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
DBUG_ENTER("insert_params_from_vars");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (Item_param **it= begin; it < end; ++it)
@@ -2342,6 +2342,9 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
/* Fix ORDER list */
for (order= (ORDER *)sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
+
+ /* clear the no_error flag for INSERT/UPDATE IGNORE */
+ sl->no_error= FALSE;
}
{
SELECT_LEX_UNIT *unit= sl->master_unit();
@@ -2457,9 +2460,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
}
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
- thd->profiling.set_query_source(stmt->query, stmt->query_length);
+ thd->profiling.set_query_source(stmt->query(), stmt->query_length());
#endif
- DBUG_PRINT("exec_query", ("%s", stmt->query));
+ DBUG_PRINT("exec_query", ("%s", stmt->query()));
DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
sp_cache_flush_obsolete(&thd->sp_proc_cache);
@@ -3029,7 +3032,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
- Parser_state parser_state(thd, thd->query, thd->query_length);
+ Parser_state parser_state(thd, thd->query(), thd->query_length());
parser_state.m_lip.stmt_prepare_mode= TRUE;
lex_start(thd);
@@ -3118,7 +3121,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
the general log.
*/
if (thd->spcont == NULL)
- general_log_write(thd, COM_STMT_PREPARE, query, query_length);
+ general_log_write(thd, COM_STMT_PREPARE, query(), query_length());
}
DBUG_RETURN(error);
}
@@ -3309,7 +3312,7 @@ Prepared_statement::reprepare()
return TRUE;
error= ((name.str && copy.set_name(&name)) ||
- copy.prepare(query, query_length) ||
+ copy.prepare(query(), query_length()) ||
validate_metadata(&copy));
if (cur_db_changed)
@@ -3547,8 +3550,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
to point at it even after we restore from backup. This is ok, as
expanded query was allocated in thd->mem_root.
*/
- stmt_backup.query= thd->query;
- stmt_backup.query_length= thd->query_length;
+ stmt_backup.set_query_inner(thd->query(), thd->query_length());
/*
At first execution of prepared statement we may perform logical
@@ -3573,8 +3575,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Note that multi-statements cannot exist here (they are not supported in
prepared statements).
*/
- if (query_cache_send_result_to_client(thd, thd->query,
- thd->query_length) <= 0)
+ if (query_cache_send_result_to_client(thd, thd->query(),
+ thd->query_length()) <= 0)
{
error= mysql_execute_command(thd);
}
@@ -3619,7 +3621,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
the general log.
*/
if (error == 0 && thd->spcont == NULL)
- general_log_write(thd, COM_STMT_EXECUTE, thd->query, thd->query_length);
+ general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
error:
flags&= ~ (uint) IS_IN_USE;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 0e0b8eb60b9..dac96f2e9c4 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -177,7 +177,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
/* Lets hope this doesn't fail as the result will be messy */
if (!silent && !error)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c5e0bce498d..cdaebef49f6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -149,6 +149,7 @@ static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
+static void join_read_key_unlock_row(st_join_table *tab);
static int join_read_always_key(JOIN_TAB *tab);
static int join_read_last_key(JOIN_TAB *tab);
static int join_no_more_records(READ_RECORD *info);
@@ -633,6 +634,18 @@ JOIN::prepare(Item ***rref_pointer_array,
MYF(0)); /* purecov: inspected */
goto err; /* purecov: inspected */
}
+ if (thd->lex->derived_tables)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE",
+ thd->lex->derived_tables & DERIVED_VIEW ?
+ "view" : "subquery");
+ goto err;
+ }
+ if (thd->lex->sql_command != SQLCOM_SELECT)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "non-SELECT");
+ goto err;
+ }
}
if (!procedure && result && result->prepare(fields_list, unit_arg))
@@ -969,6 +982,12 @@ JOIN::optimize()
DBUG_RETURN(1);
}
+ if (select_lex->olap == ROLLUP_TYPE && rollup_process_const_fields())
+ {
+ DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
+ DBUG_RETURN(1);
+ }
+
/* Remove distinct if only const tables */
select_distinct= select_distinct && (const_tables != tables);
thd_proc_info(thd, "preparing");
@@ -1099,7 +1118,7 @@ JOIN::optimize()
join_tab[const_tables].select->quick->get_type() !=
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
{
- if (group_list &&
+ if (group_list && rollup.state == ROLLUP::STATE_NONE &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_order_list,
(void *) group_list))
@@ -1143,7 +1162,8 @@ JOIN::optimize()
if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
select_distinct=0;
}
- else if (select_distinct && tables - const_tables == 1)
+ else if (select_distinct && tables - const_tables == 1 &&
+ rollup.state == ROLLUP::STATE_NONE)
{
/*
We are only using one table. In this case we change DISTINCT to a
@@ -3560,7 +3580,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
{
if (!(form->keys_in_use_for_query.is_set(key)))
continue;
- if (form->key_info[key].flags & HA_FULLTEXT)
+ if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
continue; // ToDo: ft-keys in non-ft queries. SerG
uint key_parts= (uint) form->key_info[key].key_parts;
@@ -5609,7 +5629,9 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
}
j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
j->ref.key_err=1;
+ j->ref.has_record= FALSE;
j->ref.null_rejecting= 0;
+ j->ref.use_count= 0;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
@@ -6442,6 +6464,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
DBUG_RETURN(0);
}
+
+/**
+ The default implementation of unlock-row method of READ_RECORD,
+ used in all access methods.
+*/
+
+void rr_unlock_row(st_join_table *tab)
+{
+ READ_RECORD *info= &tab->read_record;
+ info->file->unlock_row();
+}
+
+
+
static void
make_join_readinfo(JOIN *join, ulonglong options)
{
@@ -6457,6 +6493,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
TABLE *table=tab->table;
tab->read_record.table= table;
tab->read_record.file=table->file;
+ tab->read_record.unlock_row= rr_unlock_row;
tab->next_select=sub_select; /* normal select */
/*
@@ -6502,6 +6539,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
delete tab->quick;
tab->quick=0;
tab->read_first_record= join_read_key;
+ tab->read_record.unlock_row= join_read_key_unlock_row;
tab->read_record.read_record= join_no_more_records;
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
@@ -8964,7 +9002,10 @@ static void restore_prev_nj_state(JOIN_TAB *last)
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
else if (last_emb->nested_join->join_list.elements-1 ==
last_emb->nested_join->counter)
+ {
join->cur_embedding_map|= last_emb->nested_join->nj_map;
+ break;
+ }
else
break;
last_emb= last_emb->embedding;
@@ -9411,8 +9452,47 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
new_field->set_derivation(item->collation.derivation);
break;
case DECIMAL_RESULT:
- new_field= Field_new_decimal::new_decimal_field(item);
+ {
+ uint8 dec= item->decimals;
+ uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
+ uint32 len= item->max_length;
+
+ /*
+ Trying to put too many digits overall in a DECIMAL(prec,dec)
+ will always throw a warning. We must limit dec to
+ DECIMAL_MAX_SCALE however to prevent an assert() later.
+ */
+
+ if (dec > 0)
+ {
+ signed int overflow;
+
+ dec= min(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+ we'll throw out decimals rather than integers. This is still
+ bad and of course throws a truncation warning.
+ +1: for decimal point
+ */
+
+ const int required_length=
+ my_decimal_precision_to_length(intg + dec, dec,
+ item->unsigned_flag);
+
+ overflow= required_length - len;
+
+ if (overflow > 0)
+ dec= max(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+ }
+
+ new_field= new Field_new_decimal(len, maybe_null, item->name,
+ dec, item->unsigned_flag);
break;
+ }
case ROW_RESULT:
default:
// This case should never be choosen
@@ -10212,6 +10292,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
{
Field *field=(*cur_group->item)->get_tmp_table_field();
+ DBUG_ASSERT(field->table == table);
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
@@ -11189,6 +11270,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
COND *select_cond= join_tab->select_cond;
+ bool select_cond_result= TRUE;
if (error > 0 || (join->thd->is_error())) // Fatal error
return NESTED_LOOP_ERROR;
@@ -11200,7 +11282,17 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
return NESTED_LOOP_KILLED; /* purecov: inspected */
}
DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
- if (!select_cond || select_cond->val_int())
+
+ if (select_cond)
+ {
+ select_cond_result= test(select_cond->val_int());
+
+ /* check for errors evaluating the condition */
+ if (join->thd->is_error())
+ return NESTED_LOOP_ERROR;
+ }
+
+ if (!select_cond || select_cond_result)
{
/*
There is no select condition or the attached pushed down
@@ -11284,7 +11376,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
return NESTED_LOOP_NO_MORE_ROWS;
}
else
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(join_tab);
}
else
{
@@ -11294,7 +11386,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
*/
join->examined_rows++;
join->thd->row_count++;
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(join_tab);
}
return NESTED_LOOP_OK;
}
@@ -11654,18 +11746,55 @@ join_read_key(JOIN_TAB *tab)
table->status=STATUS_NOT_FOUND;
return -1;
}
+ /*
+ Moving away from the current record. Unlock the row
+ in the handler if it did not match the partial WHERE.
+ */
+ if (tab->ref.has_record && tab->ref.use_count == 0)
+ {
+ tab->read_record.file->unlock_row();
+ tab->ref.has_record= FALSE;
+ }
error=table->file->index_read_map(table->record[0],
tab->ref.key_buff,
make_prev_keypart_map(tab->ref.key_parts),
HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
+
+ if (! error)
+ {
+ tab->ref.has_record= TRUE;
+ tab->ref.use_count= 1;
+ }
+ }
+ else if (table->status == 0)
+ {
+ DBUG_ASSERT(tab->ref.has_record);
+ tab->ref.use_count++;
}
table->null_row=0;
return table->status ? -1 : 0;
}
+/**
+ Since join_read_key may buffer a record, do not unlock
+ it if it was not used in this invocation of join_read_key().
+ Only count locks, thus remembering if the record was left unused,
+ and unlock already when pruning the current value of
+ TABLE_REF buffer.
+ @sa join_read_key()
+*/
+
+static void
+join_read_key_unlock_row(st_join_table *tab)
+{
+ DBUG_ASSERT(tab->ref.use_count);
+ if (tab->ref.use_count)
+ tab->ref.use_count--;
+}
+
/*
ref access method implementation: "read_first" function
@@ -15637,32 +15766,7 @@ bool JOIN::rollup_init()
{
item->maybe_null= 1;
found_in_group= 1;
- if (item->const_item())
- {
- /*
- For ROLLUP queries each constant item referenced in GROUP BY list
- is wrapped up into an Item_func object yielding the same value
- as the constant item. The objects of the wrapper class are never
- considered as constant items and besides they inherit all
- properties of the Item_result_field class.
- This wrapping allows us to ensure writing constant items
- into temporary tables whenever the result of the ROLLUP
- operation has to be written into a temporary table, e.g. when
- ROLLUP is used together with DISTINCT in the SELECT list.
- Usually when creating temporary tables for a intermidiate
- result we do not include fields for constant expressions.
- */
- Item* new_item= new Item_func_rollup_const(item);
- if (!new_item)
- return 1;
- new_item->fix_fields(thd, (Item **) 0);
- thd->change_item_tree(it.ref(), new_item);
- for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
- {
- if (*tmp->item == item)
- thd->change_item_tree(tmp->item, new_item);
- }
- }
+ break;
}
}
if (item->type() == Item::FUNC_ITEM && !found_in_group)
@@ -15681,6 +15785,59 @@ bool JOIN::rollup_init()
}
return 0;
}
+
+/**
+ Wrap all constant Items in GROUP BY list.
+
+ For ROLLUP queries each constant item referenced in GROUP BY list
+ is wrapped up into an Item_func object yielding the same value
+ as the constant item. The objects of the wrapper class are never
+ considered as constant items and besides they inherit all
+ properties of the Item_result_field class.
+ This wrapping allows us to ensure writing constant items
+ into temporary tables whenever the result of the ROLLUP
+ operation has to be written into a temporary table, e.g. when
+ ROLLUP is used together with DISTINCT in the SELECT list.
+ Usually when creating temporary tables for a intermidiate
+ result we do not include fields for constant expressions.
+
+ @retval
+ 0 if ok
+ @retval
+ 1 on error
+*/
+
+bool JOIN::rollup_process_const_fields()
+{
+ ORDER *group_tmp;
+ Item *item;
+ List_iterator<Item> it(all_fields);
+
+ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
+ {
+ if (!(*group_tmp->item)->const_item())
+ continue;
+ while ((item= it++))
+ {
+ if (*group_tmp->item == item)
+ {
+ Item* new_item= new Item_func_rollup_const(item);
+ if (!new_item)
+ return 1;
+ new_item->fix_fields(thd, (Item **) 0);
+ thd->change_item_tree(it.ref(), new_item);
+ for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
+ {
+ if (*tmp->item == item)
+ thd->change_item_tree(tmp->item, new_item);
+ }
+ break;
+ }
+ }
+ it.rewind();
+ }
+ return 0;
+}
/**
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 0b9aa3576c7..e44d416380e 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -61,6 +61,8 @@ class store_key;
typedef struct st_table_ref
{
bool key_err;
+ /** True if something was read into buffer in join_read_key. */
+ bool has_record;
uint key_parts; ///< num of ...
uint key_length; ///< length of key_buff
int key; ///< key no
@@ -88,6 +90,11 @@ typedef struct st_table_ref
table_map depend_map; ///< Table depends on these tables.
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
uchar *null_ref_key;
+ /*
+ The number of times the record associated with this key was used
+ in the join.
+ */
+ ha_rows use_count;
} TABLE_REF;
@@ -515,6 +522,7 @@ public:
}
bool rollup_init();
+ bool rollup_process_const_fields();
bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
Item_sum ***func);
int rollup_send_data(uint idx);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1747da1a149..413733c0148 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1835,10 +1835,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
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)
+ if (tmp->query())
{
- uint length= min(max_query_length, tmp->query_length);
- thd_info->query=(char*) thd->strmake(tmp->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);
@@ -1963,11 +1963,11 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
pthread_mutex_unlock(&mysys_var->mutex);
/* INFO */
- if (tmp->query)
+ if (tmp->query())
{
- table->field[7]->store(tmp->query,
+ table->field[7]->store(tmp->query(),
min(PROCESS_LIST_INFO_WIDTH,
- tmp->query_length), cs);
+ tmp->query_length()), cs);
table->field[7]->set_notnull();
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8fd80d04af9..cb9ff6163a8 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2089,7 +2089,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
tables). In this case, we can write the original query into
the binary log.
*/
- write_bin_log(thd, !error, thd->query, thd->query_length);
+ write_bin_log(thd, !error, thd->query(), thd->query_length());
}
else if (thd->current_stmt_binlog_row_based &&
tmp_table_deleted)
@@ -3554,7 +3554,7 @@ static inline void write_create_table_bin_log(THD *thd,
(!thd->current_stmt_binlog_row_based ||
(thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
@@ -5337,14 +5337,14 @@ binlog:
write_bin_log(thd, TRUE, query.ptr(), query.length());
}
else // Case 1
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
/*
Case 3 and 4 does nothing under RBR
*/
}
else
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= FALSE;
@@ -5432,7 +5432,7 @@ mysql_discard_or_import_tablespace(THD *thd,
error=1;
if (error)
goto err;
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
err:
ha_autocommit_or_rollback(thd, error);
@@ -6441,7 +6441,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, FALSE, 0);
mysql_bin_log.write(&qinfo);
}
@@ -6695,7 +6695,7 @@ view_err:
if (!error)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd);
}
else if (error > 0)
@@ -7185,7 +7185,7 @@ view_err:
goto err1;
/* We don't replicate alter table statement on temporary tables */
if (!thd->current_stmt_binlog_row_based)
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
goto end_temporary;
}
@@ -7342,13 +7342,13 @@ view_err:
DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, table_name);
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
thd->current_stmt_binlog_row_based &&
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
{
diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc
index 9fec0e3bc63..fcc442a8f9a 100644
--- a/sql/sql_tablespace.cc
+++ b/sql/sql_tablespace.cc
@@ -66,6 +66,6 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
ha_resolve_storage_engine_name(hton),
"TABLESPACE or LOGFILE GROUP");
}
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index c055268ecca..a251a533622 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -409,7 +409,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
*/
result= FALSE;
/* Still, we need to log the query ... */
- stmt_query.append(thd->query, thd->query_length);
+ stmt_query.append(thd->query(), thd->query_length());
goto end;
}
}
@@ -918,7 +918,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
List_iterator<LEX_STRING> it_connection_cl_name(connection_cl_names);
List_iterator<LEX_STRING> it_db_cl_name(db_cl_names);
- stmt_query->append(thd->query, thd->query_length);
+ stmt_query->append(thd->query(), thd->query_length());
while ((name= it_name++))
{
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index c60dac42fb8..c6b41b59a3f 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -506,7 +506,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
rw_unlock(&THR_LOCK_udf);
/* Binlog the create function. */
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
DBUG_RETURN(0);
@@ -581,7 +581,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
rw_unlock(&THR_LOCK_udf);
/* Binlog the drop function. */
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
DBUG_RETURN(0);
err:
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 152613c0009..cfa383ce9cb 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -810,7 +810,7 @@ int mysql_update(THD *thd,
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_table, FALSE, errcode))
{
error=1; // Rollback update
@@ -1696,6 +1696,11 @@ bool multi_update::send_data(List<Item> &not_used_values)
TRG_EVENT_UPDATE))
DBUG_RETURN(1);
+ /*
+ Reset the table->auto_increment_field_not_null as it is valid for
+ only one row.
+ */
+ table->auto_increment_field_not_null= FALSE;
found++;
if (!can_compare_record || compare_record(table))
{
@@ -1860,7 +1865,7 @@ void multi_update::abort()
*/
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= TRUE;
@@ -2093,7 +2098,7 @@ bool multi_update::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode))
{
local_error= 1; // Rollback update
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 43d0b9fade0..ae3af0640a3 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1652,7 +1652,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
/* if something goes wrong, bin-log with possible error code,
otherwise bin-log with error code cleared.
*/
- write_bin_log(thd, !something_wrong, thd->query, thd->query_length);
+ write_bin_log(thd, !something_wrong, thd->query(), thd->query_length());
}
VOID(pthread_mutex_unlock(&LOCK_open));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4b2d4634ee7..1b85e5afdce 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9117,8 +9117,7 @@ procedure_clause:
MYSQL_YYABORT;
}
- if (&lex->select_lex != lex->current_select ||
- lex->select_lex.get_table_list()->derived)
+ if (&lex->select_lex != lex->current_select)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
MYSQL_YYABORT;
@@ -10698,7 +10697,7 @@ param_marker:
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
MYSQL_YYABORT;
}
- item= new (thd->mem_root) Item_param((uint) (lip->get_tok_start() - thd->query));
+ item= new (thd->mem_root) Item_param((uint) (lip->get_tok_start() - thd->query()));
if (!($$= item) || lex->param_list.push_back(item))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
diff --git a/sql/structs.h b/sql/structs.h
index bcda7b1e787..d54921791a1 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -118,16 +118,22 @@ typedef struct st_reginfo { /* Extra info about reg */
} REGINFO;
-struct st_read_record; /* For referense later */
class SQL_SELECT;
class THD;
class handler;
+struct st_join_table;
+
+void rr_unlock_row(st_join_table *tab);
-typedef struct st_read_record { /* Parameter to read_record */
+struct READ_RECORD { /* Parameter to read_record */
+ typedef int (*Read_func)(READ_RECORD*);
+ typedef void (*Unlock_row_func)(st_join_table *);
struct st_table *table; /* Head-form */
handler *file;
struct st_table **forms; /* head and ref forms */
- int (*read_record)(struct st_read_record *);
+
+ Read_func read_record;
+ Unlock_row_func unlock_row;
THD *thd;
SQL_SELECT *select;
uint cache_records;
@@ -139,7 +145,7 @@ typedef struct st_read_record { /* Parameter to read_record */
uchar *cache,*cache_pos,*cache_end,*read_positions;
IO_CACHE *io_cache;
bool print_error, ignore_not_found_rows;
-} READ_RECORD;
+};
/*
diff --git a/sql/time.cc b/sql/time.cc
index 962b65e454c..8b554beb94b 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -965,20 +965,22 @@ calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *s
0 - a == b
1 - a > b
- NOTES
- TIME.second_part is not considered during comparison
*/
-int
-my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
+int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
{
- my_ulonglong a_t= TIME_to_ulonglong_datetime(a);
- my_ulonglong b_t= TIME_to_ulonglong_datetime(b);
+ ulonglong a_t= TIME_to_ulonglong_datetime(a);
+ ulonglong b_t= TIME_to_ulonglong_datetime(b);
+ if (a_t < b_t)
+ return -1;
if (a_t > b_t)
return 1;
- else if (a_t < b_t)
+
+ if (a->second_part < b->second_part)
return -1;
+ if (a->second_part > b->second_part)
+ return 1;
return 0;
}
diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc
index 357496fe095..e3ba111043b 100644
--- a/storage/blackhole/ha_blackhole.cc
+++ b/storage/blackhole/ha_blackhole.cc
@@ -105,7 +105,7 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data)
{
DBUG_ENTER("ha_blackhole::update_row");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
@@ -114,7 +114,7 @@ int ha_blackhole::delete_row(const uchar *buf)
{
DBUG_ENTER("ha_blackhole::delete_row");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
@@ -130,7 +130,7 @@ int ha_blackhole::rnd_next(uchar *buf)
{
DBUG_ENTER("ha_blackhole::rnd_next");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -212,7 +212,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -224,7 +224,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read_idx");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -235,7 +235,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read_last");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a8b9b678282..41d76c5ec55 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -41,7 +41,7 @@ have disabled the InnoDB inlining in this file. */
#include <mysql/plugin.h>
#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
extern pthread_mutex_t LOCK_thread_count;
#endif /* MYSQL_SERVER */
@@ -54,6 +54,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
/*
@@ -1932,6 +1933,7 @@ innobase_init(
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
@@ -1971,6 +1973,7 @@ innobase_end(handlerton *hton, ha_panic_function type)
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
@@ -2215,6 +2218,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -3240,7 +3245,10 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
CHARSET_INFO* cs;
ulint key_len;
@@ -5186,7 +5194,7 @@ create_table_def(
if (dict_col_name_is_reserved(field->field_name)){
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"Error creating table '%s' with "
"column name '%s'. '%s' is a "
@@ -5433,13 +5441,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -5595,18 +5605,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -6428,9 +6442,15 @@ ha_innobase::analyze(
THD* thd, /* in: connection thread handle */
HA_CHECK_OPT* check_opt) /* in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
@@ -7027,8 +7047,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(current_thd);
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -7865,6 +7886,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -7873,11 +7895,12 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -8502,7 +8525,7 @@ innobase_index_name_is_reserved(
innobase_index_reserve_name) == 0) {
/* Push warning to mysql */
push_warning_printf((THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"Cannot Create Index with name "
"'%s'. The name is reserved "
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 8ca72ee1a60..9ddb516c3dc 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -252,4 +252,11 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
index a99fe8b6a0e..f00475fc528 100644
--- a/storage/innobase/os/os0proc.c
+++ b/storage/innobase/os/os0proc.c
@@ -591,6 +591,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index d0364c9c568..4fcb1fbf9f2 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -2089,7 +2089,7 @@ Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
constraints which reference this table are ok. */
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 0f8f4c4d071..70225ffd9d9 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,9 +1,89 @@
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#47125 auto_increment start value is ignored if an index is
+ created and engine=innodb
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47777.result,
+ mysql-test/innodb_bug47777.test:
+ Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <=
+ original_buf + buf_len
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#38996 Race condition in ANALYZE TABLE
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix bug#42383: Can't create table 'test.bug39438'
+
+2009-10-29 The InnoDB Team
+
+ * os/os0proc.c:
+ Fix Bug#48237 Error handling in os_mem_alloc_large appears to
+ be incorrect
+
+2009-10-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic:
+ Fix corruption of the buf_pool->LRU_old list and improve debug
+ assertions.
+
+2009-10-28 The InnoDB Team
+
+ * srv/srv0start.c:
+ Fix Bug#41490 After enlargement of InnoDB page size, the error message
+ become inaccurate
+
+2009-10-26 The InnoDB Team
+
+ * row/row0ins.c:
+ When allocating a data tuple, zero out the system fields in order
+ to avoid Valgrind warnings about uninitialized fields in
+ dtuple_validate().
+
+2009-10-22 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-zip.result,
+ mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test:
+ Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR)
+
+2009-10-19 The InnoDB Team
+
+ * mysql-test/innodb_information_schema.test:
+ Fix Bug#47808 innodb_information_schema.test fails when run under
+ valgrind
+
+2009-10-15 The InnoDB Team
+
+ * include/page0page.ic:
+ Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
+ cc/CC 5.10
+
+2009-10-05 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Do not invalidate buffer pool while an LRU batch is active. Added code
+ to buf_pool_invalidate() to wait for the running batches to finish.
+
+2009-10-01 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#47763 typo in error message: Failed to open table %s after %lu
+ attemtps.
+
2009-10-01 The InnoDB Team
* fsp/fsp0fsp.c, row/row0merge.c:
- Clean up after a crash during DROP INDEX. When InnoDB crashes
+ Clean up after a crash during DROP INDEX. When InnoDB crashes
while dropping an index, ensure that the index will be completely
- dropped during crash recovery. The MySQL .frm file may still
+ dropped during crash recovery. The MySQL .frm file may still
contain the dropped index, but there is little that we can do
about it.
@@ -20,15 +100,15 @@
include/page0zip.h, page/page0cur.c, page/page0page.c,
page/page0zip.c:
Do not write to PAGE_INDEX_ID when restoring an uncompressed page
- after a compression failure. The field should only be written
- when creating a B-tree page. This fix addresses a race condition
+ after a compression failure. The field should only be written
+ when creating a B-tree page. This fix addresses a race condition
in a debug assertion.
2009-09-28 The InnoDB Team
* fil/fil0fil.c:
Try to prevent the reuse of tablespace identifiers after InnoDB
- has crashed during table creation. Also, refuse to start if files
+ has crashed during table creation. Also, refuse to start if files
with duplicate tablespace identifiers are encountered.
2009-09-25 The InnoDB Team
diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
index d87abbd0ed9..ff31457d200 100644
--- a/storage/innodb_plugin/buf/buf0buf.c
+++ b/storage/innodb_plugin/buf/buf0buf.c
@@ -1163,10 +1163,15 @@ buf_relocate(
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
whose "old" flag is set. */
+ ut_a(buf_pool->LRU_old->old);
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
+ } else {
+ /* Check that the "old" flag is consistent in
+ the block and its neighbours. */
+ buf_page_set_old(dpage, buf_page_is_old(dpage));
#endif /* UNIV_LRU_DEBUG */
}
diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c
index 74dd0c07ca6..8b614ce90e5 100644
--- a/storage/innodb_plugin/buf/buf0flu.c
+++ b/storage/innodb_plugin/buf/buf0flu.c
@@ -304,6 +304,28 @@ buf_flush_write_complete(
}
/********************************************************************//**
+Flush a batch of writes to the datafiles that have already been
+written by the OS. */
+static
+void
+buf_flush_sync_datafiles(void)
+/*==========================*/
+{
+ /* Wake possible simulated aio thread to actually post the
+ writes to the operating system */
+ os_aio_simulated_wake_handler_threads();
+
+ /* Wait that all async writes to tablespaces have been posted to
+ the OS */
+ os_aio_wait_until_no_pending_writes();
+
+ /* Now we flush the data to disk (for example, with fsync) */
+ fil_flush_file_spaces(FIL_TABLESPACE);
+
+ return;
+}
+
+/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@@ -320,8 +342,8 @@ buf_flush_buffered_writes(void)
ulint i;
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
- os_aio_simulated_wake_handler_threads();
-
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
return;
}
@@ -529,22 +551,10 @@ flush:
buf_LRU_stat_inc_io();
}
- /* Wake possible simulated aio thread to actually post the
- writes to the operating system */
-
- os_aio_simulated_wake_handler_threads();
-
- /* Wait that all async writes to tablespaces have been posted to
- the OS */
-
- os_aio_wait_until_no_pending_writes();
-
- /* Now we flush the data to disk (for example, with fsync) */
-
- fil_flush_file_spaces(FIL_TABLESPACE);
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
/* We can now reuse the doublewrite memory buffer: */
-
trx_doublewrite->first_free = 0;
mutex_exit(&(trx_doublewrite->mutex));
diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
index d3a79d62d3f..4f19fd13fa5 100644
--- a/storage/innodb_plugin/buf/buf0lru.c
+++ b/storage/innodb_plugin/buf/buf0lru.c
@@ -978,14 +978,14 @@ buf_LRU_old_adjust_len(void)
#ifdef UNIV_LRU_DEBUG
ut_a(!LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(LRU_old, TRUE);
old_len = ++buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, TRUE);
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
- buf_page_set_old(LRU_old, FALSE);
buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
old_len = --buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, FALSE);
} else {
return;
}
@@ -1009,13 +1009,13 @@ buf_LRU_old_init(void)
the adjust function to move the LRU_old pointer to the right
position */
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- while (bpage != NULL) {
+ for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_PREV(LRU, bpage)) {
ut_ad(bpage->in_LRU_list);
ut_ad(buf_page_in_file(bpage));
- buf_page_set_old(bpage, TRUE);
- bpage = UT_LIST_GET_NEXT(LRU, bpage);
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = TRUE;
}
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -1091,10 +1091,19 @@ buf_LRU_remove_block(
buf_unzip_LRU_remove_block_if_needed(bpage);
- /* If the LRU list is so short that LRU_old not defined, return */
+ /* If the LRU list is so short that LRU_old is not defined,
+ clear the "old" flags and return */
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
+ for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = FALSE;
+ }
+
buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
return;
}
@@ -1155,14 +1164,13 @@ buf_LRU_add_block_to_end_low(
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
ut_d(bpage->in_LRU_list = TRUE);
- buf_page_set_old(bpage, TRUE);
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, TRUE);
buf_pool->LRU_old_len++;
buf_LRU_old_adjust_len();
@@ -1171,8 +1179,9 @@ buf_LRU_add_block_to_end_low(
/* The LRU list is now long enough for LRU_old to become
defined: init it */
- buf_pool->LRU_old_len++;
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1223,14 +1232,13 @@ buf_LRU_add_block_low(
ut_d(bpage->in_LRU_list = TRUE);
- buf_page_set_old(bpage, old);
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, old);
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1239,6 +1247,8 @@ buf_LRU_add_block_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1436,15 +1446,6 @@ alloc:
buf_pool->LRU_old = b;
}
-#ifdef UNIV_LRU_DEBUG
- ut_a(prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || UT_LIST_GET_NEXT(LRU, b)->old);
- } else {
- ut_a(!prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || !UT_LIST_GET_NEXT(LRU, b)->old);
-#endif /* UNIV_LRU_DEBUG */
}
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
@@ -1460,6 +1461,11 @@ alloc:
defined: init it */
buf_LRU_old_init();
}
+#ifdef UNIV_LRU_DEBUG
+ /* Check that the "old" flag is consistent
+ in the block and its neighbours. */
+ buf_page_set_old(b, buf_page_is_old(b));
+#endif /* UNIV_LRU_DEBUG */
} else {
ut_d(b->in_LRU_list = FALSE);
buf_LRU_add_block_low(b, buf_page_is_old(b));
@@ -1966,19 +1972,24 @@ buf_LRU_validate(void)
}
if (buf_page_is_old(bpage)) {
- old_len++;
- }
+ const buf_page_t* prev
+ = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next
+ = UT_LIST_GET_NEXT(LRU, bpage);
+
+ if (!old_len++) {
+ ut_a(buf_pool->LRU_old == bpage);
+ } else {
+ ut_a(!prev || buf_page_is_old(prev));
+ }
- if (buf_pool->LRU_old && (old_len == 1)) {
- ut_a(buf_pool->LRU_old == bpage);
+ ut_a(!next || buf_page_is_old(next));
}
bpage = UT_LIST_GET_NEXT(LRU, bpage);
}
- if (buf_pool->LRU_old) {
- ut_a(buf_pool->LRU_old_len == old_len);
- }
+ ut_a(buf_pool->LRU_old_len == old_len);
UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
ut_ad(ut_list_node_313->in_free_list));
diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
index df6dad86990..ba6f2f8666f 100644
--- a/storage/innodb_plugin/fil/fil0fil.c
+++ b/storage/innodb_plugin/fil/fil0fil.c
@@ -659,6 +659,7 @@ fil_node_open_file(
#ifdef UNIV_HOTBACKUP
if (space->id == 0) {
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+ os_file_close(node->handle);
goto add_size;
}
#endif /* UNIV_HOTBACKUP */
@@ -3244,7 +3245,7 @@ fil_load_single_table_tablespace(
fprintf(stderr,
"InnoDB: Renaming tablespace %s of id %lu,\n"
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
- "InnoDB: because its size %lld is too small"
+ "InnoDB: because its size %" PRId64 " is too small"
" (< 4 pages 16 kB each),\n"
"InnoDB: or the space id in the file header"
" is not sensible.\n"
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 8ac804ca9b6..ac710ea2b15 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -110,7 +110,7 @@ extern "C" {
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
@@ -129,6 +129,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
#define INSIDE_HA_INNOBASE_CC
@@ -229,21 +230,6 @@ static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
-/***********************************************************************
-This function checks each index name for a table against reserved
-system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
-this function pushes an error message to the client, and returns true. */
-static
-bool
-innobase_index_name_is_reserved(
-/*============================*/
- /* out: true if index name matches a
- reserved name */
- const trx_t* trx, /* in: InnoDB transaction handle */
- const TABLE* form, /* in: information on table
- columns and indexes */
- const char* norm_name); /* in: table name */
-
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
system primary index. */
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
@@ -2266,6 +2252,7 @@ innobase_change_buffering_inited_ok:
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -2320,6 +2307,7 @@ innobase_end(
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
@@ -2598,6 +2586,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -3758,7 +3748,10 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
CHARSET_INFO* cs;
ulint key_len;
@@ -5688,7 +5681,7 @@ create_table_def(
number fits in one byte in prtype */
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"In InnoDB, charset-collation codes"
" must be below 256."
@@ -5722,7 +5715,7 @@ create_table_def(
if (dict_col_name_is_reserved(field->field_name)){
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"Error creating table '%s' with "
"column name '%s'. '%s' is a "
@@ -5956,7 +5949,7 @@ create_options_are_valid(
/* Valid value. */
break;
default:
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid"
" KEY_BLOCK_SIZE = %lu."
@@ -5970,7 +5963,7 @@ create_options_are_valid(
/* If KEY_BLOCK_SIZE was specified, check for its
dependencies. */
if (kbs_specified && !srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_per_table.");
@@ -5978,7 +5971,7 @@ create_options_are_valid(
}
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format >"
@@ -6002,7 +5995,7 @@ create_options_are_valid(
if (!srv_file_per_table) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_per_table.",
@@ -6014,7 +6007,7 @@ create_options_are_valid(
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format >"
@@ -6031,7 +6024,7 @@ create_options_are_valid(
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = DYNAMIC with"
@@ -6055,7 +6048,7 @@ create_options_are_valid(
if (kbs_specified) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = %s with"
@@ -6068,7 +6061,7 @@ create_options_are_valid(
default:
push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid ROW_FORMAT specifier.");
ret = FALSE;
@@ -6132,13 +6125,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -6342,7 +6337,8 @@ ha_innobase::create(
/* Check for name conflicts (with reserved name) for
any user indices to be created. */
- if (innobase_index_name_is_reserved(trx, form, norm_name)) {
+ if (innobase_index_name_is_reserved(trx, form->key_info,
+ form->s->keys)) {
error = -1;
goto cleanup;
}
@@ -6429,18 +6425,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -7294,9 +7294,15 @@ ha_innobase::analyze(
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
@@ -7891,8 +7897,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8772,6 +8779,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -8780,11 +8788,12 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -9803,36 +9812,39 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
/***********************************************************************
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
-this function pushes an error message to the client, and returns true. */
-static
+this function pushes an warning message to the client, and returns true. */
+extern "C" UNIV_INTERN
bool
innobase_index_name_is_reserved(
/*============================*/
/* out: true if an index name
matches the reserved name */
const trx_t* trx, /* in: InnoDB transaction handle */
- const TABLE* form, /* in: information on table
- columns and indexes */
- const char* norm_name) /* in: table name */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys) /* in: Number of indexes to
+ be created. */
{
- KEY* key;
+ const KEY* key;
uint key_num; /* index number */
- for (key_num = 0; key_num < form->s->keys; key_num++) {
- key = form->key_info + key_num;
+ for (key_num = 0; key_num < num_of_keys; key_num++) {
+ key = &key_info[key_num];
if (innobase_strcasecmp(key->name,
innobase_index_reserve_name) == 0) {
/* Push warning to mysql */
push_warning_printf((THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_CANT_CREATE_TABLE,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_NAME_FOR_INDEX,
"Cannot Create Index with name "
"'%s'. The name is reserved "
"for the system default primary "
"index.",
innobase_index_reserve_name);
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ innobase_index_reserve_name);
+
return(true);
}
}
diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h
index cc98003f8ff..4779651ee27 100644
--- a/storage/innodb_plugin/handler/ha_innodb.h
+++ b/storage/innodb_plugin/handler/ha_innodb.h
@@ -257,6 +257,13 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
typedef struct trx_struct trx_t;
@@ -282,3 +289,21 @@ trx_t*
innobase_trx_allocate(
/*==================*/
MYSQL_THD thd); /*!< in: user thread handle */
+
+
+/*********************************************************************//**
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name
+matches, this function pushes an warning message to the client,
+and returns true. */
+extern "C"
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if the index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys); /* in: Number of indexes to
+ be created. */
+
diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc
index 1aa0e6b126c..37aed06b28a 100644
--- a/storage/innodb_plugin/handler/handler0alter.cc
+++ b/storage/innodb_plugin/handler/handler0alter.cc
@@ -628,7 +628,7 @@ ha_innobase::add_index(
ulint num_created = 0;
ibool dict_locked = FALSE;
ulint new_primary;
- ulint error;
+ int error;
DBUG_ENTER("ha_innobase::add_index");
ut_a(table);
@@ -656,9 +656,13 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
- /* Check that index keys are sensible */
-
- error = innobase_check_index_keys(key_info, num_of_keys);
+ /* Check if the index name is reserved. */
+ if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
+ error = -1;
+ } else {
+ /* Check that index keys are sensible */
+ error = innobase_check_index_keys(key_info, num_of_keys);
+ }
if (UNIV_UNLIKELY(error)) {
err_exit:
diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
index e9d95a14f1b..927ff893e39 100644
--- a/storage/innodb_plugin/include/buf0buf.h
+++ b/storage/innodb_plugin/include/buf0buf.h
@@ -1129,7 +1129,7 @@ struct buf_page_struct{
debugging */
#endif /* UNIV_DEBUG */
unsigned old:1; /*!< TRUE if the block is in the old
- blocks in the LRU list */
+ blocks in buf_pool->LRU_old */
unsigned freed_page_clock:31;/*!< the value of
buf_pool->freed_page_clock
when this block was the last
@@ -1393,8 +1393,7 @@ struct buf_pool_struct{
the block to which LRU_old points
onward, including that block;
see buf0lru.c for the restrictions
- on this value; not defined if
- LRU_old == NULL;
+ on this value; 0 if LRU_old == NULL;
NOTE: LRU_old_len must be adjusted
whenever LRU_old shrinks or grows! */
diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
index 8b1f904a090..0f92a59a1c7 100644
--- a/storage/innodb_plugin/include/buf0buf.ic
+++ b/storage/innodb_plugin/include/buf0buf.ic
@@ -466,10 +466,19 @@ buf_page_set_old(
ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
- && UT_LIST_GET_PREV(LRU, bpage)->old
- == UT_LIST_GET_NEXT(LRU, bpage)->old) {
- ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
+ ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
+ /* If a block is flagged "old", the LRU_old list must exist. */
+ ut_a(!old || buf_pool->LRU_old);
+
+ if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
+ const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
+ if (prev->old == next->old) {
+ ut_a(prev->old == old);
+ } else {
+ ut_a(!prev->old);
+ ut_a(buf_pool->LRU_old == (old ? bpage : next));
+ }
}
#endif /* UNIV_LRU_DEBUG */
diff --git a/storage/innodb_plugin/include/page0page.ic b/storage/innodb_plugin/include/page0page.ic
index 318ec1cc1f2..8f794410f20 100644
--- a/storage/innodb_plugin/include/page0page.ic
+++ b/storage/innodb_plugin/include/page0page.ic
@@ -907,7 +907,7 @@ page_get_data_size(
/************************************************************//**
Allocates a block of memory from the free list of an index page. */
-UNIV_INTERN
+UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h
index 6d5d195172e..b05241f00f8 100644
--- a/storage/innodb_plugin/include/row0mysql.h
+++ b/storage/innodb_plugin/include/row0mysql.h
@@ -756,8 +756,6 @@ struct row_prebuilt_struct {
store it here so that we can return
it to MySQL */
/*----------------------*/
- UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
- /*!< list node of table->prebuilts */
ulint magic_n2; /*!< this should be the same as
magic_n */
};
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index 0e14f7b1cba..5d0361658af 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -237,7 +237,7 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP)
+#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
#else
# define UNIV_INTERN
diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c
index a1d3bad2add..0cb76d1796f 100644
--- a/storage/innodb_plugin/os/os0file.c
+++ b/storage/innodb_plugin/os/os0file.c
@@ -832,6 +832,23 @@ next_file:
ret = stat(full_path, &statinfo);
if (ret) {
+
+ if (errno == ENOENT) {
+ /* readdir() returned a file that does not exist,
+ it must have been deleted in the meantime. Do what
+ would have happened if the file was deleted before
+ readdir() - ignore and go to the next entry.
+ If this is the last entry then info->name will still
+ contain the name of the deleted file when this
+ function returns, but this is not an issue since the
+ caller shouldn't be looking at info when end of
+ directory is returned. */
+
+ ut_free(full_path);
+
+ goto next_file;
+ }
+
os_file_handle_error_no_exit(full_path, "stat");
ut_free(full_path);
diff --git a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c
index a0ea9a1b258..48922886f23 100644
--- a/storage/innodb_plugin/os/os0proc.c
+++ b/storage/innodb_plugin/os/os0proc.c
@@ -97,6 +97,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index ab3ae70e3e2..fe51fce82c4 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -141,7 +141,7 @@ row_ins_alloc_sys_fields(
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
@@ -152,7 +152,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
@@ -163,7 +163,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index 819381fc280..540a4450045 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -2068,7 +2068,7 @@ Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
constraints which reference this table are ok.
@return error code or DB_SUCCESS */
diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
index 37263317126..796541a9f1a 100644
--- a/storage/innodb_plugin/srv/srv0start.c
+++ b/storage/innodb_plugin/srv/srv0start.c
@@ -1376,7 +1376,7 @@ innobase_start_or_create_for_mysql(void)
sum_of_new_sizes += srv_data_file_sizes[i];
}
- if (sum_of_new_sizes < 640) {
+ if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: tablespace size must be"
" at least 10 MB\n");
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 931face3dc2..cdfbf16db99 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -115,6 +115,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
Also we likely need to lock mutex here (in both cases with protocol and
push_warning).
*/
+#ifdef THREAD
+ if (param->need_print_msg_lock)
+ pthread_mutex_lock(&param->print_msg_mutex);
+#endif
protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info);
@@ -123,6 +127,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
+#ifdef THREAD
+ if (param->need_print_msg_lock)
+ pthread_mutex_unlock(&param->print_msg_mutex);
+#endif
return;
}
@@ -1403,8 +1411,8 @@ bool ha_myisam::check_and_repair(THD *thd)
check_opt.flags|=T_QUICK;
sql_print_warning("Checking table: '%s'",table->s->path.str);
- old_query= thd->query;
- old_query_length= thd->query_length;
+ old_query= thd->query();
+ old_query_length= thd->query_length();
thd->set_query(table->s->table_name.str,
(uint) table->s->table_name.length);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 8f7b1399aa2..c10cfdd0c9b 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param)
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+#ifdef THREAD
+ param->need_print_msg_lock= 0;
+#endif
}
/* Check the status flags for the table */
@@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
/* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0);
+ pthread_mutex_init(&param->print_msg_mutex, MY_MUTEX_INIT_FAST);
+ param->need_print_msg_lock= 1;
if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks,
@@ -3108,6 +3113,8 @@ err:
pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex);
+ pthread_mutex_destroy(&param->print_msg_mutex);
+ param->need_print_msg_lock= 0;
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index fb16af9cddf..b450d27de66 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -466,8 +466,12 @@ ok:
Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will
also indicate EOF to the readers.
+ That means that a writer always gets here first and readers -
+ only when they see EOF. But if a reader finishes prematurely
+ because of an error it may reach this earlier - don't allow it
+ to detach the writer thread.
*/
- if (sort_param->sort_info->info->rec_cache.share)
+ if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
@@ -789,6 +793,7 @@ cleanup:
close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
{
+ DBUG_ASSERT(t_file2.type == WRITE_CACHE);
*t_file=t_file2; /* Copy result file */
t_file->current_pos= &t_file->write_pos;
t_file->current_end= &t_file->write_end;
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index bc8adf6fd32..11e8c1cc191 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -14831,7 +14831,7 @@ void Dblqh::srLogLimits(Signal* signal)
while(true) {
ndbrequire(tmbyte < clogFileSize);
if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) {
- if (logFilePtr.p->logMaxGciCompleted[tmbyte] < logPartPtr.p->logLastGci) {
+ if (logFilePtr.p->logMaxGciCompleted[tmbyte] <= logPartPtr.p->logLastGci) {
jam();
/* --------------------------------------------------------------------
* WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 2ea48ddab2f..6ae0cc3a293 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -7858,6 +7858,9 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
return 1;
}
+ if (!cs->caseinfo)
+ cs->caseinfo= my_unicase_default;
+
if (!(newweights= (uint16**) (*alloc)(256*sizeof(uint16*))))
return 1;
bzero(newweights, 256*sizeof(uint16*));
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 579685204e8..a7b10f5d587 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -46,6 +46,9 @@ static char *opt_user= 0;
static char *opt_password= 0;
static char *opt_host= 0;
static char *opt_unix_socket= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static unsigned int opt_port;
static my_bool tty_password= 0, opt_silent= 0;
@@ -230,6 +233,26 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
}
}
+/*
+ Enhanced version of mysql_client_init(), which may also set shared memory
+ base on Windows.
+*/
+static MYSQL *mysql_client_init(MYSQL* con)
+{
+ MYSQL* res = mysql_init(con);
+#ifdef HAVE_SMEM
+ if (res && shared_memory_base_name)
+ mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
+#endif
+ return res;
+}
+
+/*
+ Disable direct calls of mysql_init, as it disregards shared memory base.
+*/
+#define mysql_init(A) Please use mysql_client_init instead of mysql_init
+
+
/* Check if the connection has InnoDB tables */
static my_bool check_have_innodb(MYSQL *conn)
@@ -293,10 +316,10 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
fprintf(stdout, "\n Establishing a connection to '%s' ...",
opt_host ? opt_host : "");
- if (!(mysql= mysql_init(NULL)))
+ if (!(mysql= mysql_client_init(NULL)))
{
opt_silent= 0;
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
/* enable local infile, in non-binary builds often disabled by default */
@@ -1160,9 +1183,9 @@ static my_bool thread_query(char *query)
error= 0;
if (!opt_silent)
fprintf(stdout, "\n in thread_query(%s)", query);
- if (!(l_mysql= mysql_init(NULL)))
+ if (!(l_mysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
return 1;
}
if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
@@ -2512,9 +2535,9 @@ static void test_ps_query_cache()
case TEST_QCACHE_ON_WITH_OTHER_CONN:
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- printf("mysql_init() failed");
+ printf("mysql_client_init() failed");
DIE_UNLESS(0);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -4960,9 +4983,9 @@ static void test_stmt_close()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -5851,9 +5874,9 @@ DROP TABLE IF EXISTS test_multi_tab";
rc= mysql_more_results(mysql);
DIE_UNLESS(rc == 0);
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -5976,9 +5999,9 @@ static void test_prepare_multi_statements()
char query[MAX_TEST_QUERY_LENGTH];
myheader("test_prepare_multi_statements");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stderr, "\n mysql_init() failed");
+ fprintf(stderr, "\n mysql_client_init() failed");
exit(1);
}
@@ -7459,9 +7482,9 @@ static void test_prepare_grant()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
@@ -7915,9 +7938,9 @@ static void test_drop_temp()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -13159,7 +13182,7 @@ static void test_bug15518()
int rc;
myheader("test_bug15518");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -13315,9 +13338,9 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
@@ -13856,7 +13879,7 @@ static void test_bug9992()
if (!opt_silent)
printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -14445,9 +14468,9 @@ static void test_bug12001()
myheader("test_bug12001");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -15172,9 +15195,9 @@ static void test_opt_reconnect()
myheader("test_opt_reconnect");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -15209,9 +15232,9 @@ static void test_opt_reconnect()
mysql_close(lmysql);
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
DIE_UNLESS(0);
}
@@ -15246,7 +15269,7 @@ static void test_bug12744()
int rc;
myheader("test_bug12744");
- lmysql= mysql_init(NULL);
+ lmysql= mysql_client_init(NULL);
DIE_UNLESS(lmysql);
if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
@@ -15819,7 +15842,7 @@ static void test_bug15752()
rc= mysql_query(mysql, "create procedure p1() select 1");
myquery(rc);
- mysql_init(&mysql_local);
+ mysql_client_init(&mysql_local);
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket,
@@ -16705,7 +16728,7 @@ static void test_bug29692()
{
MYSQL* conn;
- if (!(conn= mysql_init(NULL)))
+ if (!(conn= mysql_client_init(NULL)))
{
myerror("test_bug29692 init failed");
exit(1);
@@ -16840,7 +16863,7 @@ static void test_bug30472()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17014,7 +17037,7 @@ static void test_bug20023()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17151,7 +17174,7 @@ static void bug31418_impl()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -18001,7 +18024,7 @@ static void test_bug44495()
"END;");
myquery(rc);
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
current_db, opt_port, opt_unix_socket,
@@ -18064,6 +18087,11 @@ static struct my_option client_test_long_options[] =
0, 0, 0, 0, 0, 0},
{"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", 'm', "Base name of shared memory.",
+ (uchar**) &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection",
(uchar **) &opt_unix_socket, (uchar **) &opt_unix_socket, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/vio/vio.c b/vio/vio.c
index e088687098b..fd8e2e5a402 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -43,7 +43,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if ((flags & VIO_BUFFERED_READ) &&
!(vio->read_buffer= (char*)my_malloc(VIO_READ_BUFFER_SIZE, MYF(MY_WME))))
flags&= ~VIO_BUFFERED_READ;
-#ifdef __WIN__
+#ifdef _WIN32
if (type == VIO_TYPE_NAMEDPIPE)
{
vio->viodelete =vio_delete;
@@ -59,9 +59,16 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ignore_timeout;
+
+ vio->timeout=vio_win32_timeout;
+ /* Set default timeout */
+ vio->read_timeout_millis = INFINITE;
+ vio->write_timeout_millis = INFINITE;
+
+ memset(&(vio->pipe_overlapped), 0, sizeof(OVERLAPPED));
+ vio->pipe_overlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
+ DBUG_VOID_RETURN;
}
- else /* default is VIO_TYPE_TCPIP */
#endif
#ifdef HAVE_SMEM
if (type == VIO_TYPE_SHARED_MEMORY)
@@ -79,9 +86,14 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ignore_timeout;
+
+ /* Currently, shared memory is on Windows only, hence the below is ok*/
+ vio->timeout= vio_win32_timeout;
+ /* Set default timeout */
+ vio->read_timeout_millis= INFINITE;
+ vio->write_timeout_millis= INFINITE;
+ DBUG_VOID_RETURN;
}
- else
#endif
#ifdef HAVE_OPENSSL
if (type == VIO_TYPE_SSL)
@@ -100,8 +112,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking;
vio->timeout =vio_timeout;
+ DBUG_VOID_RETURN;
}
- else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */
{
vio->viodelete =vio_delete;
@@ -193,7 +205,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
}
#ifdef HAVE_SMEM
-Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
+Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
HANDLE event_server_wrote, HANDLE event_server_read,
HANDLE event_client_wrote, HANDLE event_client_read,
HANDLE event_conn_closed)
@@ -212,7 +224,6 @@ Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_m
vio->event_conn_closed= event_conn_closed;
vio->shared_memory_remain= 0;
vio->shared_memory_pos= handle_map;
- vio->net= net;
strmov(vio->desc, "shared memory");
}
DBUG_RETURN(vio);
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index 792fad4cc66..21fa80143cd 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -25,7 +25,10 @@
#include <m_string.h>
#include <violite.h>
-void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
+#ifdef _WIN32
+void vio_win32_timeout(Vio *vio, uint which, uint timeout);
+#endif
+
void vio_timeout(Vio *vio,uint which, uint timeout);
#ifdef HAVE_OPENSSL
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 2d7fd0e08cd..c929cac2a05 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -261,19 +261,13 @@ int vio_close(Vio * vio)
{
int r=0;
DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else
-#endif /* __WIN__ */
+
if (vio->type != VIO_CLOSED)
{
+ DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP ||
+ vio->type == VIO_TYPE_SOCKET ||
+ vio->type == VIO_TYPE_SSL);
+
DBUG_ASSERT(vio->sd >= 0);
if (shutdown(vio->sd, SHUT_RDWR))
r= -1;
@@ -417,44 +411,97 @@ void vio_timeout(Vio *vio, uint which, uint timeout)
#ifdef __WIN__
-size_t vio_read_pipe(Vio * vio, uchar* buf, size_t size)
+
+/*
+ Finish pending IO on pipe. Honor wait timeout
+*/
+static int pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_millis)
{
DWORD length;
+ DWORD ret;
+
+ DBUG_ENTER("pipe_complete_io");
+
+ ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_millis);
+ /*
+ WaitForSingleObjects will normally return WAIT_OBJECT_O (success, IO completed)
+ or WAIT_TIMEOUT.
+ */
+ if(ret != WAIT_OBJECT_0)
+ {
+ CancelIo(vio->hPipe);
+ DBUG_PRINT("error",("WaitForSingleObject() returned %d", ret));
+ DBUG_RETURN(-1);
+ }
+
+ if (!GetOverlappedResult(vio->hPipe,&(vio->pipe_overlapped),&length, FALSE))
+ {
+ DBUG_PRINT("error",("GetOverlappedResult() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(length);
+}
+
+
+size_t vio_read_pipe(Vio * vio, uchar *buf, size_t size)
+{
+ DWORD bytes_read;
DBUG_ENTER("vio_read_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
+ if (!ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
+ &(vio->pipe_overlapped)))
+ {
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ DBUG_PRINT("error",("ReadFile() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN((size_t)-1);
+ }
+ bytes_read= pipe_complete_io(vio, buf, size,vio->read_timeout_millis);
+ }
- DBUG_PRINT("exit", ("%d", length));
- DBUG_RETURN((size_t) length);
+ DBUG_PRINT("exit", ("%d", bytes_read));
+ DBUG_RETURN(bytes_read);
}
size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
{
- DWORD length;
+ DWORD bytes_written;
DBUG_ENTER("vio_write_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
+ if (!WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
+ &(vio->pipe_overlapped)))
+ {
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ DBUG_PRINT("vio_error",("WriteFile() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN((size_t)-1);
+ }
+ bytes_written = pipe_complete_io(vio, (char *)buf, size,
+ vio->write_timeout_millis);
+ }
- DBUG_PRINT("exit", ("%d", length));
- DBUG_RETURN((size_t) length);
+ DBUG_PRINT("exit", ("%d", bytes_written));
+ DBUG_RETURN(bytes_written);
}
+
int vio_close_pipe(Vio * vio)
{
int r;
DBUG_ENTER("vio_close_pipe");
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
+
+ CloseHandle(vio->pipe_overlapped.hEvent);
DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
+ r= CloseHandle(vio->hPipe);
if (r)
{
DBUG_PRINT("vio_error", ("close() failed, error: %d",GetLastError()));
@@ -466,10 +513,23 @@ int vio_close_pipe(Vio * vio)
}
-void vio_ignore_timeout(Vio *vio __attribute__((unused)),
- uint which __attribute__((unused)),
- uint timeout __attribute__((unused)))
+void vio_win32_timeout(Vio *vio, uint which , uint timeout_sec)
{
+ DWORD timeout_millis;
+ /*
+ Windows is measuring timeouts in milliseconds. Check for possible int
+ overflow.
+ */
+ if (timeout_sec > UINT_MAX/1000)
+ timeout_millis= INFINITE;
+ else
+ timeout_millis= timeout_sec * 1000;
+
+ /* which == 1 means "write", which == 0 means "read".*/
+ if(which)
+ vio->write_timeout_millis= timeout_millis;
+ else
+ vio->read_timeout_millis= timeout_millis;
}
@@ -504,7 +564,7 @@ size_t vio_read_shared_memory(Vio * vio, uchar* buf, size_t size)
WAIT_ABANDONED_0 and WAIT_TIMEOUT - fail. We can't read anything
*/
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->net->read_timeout*1000) != WAIT_OBJECT_0)
+ vio->read_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
@@ -561,7 +621,7 @@ size_t vio_write_shared_memory(Vio * vio, const uchar* buf, size_t size)
while (remain != 0)
{
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->net->write_timeout*1000) != WAIT_OBJECT_0)
+ vio->write_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN((size_t) -1);
}
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 6a6e08818c6..51d049b18b9 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -144,55 +144,6 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
}
-static int
-vio_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- char buf[256];
- X509 *err_cert;
-
- DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok: %d ctx: 0x%lx", ok, (long) ctx));
-
- err_cert= X509_STORE_CTX_get_current_cert(ctx);
- X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
- DBUG_PRINT("info", ("cert: %s", buf));
- if (!ok)
- {
- int err, depth;
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
-
- DBUG_PRINT("error",("verify error: %d '%s'",err,
- X509_verify_cert_error_string(err)));
- /*
- Approve cert if depth is greater then "verify_depth", currently
- verify_depth is always 0 and there is no way to increase it.
- */
- if (verify_depth >= depth)
- ok= 1;
- }
- switch (ctx->error)
- {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
- DBUG_PRINT("info",("issuer= %s\n", buf));
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- DBUG_PRINT("error", ("notBefore"));
- /*ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));*/
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- DBUG_PRINT("error", ("notAfter error"));
- /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/
- break;
- }
- DBUG_PRINT("exit", ("%d", ok));
- DBUG_RETURN(ok);
-}
-
-
#ifdef __NETWARE__
/* NetWare SSL cleanup */
@@ -354,11 +305,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
/* Init the VioSSLFd as a "connector" ie. the client side */
- /*
- The verify_callback function is used to control the behaviour
- when the SSL_VERIFY_PEER flag is set.
- */
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
return ssl_fd;
}
@@ -382,11 +329,7 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
/* Set max number of cached sessions, returns the previous size */
SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);
- /*
- The verify_callback function is used to control the behaviour
- when the SSL_VERIFY_PEER flag is set.
- */
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
/*
Set session_id - an identifier for this server session