summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--client/my_readline.h4
-rw-r--r--client/mysql.cc18
-rw-r--r--client/mysqltest.cc12
-rw-r--r--client/readline.cc43
-rw-r--r--config.h.cmake5
-rw-r--r--configure.cmake11
-rw-r--r--include/my_pthread.h2
-rw-r--r--include/my_sys.h4
-rw-r--r--include/my_time.h13
-rw-r--r--mysql-test/collections/default.daily20
-rw-r--r--mysql-test/collections/default.experimental6
-rw-r--r--mysql-test/collections/default.release11
-rwxr-xr-xmysql-test/collections/default.weekly15
-rw-r--r--mysql-test/collections/mysql-5.1-innodb.push5
-rw-r--r--mysql-test/collections/mysql-5.5-bugteam.daily5
-rw-r--r--mysql-test/collections/mysql-5.5-bugteam.push4
-rw-r--r--mysql-test/collections/mysql-5.5-innodb.push5
-rw-r--r--mysql-test/collections/mysql-next-mr.push5
-rw-r--r--mysql-test/collections/mysql-trunk-innodb.push5
-rw-r--r--mysql-test/collections/mysql-trunk.push5
-rw-r--r--mysql-test/collections/test-bt10
-rw-r--r--mysql-test/collections/test-bt-debug1
-rw-r--r--mysql-test/collections/test-bt-debug-fast0
-rw-r--r--mysql-test/collections/test-bt-fast2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_insert_duplicate.test59
-rw-r--r--mysql-test/extra/rpl_tests/rpl_insert_ignore.test77
-rw-r--r--mysql-test/include/commit.inc8
-rw-r--r--mysql-test/include/ctype_numconv.inc29
-rw-r--r--mysql-test/include/gis_keys.inc16
-rw-r--r--mysql-test/include/have_dbi_dbd-mysql.inc78
-rw-r--r--mysql-test/include/mtr_warnings.sql3
-rw-r--r--mysql-test/include/mysqlhotcopy.inc16
-rw-r--r--mysql-test/include/plugin.defs2
-rw-r--r--mysql-test/include/rpl_start_server.inc10
-rw-r--r--mysql-test/include/rpl_stop_server.inc4
-rw-r--r--mysql-test/include/rpl_sync.inc2
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm16
-rw-r--r--mysql-test/lib/My/CoreDump.pm2
-rw-r--r--mysql-test/lib/My/File/Path.pm15
-rw-r--r--mysql-test/lib/My/Find.pm2
-rw-r--r--mysql-test/lib/My/Options.pm2
-rw-r--r--mysql-test/lib/My/Platform.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess.pm21
-rw-r--r--mysql-test/lib/My/SafeProcess/Base.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_kill_win.cc2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc11
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process_win.cc6
-rw-r--r--mysql-test/lib/My/SysInfo.pm2
-rw-r--r--mysql-test/lib/My/Test.pm14
-rw-r--r--mysql-test/lib/mtr_cases.pm2
-rw-r--r--mysql-test/lib/mtr_gcov.pl2
-rw-r--r--mysql-test/lib/mtr_gprof.pl2
-rw-r--r--mysql-test/lib/mtr_io.pl2
-rw-r--r--mysql-test/lib/mtr_match.pm2
-rw-r--r--mysql-test/lib/mtr_misc.pl19
-rw-r--r--mysql-test/lib/mtr_report.pm2
-rw-r--r--mysql-test/lib/mtr_stress.pl2
-rw-r--r--mysql-test/lib/mtr_unique.pm2
-rwxr-xr-xmysql-test/mysql-stress-test.pl9
-rwxr-xr-xmysql-test/mysql-test-run.pl166
-rw-r--r--mysql-test/r/commit_1innodb.result8
-rw-r--r--mysql-test/r/csv_not_null.result3
-rw-r--r--mysql-test/r/ctype_binary.result40
-rw-r--r--mysql-test/r/ctype_cp1251.result40
-rw-r--r--mysql-test/r/ctype_latin1.result40
-rw-r--r--mysql-test/r/ctype_ucs.result40
-rw-r--r--mysql-test/r/ctype_utf8.result40
-rw-r--r--mysql-test/r/filesort_debug.result16
-rw-r--r--mysql-test/r/func_group.result10
-rw-r--r--mysql-test/r/func_time.result18
-rw-r--r--mysql-test/r/gis.result12
-rw-r--r--mysql-test/r/grant.result75
-rw-r--r--mysql-test/r/innodb_mysql_sync.result65
-rw-r--r--mysql-test/r/join_outer.result142
-rw-r--r--mysql-test/r/mysqld--defaults-file.result12
-rw-r--r--mysql-test/r/not_embedded_server.result4
-rw-r--r--mysql-test/r/order_by.result28
-rw-r--r--mysql-test/r/partition_error.result13
-rw-r--r--mysql-test/r/plugin_auth.result12
-rw-r--r--mysql-test/r/range.result101
-rw-r--r--mysql-test/r/ssl_and_innodb.result8
-rw-r--r--mysql-test/r/symlink.result15
-rw-r--r--mysql-test/r/type_datetime.result11
-rw-r--r--mysql-test/r/type_year.result14
-rw-r--r--mysql-test/r/user_var.result6
-rw-r--r--mysql-test/r/variables.result22
-rw-r--r--mysql-test/std_data/checkDBI_DBD-mysql.pl97
-rw-r--r--mysql-test/suite/binlog/r/binlog_unsafe.result2
-rw-r--r--mysql-test/suite/binlog/t/binlog_unsafe.test2
-rw-r--r--mysql-test/suite/engines/funcs/r/ps_string_not_null.resultbin11681 -> 11681 bytes
-rw-r--r--mysql-test/suite/engines/funcs/t/ps_string_not_null.test2
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc-56228.result30
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug30423.result95
-rw-r--r--mysql-test/suite/innodb/r/innodb_gis.result12
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc-56228.test33
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug30423.test211
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug56143.test5
-rw-r--r--mysql-test/suite/parts/inc/partition_layout_check1.inc13
-rw-r--r--mysql-test/suite/parts/inc/partition_layout_check2.inc7
-rw-r--r--mysql-test/suite/parts/t/partition_recover_myisam.test4
-rw-r--r--mysql-test/suite/parts/t/partition_special_innodb.test4
-rw-r--r--mysql-test/suite/rpl/r/rpl_circular_for_4_hosts.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_heartbeat_2slaves.result14
-rw-r--r--mysql-test/suite/rpl/r/rpl_insert_duplicate.result29
-rw-r--r--mysql-test/suite/rpl/r/rpl_insert_ignore.result62
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddatalocal.result15
-rw-r--r--mysql-test/suite/rpl/r/rpl_log_pos.result2
-rw-r--r--mysql-test/suite/rpl/t/disabled.def3
-rw-r--r--mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test35
-rw-r--r--mysql-test/suite/rpl/t/rpl_insert_duplicate.test14
-rw-r--r--mysql-test/suite/rpl/t/rpl_insert_ignore.test7
-rw-r--r--mysql-test/suite/rpl/t/rpl_loaddatalocal.test26
-rw-r--r--mysql-test/suite/sys_vars/r/all_vars.result2
-rw-r--r--mysql-test/suite/sys_vars/r/secure_file_priv2.result6
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv2.test23
-rw-r--r--mysql-test/t/csv_not_null.test6
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/filesort_debug.test23
-rw-r--r--mysql-test/t/func_group.test11
-rw-r--r--mysql-test/t/func_time.test20
-rw-r--r--mysql-test/t/grant.test101
-rw-r--r--mysql-test/t/innodb_mysql_sync.test133
-rw-r--r--mysql-test/t/join_outer.test124
-rw-r--r--mysql-test/t/mysql.test6
-rw-r--r--mysql-test/t/mysqld--defaults-file.test47
-rw-r--r--mysql-test/t/not_embedded_server.test10
-rw-r--r--mysql-test/t/order_by.test20
-rw-r--r--mysql-test/t/partition_error.test16
-rw-r--r--mysql-test/t/plugin_auth.test22
-rw-r--r--mysql-test/t/range.test67
-rw-r--r--mysql-test/t/ssl_and_innodb.test11
-rw-r--r--mysql-test/t/symlink.test17
-rw-r--r--mysql-test/t/type_datetime.test11
-rw-r--r--mysql-test/t/type_year.test10
-rw-r--r--mysql-test/t/user_var.test12
-rw-r--r--mysql-test/t/variables.test28
-rw-r--r--mysql-test/valgrind.supp52
-rw-r--r--mysys/charset.c20
-rw-r--r--mysys/default.c2
-rw-r--r--mysys/mf_format.c2
-rw-r--r--mysys/my_fopen.c2
-rw-r--r--mysys/my_getsystime.c2
-rw-r--r--plugin/auth/auth_socket.c2
-rw-r--r--plugin/auth/test_plugin.c45
-rw-r--r--regex/my_regex.h4
-rw-r--r--regex/regcomp.c15
-rw-r--r--regex/reginit.c6
-rw-r--r--sql-common/client.c35
-rw-r--r--sql-common/my_time.c2
-rw-r--r--sql/field.cc1
-rw-r--r--sql/filesort.cc23
-rw-r--r--sql/ha_partition.cc26
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h39
-rw-r--r--sql/item.h15
-rw-r--r--sql/item_cmpfunc.cc11
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_geofunc.h2
-rw-r--r--sql/item_strfunc.cc14
-rw-r--r--sql/item_strfunc.h13
-rw-r--r--sql/item_sum.cc21
-rw-r--r--sql/item_sum.h12
-rw-r--r--sql/item_timefunc.cc19
-rw-r--r--sql/item_timefunc.h22
-rw-r--r--sql/log.cc2
-rw-r--r--sql/mysqld.cc32
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/protocol.cc17
-rw-r--r--sql/share/errmsg-utf8.txt8
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/sql_class.cc7
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_load.cc84
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_repl.cc12
-rw-r--r--sql/sql_select.cc344
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_table.cc82
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sys_vars.cc12
-rw-r--r--sql/table.cc2
-rw-r--r--sql/unireg.h4
-rw-r--r--storage/innobase/btr/btr0btr.c2
-rw-r--r--storage/innobase/btr/btr0cur.c321
-rw-r--r--storage/innobase/btr/btr0sea.c2
-rw-r--r--storage/innobase/buf/buf0buddy.c2
-rw-r--r--storage/innobase/buf/buf0buf.c52
-rw-r--r--storage/innobase/buf/buf0lru.c46
-rw-r--r--storage/innobase/dict/dict0dict.c20
-rw-r--r--storage/innobase/dict/dict0load.c2
-rw-r--r--storage/innobase/fsp/fsp0fsp.c8
-rw-r--r--storage/innobase/handler/ha_innodb.cc117
-rw-r--r--storage/innobase/handler/i_s.cc11
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c27
-rw-r--r--storage/innobase/include/btr0cur.h47
-rw-r--r--storage/innobase/include/buf0buf.h14
-rw-r--r--storage/innobase/include/buf0lru.h12
-rw-r--r--storage/innobase/include/dict0mem.h6
-rw-r--r--storage/innobase/include/dict0types.h5
-rw-r--r--storage/innobase/include/rem0cmp.h4
-rw-r--r--storage/innobase/include/rem0cmp.ic2
-rw-r--r--storage/innobase/include/row0upd.h26
-rw-r--r--storage/innobase/include/srv0srv.h18
-rw-r--r--storage/innobase/include/sync0rw.h3
-rw-r--r--storage/innobase/include/trx0rseg.h4
-rw-r--r--storage/innobase/include/trx0trx.h4
-rw-r--r--storage/innobase/include/univ.i21
-rw-r--r--storage/innobase/include/ut0vec.h19
-rw-r--r--storage/innobase/include/ut0vec.ic29
-rw-r--r--storage/innobase/lock/lock0lock.c78
-rw-r--r--storage/innobase/mem/mem0mem.c2
-rw-r--r--storage/innobase/mtr/mtr0log.c2
-rw-r--r--storage/innobase/page/page0zip.c2
-rw-r--r--storage/innobase/rem/rem0cmp.c14
-rw-r--r--storage/innobase/row/row0ins.c2
-rw-r--r--storage/innobase/row/row0merge.c72
-rw-r--r--storage/innobase/row/row0mysql.c14
-rw-r--r--storage/innobase/row/row0purge.c68
-rw-r--r--storage/innobase/row/row0umod.c35
-rw-r--r--storage/innobase/row/row0upd.c47
-rw-r--r--storage/innobase/row/row0vers.c10
-rw-r--r--storage/innobase/srv/srv0srv.c5
-rw-r--r--storage/innobase/srv/srv0start.c13
-rw-r--r--storage/innobase/sync/sync0arr.c4
-rw-r--r--storage/innobase/sync/sync0rw.c19
-rw-r--r--storage/innobase/sync/sync0sync.c357
-rw-r--r--storage/innobase/trx/trx0roll.c4
-rw-r--r--storage/innobase/trx/trx0trx.c25
-rw-r--r--strings/bchange.c2
-rw-r--r--strings/bmove_upp.c2
-rw-r--r--strings/conf_to_src.c4
-rw-r--r--strings/ctype-big5.c2
-rw-r--r--strings/ctype-bin.c2
-rw-r--r--strings/ctype-cp932.c2
-rw-r--r--strings/ctype-czech.c2
-rw-r--r--strings/ctype-euc_kr.c2
-rw-r--r--strings/ctype-eucjpms.c2
-rw-r--r--strings/ctype-extra.c2
-rw-r--r--strings/ctype-gb2312.c2
-rw-r--r--strings/ctype-gbk.c2
-rw-r--r--strings/ctype-latin1.c2
-rw-r--r--strings/ctype-mb.c2
-rw-r--r--strings/ctype-simple.c2
-rw-r--r--strings/ctype-sjis.c2
-rw-r--r--strings/ctype-tis620.c2
-rw-r--r--strings/ctype-uca.c2
-rw-r--r--strings/ctype-ucs2.c2
-rw-r--r--strings/ctype-ujis.c2
-rw-r--r--strings/ctype-utf8.c2
-rw-r--r--strings/ctype-win1250ch.c2
-rw-r--r--strings/ctype.c2
-rw-r--r--strings/do_ctype.c2
-rw-r--r--strings/dtoa.c2
-rw-r--r--strings/dump_map.c2
-rw-r--r--strings/int2str.c2
-rw-r--r--strings/is_prefix.c2
-rw-r--r--strings/llstr.c2
-rw-r--r--strings/longlong2str.c2
-rw-r--r--strings/my_strchr.c2
-rw-r--r--strings/my_strtoll10.c2
-rw-r--r--strings/my_vsnprintf.c2
-rw-r--r--strings/str2int.c2
-rw-r--r--strings/str_alloc.c2
-rw-r--r--strings/strappend.c2
-rw-r--r--strings/strcend.c2
-rw-r--r--strings/strcont.c2
-rw-r--r--strings/strend.c2
-rw-r--r--strings/strfill.c2
-rw-r--r--strings/strmake.c2
-rw-r--r--strings/strmov.c2
-rw-r--r--strings/strnlen.c2
-rw-r--r--strings/strnmov.c2
-rw-r--r--strings/strxmov.c2
-rw-r--r--strings/strxnmov.c2
-rw-r--r--strings/uca-dump.c2
-rw-r--r--strings/uctypedump.c2
-rw-r--r--strings/utr11-dump.c2
-rw-r--r--strings/xml.c2
-rw-r--r--support-files/mysql.spec.sh69
287 files changed, 4612 insertions, 1287 deletions
diff --git a/README b/README
index 5463de4a7e8..48948352e12 100644
--- a/README
+++ b/README
@@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software
is released under the version 2 of the GNU General Public License.
MySQL is brought to you by the MySQL team at Oracle.
-Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
License information can be found in the COPYING file.
diff --git a/client/my_readline.h b/client/my_readline.h
index 08cff565819..276e279f43d 100644
--- a/client/my_readline.h
+++ b/client/my_readline.h
@@ -28,11 +28,13 @@ typedef struct st_line_buffer
uint eof;
ulong max_size;
ulong read_length; /* Length of last read string */
+ int error;
+ bool truncated;
} LINE_BUFFER;
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
-extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated);
+extern char *batch_readline(LINE_BUFFER *buffer);
extern void batch_readline_end(LINE_BUFFER *buffer);
#endif /* CLIENT_MY_READLINE_INCLUDED */
diff --git a/client/mysql.cc b/client/mysql.cc
index 8fea1b054f3..5f33cad6dba 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1127,6 +1127,8 @@ int main(int argc,char *argv[])
if (status.batch && !status.line_buff &&
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{
+ put_info("Can't initialize batch_readline - may be the input source is "
+ "a directory or a block device.", INFO_ERROR, 0);
free_defaults(defaults_argv);
my_end(0);
exit(1);
@@ -1839,14 +1841,13 @@ static int read_and_execute(bool interactive)
ulong line_number=0;
bool ml_comment= 0;
COMMANDS *com;
- bool truncated= 0;
status.exit_status=1;
-
+
for (;;)
{
if (!interactive)
{
- line=batch_readline(status.line_buff, &truncated);
+ line=batch_readline(status.line_buff);
/*
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
Editors like "notepad" put this marker in
@@ -1909,9 +1910,13 @@ static int read_and_execute(bool interactive)
if (opt_outfile && line)
fprintf(OUTFILE, "%s\n", line);
}
- if (!line) // End of file
+ // End of file or system error
+ if (!line)
{
- status.exit_status=0;
+ if (status.line_buff && status.line_buff->error)
+ status.exit_status= 1;
+ else
+ status.exit_status= 0;
break;
}
@@ -1932,7 +1937,8 @@ static int read_and_execute(bool interactive)
#endif
continue;
}
- if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated))
+ if (add_line(glob_buffer, line, &in_string, &ml_comment,
+ status.line_buff ? status.line_buff->truncated : 0))
break;
}
/* if in batch mode, send last query even if it doesn't end with \g or go */
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 6d1630ebdaa..ffc99a3dffd 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
mysqltest
@@ -7555,8 +7555,12 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
mysql_free_result(res); /* Free normal result set with meta data */
- /* Clear prepare warnings */
- dynstr_set(&ds_prepare_warnings, NULL);
+ /*
+ Clear prepare warnings if there are execute warnings,
+ since they are probably duplicated.
+ */
+ if (ds_execute_warnings.length || mysql->warning_count)
+ dynstr_set(&ds_prepare_warnings, NULL);
}
else
{
diff --git a/client/readline.cc b/client/readline.cc
index 5c1a9951d9b..f6d3d1295f1 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -18,18 +18,28 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
+#include <my_dir.h>
#include "my_readline.h"
static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
ulong max_size);
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
static size_t fill_buffer(LINE_BUFFER *buffer);
-static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated);
+static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
{
LINE_BUFFER *line_buff;
+ MY_STAT input_file_stat;
+
+#ifndef __WIN__
+ if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) ||
+ MY_S_ISDIR(input_file_stat.st_mode) ||
+ MY_S_ISBLK(input_file_stat.st_mode))
+ return 0;
+#endif
+
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;
@@ -42,13 +52,12 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
}
-char *batch_readline(LINE_BUFFER *line_buff, bool *truncated)
+char *batch_readline(LINE_BUFFER *line_buff)
{
char *pos;
ulong out_length;
- DBUG_ASSERT(truncated != NULL);
- if (!(pos=intern_read_line(line_buff,&out_length, truncated)))
+ if (!(pos=intern_read_line(line_buff, &out_length)))
return 0;
if (out_length && pos[out_length-1] == '\n')
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
@@ -162,7 +171,10 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
buffer->bufread+1,
MYF(MY_WME | MY_FAE))))
- return (uint) -1;
+ {
+ buffer->error= my_errno;
+ return (size_t) -1;
+ }
buffer->start_of_line=buffer->buffer+start_offset;
buffer->end=buffer->buffer+bufbytes;
}
@@ -177,7 +189,10 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
/* Read in new stuff. */
if ((read_count= my_read(buffer->file, (uchar*) buffer->end, read_count,
MYF(MY_WME))) == MY_FILE_ERROR)
+ {
+ buffer->error= my_errno;
return (size_t) -1;
+ }
DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong) read_count));
@@ -198,8 +213,7 @@ static size_t fill_buffer(LINE_BUFFER *buffer)
}
-
-char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated)
+char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length)
{
char *pos;
size_t length;
@@ -214,22 +228,25 @@ char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length, bool *truncated)
if (pos == buffer->end)
{
/*
- fill_buffer() can return 0 either on EOF in which case we abort
- or when the internal buffer has hit the size limit. In the latter case
- return what we have read so far and signal string truncation.
+ fill_buffer() can return NULL on EOF (in which case we abort),
+ on error, or when the internal buffer has hit the size limit.
+ In the latter case return what we have read so far and signal
+ string truncation.
*/
- if (!(length=fill_buffer(buffer)) || length == (uint) -1)
+ if (!(length= fill_buffer(buffer)))
{
if (buffer->eof)
DBUG_RETURN(0);
}
+ else if (length == (size_t) -1)
+ DBUG_RETURN(NULL);
else
continue;
pos--; /* break line here */
- *truncated= 1;
+ buffer->truncated= 1;
}
else
- *truncated= 0;
+ buffer->truncated= 0;
buffer->end_of_line=pos+1;
*out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
DBUG_RETURN(buffer->start_of_line);
diff --git a/config.h.cmake b/config.h.cmake
index 65ebd077da6..7de8f716e77 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -614,4 +614,9 @@
#define PROTOCOL_VERSION 10
+/* time_t related defines */
+
+#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
+#cmakedefine TIME_T_UNSIGNED @TIME_T_UNSIGNED@
+
#endif
diff --git a/configure.cmake b/configure.cmake
index 954b60a45f6..90a01ff913c 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -574,6 +574,7 @@ MY_CHECK_TYPE_SIZE(uint32 UINT32)
MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T)
MY_CHECK_TYPE_SIZE(int64 INT64)
MY_CHECK_TYPE_SIZE(uint64 UINT64)
+MY_CHECK_TYPE_SIZE(time_t TIME_T)
SET (CMAKE_EXTRA_INCLUDE_FILES sys/types.h)
MY_CHECK_TYPE_SIZE(bool BOOL)
SET(CMAKE_EXTRA_INCLUDE_FILES)
@@ -593,6 +594,16 @@ ENDIF()
# Code tests
#
+# check whether time_t is unsigned
+CHECK_C_SOURCE_COMPILES("
+int main()
+{
+ int array[(((time_t)-1) > 0) ? 1 : -1];
+ return 0;
+}"
+TIME_T_UNSIGNED)
+
+
CHECK_C_SOURCE_COMPILES("
#ifdef _WIN32
#include <winsock2.h>
diff --git a/include/my_pthread.h b/include/my_pthread.h
index f1636cad136..b8608a97849 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/my_sys.h b/include/my_sys.h
index 8d0c4e0afd0..5cef60799b8 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -104,7 +104,7 @@ typedef struct my_aio_result {
#define ME_HOLDTANG 8 /* Don't delete last keys */
#define ME_WAITTOT 16 /* Wait for errtime secs of for a action */
#define ME_WAITTANG 32 /* Wait for a user action */
-#define ME_NOREFRESH 64 /* Dont refresh screen */
+#define ME_NOREFRESH 64 /* Write the error message to error log */
#define ME_NOINPUT 128 /* Dont use the input libary */
#define ME_COLOUR1 ((1 << ME_HIGHBYTE)) /* Possibly error-colours */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE))
diff --git a/include/my_time.h b/include/my_time.h
index fdfe130c45f..68f9c2e739f 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -50,6 +50,19 @@ typedef long my_time_t;
/* two-digit years < this are 20..; >= this are 19.. */
#define YY_PART_YEAR 70
+/*
+ check for valid times only if the range of time_t is greater than
+ the range of my_time_t
+*/
+#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
+# define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
+ ((x) <= TIMESTAMP_MAX_VALUE && \
+ (x) >= TIMESTAMP_MIN_VALUE)
+#else
+# define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
+ ((x) >= TIMESTAMP_MIN_VALUE)
+#endif
+
/* Flags to str_to_datetime */
#define TIME_FUZZY_DATE 1
#define TIME_DATETIME_ONLY 2
diff --git a/mysql-test/collections/default.daily b/mysql-test/collections/default.daily
index 81dffff91ce..75c03d4d47b 100644
--- a/mysql-test/collections/default.daily
+++ b/mysql-test/collections/default.daily
@@ -1,5 +1,15 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-ndb
+
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=row --vardir=var-row --mysqld=--binlog-format=row
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --mysqld=--binlog-format=row --ps-protocol
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --ps-protocol
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_funcs1 --vardir=var-ps_funcs_1 --suite=funcs_1 --ps-protocol
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-ps_nist --suite=nist --ps-protocol
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index 7ffc88745ea..4b519d3e37f 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -8,7 +8,6 @@ funcs_1.charset_collation_1 # depends on compile-time decisions
innodb.innodb_information_schema # Bug#48883 2010-05-11 alik Test "innodb_information_schema" takes fewer locks than expected
main.func_math @freebsd # Bug#43020 2010-05-04 alik main.func_math fails on FreeBSD in PB2
-main.gis # Bug#52208 2010-11-24 alik gis fails on some platforms (Solaris, HP-UX, Linux)
main.gis-rtree @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server
main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_multi_bug38499 times out sporadically
main.outfile_loaddata @solaris # Bug#46895 2010-01-20 alik Test "outfile_loaddata" fails (reproducible)
@@ -25,6 +24,11 @@ sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Severa
sys_vars.plugin_dir_basic # Bug#52223 2010-11-24 alik Test "plugin_dir_basic" does not support RPM build (test) directory structure
sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10
sys_vars.wait_timeout_func # Bug#41255 2010-04-26 alik wait_timeout_func fails
+sys_vars.sys_vars # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
+sys_vars.rpl_semi_sync_master_enabled_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
+sys_vars.rpl_semi_sync_master_timeout_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
+sys_vars.rpl_semi_sync_master_trace_level_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
+sys_vars.rpl_semi_sync_master_wait_no_slave_basic # Bug #59148 2011-01-10 joro 'INSTALL PLUGIN rpl_semi_sync_master' fails in release build with debug binaries
# BUG #59055 : All ndb tests should be removed from the repository
# Leaving the sys_vars tests for now. sys_vars.all_vars.test fails on removing ndb tests
diff --git a/mysql-test/collections/default.release b/mysql-test/collections/default.release
new file mode 100644
index 00000000000..108e1032ca2
--- /dev/null
+++ b/mysql-test/collections/default.release
@@ -0,0 +1,11 @@
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=debug --vardir=var-debug --skip-ndbcluster --skip-rpl --report-features --debug-server
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --skip-ndbcluster --report-features
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --skip-ndbcluster --ps-protocol
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs1+ps --vardir=var-funcs_1_ps --suite=funcs_1 --ps-protocol
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded-server --skip-rpl --skip-ndbcluster
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-nist_ps --suite=nist --ps-protocol
diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly
index ab792e14926..a1339fcf0fc 100755
--- a/mysql-test/collections/default.weekly
+++ b/mysql-test/collections/default.weekly
@@ -1,8 +1,7 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=1st --experimental=collections/default.experimental 1st
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_2_innodb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb funcs_1.myisam_views-big
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=row
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=mixed
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=row
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=mixed
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 main.alter_table-big main.archive-big main.count_distinct3 main.create-big main.events_stress main.events_time_zone main.information_schema-big main.log_tables-big main.merge-big main.mysqlbinlog_row_big main.read_many_rows_innodb main.ssl-big main.sum_distinct-big main.type_newdecimal-big main.variables-big parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_2_innodb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb funcs_1.myisam_views-big
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-row-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=row
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-mixed-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=mixed
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-row-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=row
+perl mysql-test-run.pl --timer --force --debug-server --parallel=auto --comment=eits-rpl-binlog-mixed-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=mixed
diff --git a/mysql-test/collections/mysql-5.1-innodb.push b/mysql-test/collections/mysql-5.1-innodb.push
deleted file mode 100644
index a213706498e..00000000000
--- a/mysql-test/collections/mysql-5.1-innodb.push
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
diff --git a/mysql-test/collections/mysql-5.5-bugteam.daily b/mysql-test/collections/mysql-5.5-bugteam.daily
deleted file mode 100644
index 81dffff91ce..00000000000
--- a/mysql-test/collections/mysql-5.5-bugteam.daily
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-ndb
diff --git a/mysql-test/collections/mysql-5.5-bugteam.push b/mysql-test/collections/mysql-5.5-bugteam.push
deleted file mode 100644
index 06118ed9e1e..00000000000
--- a/mysql-test/collections/mysql-5.5-bugteam.push
+++ /dev/null
@@ -1,4 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_ps_row --vardir=var-main-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_embedded --vardir=var-main_emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
diff --git a/mysql-test/collections/mysql-5.5-innodb.push b/mysql-test/collections/mysql-5.5-innodb.push
deleted file mode 100644
index a213706498e..00000000000
--- a/mysql-test/collections/mysql-5.5-innodb.push
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
diff --git a/mysql-test/collections/mysql-next-mr.push b/mysql-test/collections/mysql-next-mr.push
deleted file mode 100644
index b87cc4b801f..00000000000
--- a/mysql-test/collections/mysql-next-mr.push
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
diff --git a/mysql-test/collections/mysql-trunk-innodb.push b/mysql-test/collections/mysql-trunk-innodb.push
deleted file mode 100644
index df00743c6d8..00000000000
--- a/mysql-test/collections/mysql-trunk-innodb.push
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,rpl,sys_vars,perfschema
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
diff --git a/mysql-test/collections/mysql-trunk.push b/mysql-test/collections/mysql-trunk.push
deleted file mode 100644
index b87cc4b801f..00000000000
--- a/mysql-test/collections/mysql-trunk.push
+++ /dev/null
@@ -1,5 +0,0 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
diff --git a/mysql-test/collections/test-bt b/mysql-test/collections/test-bt
deleted file mode 100644
index 58f0c2c3cde..00000000000
--- a/mysql-test/collections/test-bt
+++ /dev/null
@@ -1,10 +0,0 @@
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=normal --skip-ndbcluster --report-features --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=ps --skip-ndbcluster --ps-protocol --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=funcs1+ps --suite=funcs_1 --ps-protocol --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=funcs2 --suite=funcs_2 --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=partitions --suite=parts --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=stress --suite=stress --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=jp --suite=jp --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=embedded --embedded-server --skip-rpl --skip-ndbcluster --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=nist --suite=nist --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=nist+ps --suite=nist --ps-protocol --experimental=collections/default.experimental
diff --git a/mysql-test/collections/test-bt-debug b/mysql-test/collections/test-bt-debug
deleted file mode 100644
index 5fc1e15e0d2..00000000000
--- a/mysql-test/collections/test-bt-debug
+++ /dev/null
@@ -1 +0,0 @@
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=debug --skip-ndbcluster --skip-rpl --report-features --experimental=collections/default.experimental
diff --git a/mysql-test/collections/test-bt-debug-fast b/mysql-test/collections/test-bt-debug-fast
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/mysql-test/collections/test-bt-debug-fast
+++ /dev/null
diff --git a/mysql-test/collections/test-bt-fast b/mysql-test/collections/test-bt-fast
deleted file mode 100644
index 7978c8082f0..00000000000
--- a/mysql-test/collections/test-bt-fast
+++ /dev/null
@@ -1,2 +0,0 @@
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=ps --skip-ndbcluster --ps-protocol --report-features --experimental=collections/default.experimental
-perl mysql-test-run.pl --force --timer --parallel=auto --comment=stress --suite=stress --experimental=collections/default.experimental
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_duplicate.test b/mysql-test/extra/rpl_tests/rpl_insert_duplicate.test
new file mode 100644
index 00000000000..a81eeba3231
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_insert_duplicate.test
@@ -0,0 +1,59 @@
+# BUG#59338 Inconsistency in binlog for statements that don't change any rows STATEMENT SBR
+# In SBR, if a statement does not fail, it is always written to the binary log,
+# regardless if rows are changed or not. If there is a failure, a statement is
+# only written to the binary log if a non-transactional (.e.g. MyIsam) engine
+# is updated. INSERT ON DUPLICATE KEY UPDATE was not following the rule above
+# and was not written to the binary log, if then engine was Innodb.
+#
+# In this test case, we check if INSERT ON DUPLICATE KEY UPDATE that does not
+# change anything is still written to the binary log.
+
+# Prepare environment
+--connection master
+
+eval CREATE TABLE t1 (
+ a INT UNSIGNED NOT NULL PRIMARY KEY
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a INT UNSIGNED
+) ENGINE=$engine_type;
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+# An insert duplicate that does not update anything must be written to the binary
+# log in SBR and MIXED modes. We check this property by summing a before and after
+# the update and comparing the binlog positions. The sum should be the same at both
+# points and the statement should be in the binary log.
+--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
+--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1)
+--let $statement_file=INSERT INTO t1 SELECT t2.a FROM t2 ORDER BY t2.a ON DUPLICATE KEY UPDATE t1.a= t1.a
+--eval $statement_file
+
+--let $assert_cond= SUM(a) = 1 FROM t1
+--let $assert_text= Sum of elements in t1 should be 1.
+--source include/assert.inc
+
+if (`SELECT @@BINLOG_FORMAT = 'ROW'`)
+{
+ --let $binlog_position_cmp= =
+ --let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start
+ --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
+}
+if (`SELECT @@BINLOG_FORMAT != 'ROW'`)
+{
+ --let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 1, 1\', Info, 1]\' LIKE \'%$statement_file\'
+ --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
+}
+--source include/assert.inc
+
+# Compare master and slave
+--sync_slave_with_master
+--let $diff_tables= master:test.t1 , slave:test.t1
+--source include/diff_tables.inc
+
+# Clean up
+--connection master
+drop table t1, t2;
+--sync_slave_with_master
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_ignore.test b/mysql-test/extra/rpl_tests/rpl_insert_ignore.test
index ee09c316354..270dde7675c 100644
--- a/mysql-test/extra/rpl_tests/rpl_insert_ignore.test
+++ b/mysql-test/extra/rpl_tests/rpl_insert_ignore.test
@@ -5,6 +5,7 @@
# Slave needs to be started with --innodb to store table in InnoDB.
# Same test for MyISAM (which had no bug).
+--connection master
eval CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned,
@@ -32,40 +33,44 @@ INSERT INTO t2 VALUES (5, 4);
INSERT INTO t2 VALUES (6, 6);
INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
-
-# Compare results
-
-SELECT * FROM t1 ORDER BY a;
-
-sync_slave_with_master;
-SELECT * FROM t1 ORDER BY a;
-
-# Now do the same for MyISAM
-
-connection master;
-drop table t1;
-eval CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned,
- unique (b)
-) ENGINE=$engine_type2;
-
-INSERT INTO t1 VALUES (1, 1);
-INSERT INTO t1 VALUES (2, 2);
-INSERT INTO t1 VALUES (3, 3);
-INSERT INTO t1 VALUES (4, 4);
-
---disable_warnings
-INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
---enable_warnings
-
-SELECT * FROM t1 ORDER BY a;
-
-sync_slave_with_master;
-SELECT * FROM t1 ORDER BY a;
-
-connection master;
+--let $assert_cond= COUNT(*) = 6 FROM t1
+--let $assert_text= Count of elements in t1 should be 6.
+--source include/assert.inc
+
+# Compare master and slave
+--sync_slave_with_master
+--let $diff_tables= master:test.t1 , slave:test.t1
+--source include/diff_tables.inc
+
+# BUG#59338 Inconsistency in binlog for statements that don't change any rows STATEMENT SBR
+# An insert ignore that does not update anything must be written to the binary log in SBR
+# and MIXED modes. We check this property by counting occurrences in t1 before and after
+# the insert and comparing the binlog positions. The count should be the same in both points
+# and the statement should be in the binary log.
+--connection master
+--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
+--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1)
+--let $statement_file=INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a
+--eval $statement_file
+
+--let $assert_cond= COUNT(*) = 6 FROM t1
+--let $assert_text= Count of elements in t1 should be 6.
+--source include/assert.inc
+
+if (`SELECT @@BINLOG_FORMAT = 'ROW'`)
+{
+ --let $binlog_position_cmp= =
+ --let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start
+ --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
+}
+if (`SELECT @@BINLOG_FORMAT != 'ROW'`)
+{
+ --let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 2, 1\', Info, 1]\' LIKE \'%$statement_file\'
+ --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
+}
+--source include/assert.inc
+
+# Clean up
+--connection master
drop table t1, t2;
-sync_slave_with_master;
-
-# End of 4.1 tests
+--sync_slave_with_master
diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc
index 81fbdb03bca..9df1571a849 100644
--- a/mysql-test/include/commit.inc
+++ b/mysql-test/include/commit.inc
@@ -502,16 +502,16 @@ call p_verify_status_increment(2, 2, 2, 2);
--echo # 12. Read-write statement: IODKU, change 0 rows.
--echo #
insert t1 set a=2 on duplicate key update a=2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
commit;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
--echo # 13. Read-write statement: INSERT IGNORE, change 0 rows.
--echo #
insert ignore t1 set a=2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
commit;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
--echo # 14. Read-write statement: INSERT IGNORE, change 1 row.
--echo #
diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc
index 83d69cfa40d..571b8207107 100644
--- a/mysql-test/include/ctype_numconv.inc
+++ b/mysql-test/include/ctype_numconv.inc
@@ -1738,6 +1738,35 @@ DROP TABLE t1;
--echo #
+--echo # Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+--echo #
+SELECT @@collation_connection, @@character_set_results;
+CREATE TABLE t1 AS
+SELECT
+ DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+ DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+ DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+ DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+--enable_metadata
+# PS protocol gives different "Max length" value for DATETIME.
+--disable_ps_protocol
+SELECT
+ DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+ DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+ DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+ DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+--disable_metadata
+--enable_ps_protocol
+SELECT
+ HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+ HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+ HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+
+
+--echo #
--echo # Bug#52159 returning time type from function and empty left join causes debug assertion
--echo #
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/include/gis_keys.inc b/mysql-test/include/gis_keys.inc
index c75311f062a..ad00c7e1ef9 100644
--- a/mysql-test/include/gis_keys.inc
+++ b/mysql-test/include/gis_keys.inc
@@ -44,3 +44,19 @@ SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)');
DROP TABLE t1, t2;
--echo End of 5.0 tests
+
+
+--echo #
+--echo # Test for bug #58650 "Failing assertion: primary_key_no == -1 ||
+--echo # primary_key_no == 0".
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+--echo # The minimal test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)), unique key a (a));
+drop table t1;
+--echo # The original test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)));
+create unique index a on t1(a);
+drop table t1;
diff --git a/mysql-test/include/have_dbi_dbd-mysql.inc b/mysql-test/include/have_dbi_dbd-mysql.inc
new file mode 100644
index 00000000000..212e36ac353
--- /dev/null
+++ b/mysql-test/include/have_dbi_dbd-mysql.inc
@@ -0,0 +1,78 @@
+#
+# Originally created by John Embretsen, 2011-01-26.
+#
+# Checks for the existence of Perl modules DBI and DBD::mysql as seen from the
+# perl installation used by "external" executable perl scripts, i.e. scripts
+# that are executed as standalone scripts interpreted by the perl installation
+# specified by the "shebang" line in the top of these scripts.
+#
+# If either module is not found, the test will be skipped.
+#
+# For use in tests that call perl scripts that require these modules.
+#
+# This file is intended to work on Unix. Windows may need different treatment.
+# Reasoning:
+# - "shebangs" are not relevant on Windows, but need to be handled here.
+# - Perl scripts cannot be made executable on Windows, interpreter must be
+# specified.
+#
+# Note that if there are multiple perl installations and not all have the
+# required modules, this check may fail even if the perl in path does have
+# the modules available. This may happen if the perl specified by the script's
+# shebang (e.g. #!/usr/bin/perl) does not have these modules, and script is
+# called without specifying the perl interpreter. However, this will be
+# a correct result in cases where a test calls a script with a similar shebang.
+#
+################################################################################
+
+--source include/not_windows.inc
+
+# We jump through some hoops since there is no direct way to check if an
+# external command went OK or not from a mysql-test file:
+#
+# - In theory, we could do as simple as "exec perl -MDBI -MDBD::mysql -e 1",
+# however we cannot check the result (exit code) from within a test script.
+# Also, this may not yield the same result as other uses of perl due to the
+# shebang issue mentioned above.
+# - Instead we use a separate helper perl script that checks for the modules.
+# - If the modules are found, the perl script leaves a file which sets a
+# variable that can be read by this file.
+# If the modules are not found, the perl script does not set this variable,
+# but leaves an empty file instead.
+#
+# This is done because there is apparently no direct way to transfer
+# information from perl to the test script itself.
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+
+# We do not use embedded perl in this script because that would not have yielded
+# correct results for a situation where an external Perl script is called like
+# "scriptname" instead of "perl scriptname" and the shebang in the script points
+# to a specific perl that may be different than the perl in PATH.
+#
+# Instead, we call a separate helper script which checks for the modules in its
+# own environment. We call it without "perl" in front.
+
+--let $perlChecker= $MYSQLTEST_VARDIR/std_data/checkDBI_DBD-mysql.pl
+--let $resultFile= $MYSQL_TMP_DIR/dbidbd-mysql.txt
+
+# Make the script executable and execute it.
+--chmod 0755 $perlChecker
+--exec $perlChecker
+
+# Source the resulting temporary file and look for a variable being set.
+--source $resultFile
+
+if (!$dbidbd) {
+ --skip Test needs Perl modules DBI and DBD::mysql
+}
+
+# Clean up
+--remove_file $resultFile
+
+--enable_query_log
+--enable_result_log
+--enable_warnings
+
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index f793ff54e86..78cc9882d79 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -183,9 +183,6 @@ INSERT INTO global_suppressions VALUES
("The slave I.O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master."),
(".SELECT UNIX_TIMESTAMP... failed on master, do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS"),
- /* Test case for Bug#31590 in order_by.test produces the following error */
- ("Out of sort memory; increase server sort buffer size"),
-
/* Special case for Bug #26402 in show_check.test
- Question marks are not valid file name parts on Windows. Ignore
this error message.
diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc
index 91e0eff1e0f..fcf57a68644 100644
--- a/mysql-test/include/mysqlhotcopy.inc
+++ b/mysql-test/include/mysqlhotcopy.inc
@@ -4,12 +4,26 @@
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/have_dbi_dbd-mysql.inc
if (!$MYSQLHOTCOPY)
{
+ # Fail the test if the mysqlhotcopy script is missing.
+ # If the tool's location changes, mysql-test-run.pl must be updated to
+ # reflect this (look for "MYSQLHOTCOPY").
die due to missing mysqlhotcopy tool;
}
+# NOTE (johnemb, 2011-01-26):
+# In this test mysqlhotcopy (a perl script) is executed as a standalone
+# executable, i.e. not necessarily using the perl interpreter in PATH,
+# because that is how the documentation demonstrates it.
+#
+# We include have_dbi_dbd-mysql.inc above so that the test will
+# be skipped if Perl modules required by the mysqlhotcopy tool are not
+# found when the script is run this way.
+
+
let $MYSQLD_DATADIR= `SELECT @@datadir`;
--disable_warnings
DROP DATABASE IF EXISTS hotcopy_test;
@@ -93,7 +107,7 @@ DROP DATABASE hotcopy_save;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
--list_files $MYSQLD_DATADIR/hotcopy_save
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
---error 9,2304
+--error 9,11,2304
--exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
--replace_result $MASTER_MYSOCK MASTER_MYSOCK
--exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save
diff --git a/mysql-test/include/plugin.defs b/mysql-test/include/plugin.defs
index 5192dccabf7..2b840d9f438 100644
--- a/mysql-test/include/plugin.defs
+++ b/mysql-test/include/plugin.defs
@@ -27,7 +27,7 @@
# with name1, name2 etc from the comma separated list of plugin names
# in the optional 4th argument.
-auth_test_plugin plugin/auth PLUGIN_AUTH test_plugin_server
+auth_test_plugin plugin/auth PLUGIN_AUTH test_plugin_server,cleartext_plugin_server
qa_auth_interface plugin/auth PLUGIN_AUTH_INTERFACE qa_auth_interface
qa_auth_server plugin/auth PLUGIN_AUTH_SERVER qa_auth_server
qa_auth_client plugin/auth PLUGIN_AUTH_CLIENT qa_auth_client
diff --git a/mysql-test/include/rpl_start_server.inc b/mysql-test/include/rpl_start_server.inc
index ac8106f141c..c59c7759910 100644
--- a/mysql-test/include/rpl_start_server.inc
+++ b/mysql-test/include/rpl_start_server.inc
@@ -45,15 +45,7 @@ if ($rpl_server_parameters)
--source include/rpl_connection.inc
# Write file to make mysql-test-run.pl start up the server again
---let WRITE_TO_FILE= $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
---let WRITE_TO_VAR= $_rpl_start_server_command
-perl;
-my $file= $ENV{'WRITE_TO_FILE'};
-my $var= $ENV{'WRITE_TO_VAR'};
-open WRITE_FILE, ">> $file" or die "Error opening $file: $!";
-print WRITE_FILE $var, "\n" or die "Error appending to $file: $!";
-close WRITE_FILE or die "Error closing $file: $!";
-EOF
+--exec echo "$_rpl_start_server_command" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
--source include/rpl_reconnect.inc
diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc
index a90981d6de8..e1f8839dd69 100644
--- a/mysql-test/include/rpl_stop_server.inc
+++ b/mysql-test/include/rpl_stop_server.inc
@@ -44,9 +44,7 @@ if ($rpl_debug)
# Write file to make mysql-test-run.pl expect the "crash", but don't start
# it until it's told to
---append_file $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
-wait
-EOF
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
# Send shutdown to the connected server and give
# it 10 seconds to die before zapping it
diff --git a/mysql-test/include/rpl_sync.inc b/mysql-test/include/rpl_sync.inc
index a05bee23981..be2904528ff 100644
--- a/mysql-test/include/rpl_sync.inc
+++ b/mysql-test/include/rpl_sync.inc
@@ -88,7 +88,7 @@ while ($_rpl_i) {
{
--echo Sync IO: $_rpl_slave_io_running; Sync SQL: $_rpl_slave_sql_running
}
- --let $_rpl_slave_io_running= `SELECT IF('$_rpl_slave_io_running' = 'Yes', 1, '')`
+ --let $_rpl_slave_io_running= `SELECT IF('$_rpl_slave_io_running' != 'No', 1, '')`
--let $_rpl_slave_sql_running= `SELECT IF('$_rpl_slave_sql_running' = 'Yes', 1, '')`
if ($_rpl_slave_io_running)
{
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index 19c3ee4d5d8..6ba23754890 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -1,4 +1,20 @@
# -*- cperl -*-
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
package My::ConfigFactory;
use strict;
diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm
index 3ac9e385070..c0f6535b96e 100644
--- a/mysql-test/lib/My/CoreDump.pm
+++ b/mysql-test/lib/My/CoreDump.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB, 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
diff --git a/mysql-test/lib/My/File/Path.pm b/mysql-test/lib/My/File/Path.pm
index 25a26568eee..d1ac2b432ac 100644
--- a/mysql-test/lib/My/File/Path.pm
+++ b/mysql-test/lib/My/File/Path.pm
@@ -1,4 +1,19 @@
# -*- cperl -*-
+# Copyright (C) 2008 MySQL AB, 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
package My::File::Path;
use strict;
diff --git a/mysql-test/lib/My/Find.pm b/mysql-test/lib/My/Find.pm
index b2fec0d77b8..a44c9a7508c 100644
--- a/mysql-test/lib/My/Find.pm
+++ b/mysql-test/lib/My/Find.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB
#
# 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
diff --git a/mysql-test/lib/My/Options.pm b/mysql-test/lib/My/Options.pm
index 3bfbe1fc90e..dcd934084e2 100644
--- a/mysql-test/lib/My/Options.pm
+++ b/mysql-test/lib/My/Options.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB
#
# 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
diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm
index 371120ab644..cbe8f929d71 100644
--- a/mysql-test/lib/My/Platform.pm
+++ b/mysql-test/lib/My/Platform.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB, 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
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index 461897b56f0..14153982d4e 100644
--- a/mysql-test/lib/My/SafeProcess.pm
+++ b/mysql-test/lib/My/SafeProcess.pm
@@ -1,14 +1,15 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; version 2
+# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
@@ -138,6 +139,7 @@ sub new {
my $host = delete($opts{'host'});
my $shutdown = delete($opts{'shutdown'});
my $user_data= delete($opts{'user_data'});
+ my $envs = delete($opts{'envs'});
# if (defined $host) {
# $safe_script= "lib/My/SafeProcess/safe_process_cpcd.pl";
@@ -160,6 +162,13 @@ sub new {
# Point the safe_process at the right parent if running on cygwin
push(@safe_args, "--parent-pid=".Cygwin::pid_to_winpid($$)) if IS_CYGWIN;
+ foreach my $env_var (@$envs) {
+ croak("Missing = in env string") unless $env_var =~ /=/;
+ croak("Env string $env_var seen, probably missing value for --mysqld-env")
+ if $env_var =~ /^--/;
+ push @safe_args, "--env $env_var";
+ }
+
push(@safe_args, "--");
push(@safe_args, $path); # The program safe_process should execute
diff --git a/mysql-test/lib/My/SafeProcess/Base.pm b/mysql-test/lib/My/SafeProcess/Base.pm
index 9a6871264b8..c0c70e48082 100644
--- a/mysql-test/lib/My/SafeProcess/Base.pm
+++ b/mysql-test/lib/My/SafeProcess/Base.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB, 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
diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
index f72b851d0b6..72fe874e621 100644
--- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (C) 2008 MySQL AB, 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
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index 1c778362975..e5eca0c0d8b 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 MySQL AB
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -175,7 +175,7 @@ int main(int argc, char* const argv[] )
} else {
if ( strcmp(arg, "--verbose") == 0 )
verbose++;
- else if ( strncmp(arg, "--parent-pid", 10) == 0 )
+ else if ( strncmp(arg, "--parent-pid", 12) == 0 )
{
/* Override parent_pid with a value provided by user */
const char* start;
@@ -184,10 +184,15 @@ int main(int argc, char* const argv[] )
start++; /* Step past = */
if ((parent_pid= atoi(start)) == 0)
die("Invalid value '%s' passed to --parent-id", start);
- } else if ( strcmp(arg, "--nocore") == 0 )
+ }
+ else if ( strcmp(arg, "--nocore") == 0 )
{
nocore = true; // Don't allow the process to dump core
}
+ else if ( strncmp (arg, "--env ", 6) == 0 )
+ {
+ putenv(strdup(arg+6));
+ }
else
die("Unknown option: %s", arg);
}
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 8fffede0b62..7e0ae68b4de 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -220,6 +220,10 @@ int main(int argc, const char** argv )
{
nocore= TRUE;
}
+ else if ( strncmp (arg, "--env ", 6) == 0 )
+ {
+ putenv(strdup(arg+6));
+ }
else
die("Unknown option: %s", arg);
}
diff --git a/mysql-test/lib/My/SysInfo.pm b/mysql-test/lib/My/SysInfo.pm
index f1ba5fb610f..b8569e415e8 100644
--- a/mysql-test/lib/My/SysInfo.pm
+++ b/mysql-test/lib/My/SysInfo.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2008 MySQL AB
#
# 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
diff --git a/mysql-test/lib/My/Test.pm b/mysql-test/lib/My/Test.pm
index 68b100f91af..c756a677052 100644
--- a/mysql-test/lib/My/Test.pm
+++ b/mysql-test/lib/My/Test.pm
@@ -1,4 +1,18 @@
# -*- cperl -*-
+# Copyright (C) 2008 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 856982e98a1..c3dd43c12ca 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl
index f531889b08d..d8fb1c0a07d 100644
--- a/mysql-test/lib/mtr_gcov.pl
+++ b/mysql-test/lib/mtr_gcov.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004, 2006 MySQL AB
+# Copyright (C) 2004, 2006 MySQL AB, 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
diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl
index 5820a4007b8..a5e05b28723 100644
--- a/mysql-test/lib/mtr_gprof.pl
+++ b/mysql-test/lib/mtr_gprof.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004 MySQL AB
+# Copyright (C) 2004 MySQL AB, 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
diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl
index 21581798ddc..6a6b3a3d028 100644
--- a/mysql-test/lib/mtr_io.pl
+++ b/mysql-test/lib/mtr_io.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2004-2007 MySQL AB, 2008 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
diff --git a/mysql-test/lib/mtr_match.pm b/mysql-test/lib/mtr_match.pm
index 40afd4e0336..6fc9832ac43 100644
--- a/mysql-test/lib/mtr_match.pm
+++ b/mysql-test/lib/mtr_match.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
+# Copyright (C) 2004-2008 MySQL AB
#
# 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
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index dc9928d37c5..678d3829226 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -1,15 +1,16 @@
# -*- cperl -*-
-# Copyright (C) 2004-2006 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; version 2
+# of the License.
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index cd3f9ce1041..f86be0d4c68 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright 2004-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl
index 702bc178ae5..ab4214791d0 100644
--- a/mysql-test/lib/mtr_stress.pl
+++ b/mysql-test/lib/mtr_stress.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2006 MySQL AB
+# Copyright (C) 2004-2007 MySQL AB, 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
diff --git a/mysql-test/lib/mtr_unique.pm b/mysql-test/lib/mtr_unique.pm
index 6b60157422d..506af448266 100644
--- a/mysql-test/lib/mtr_unique.pm
+++ b/mysql-test/lib/mtr_unique.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (C) 2006 MySQL AB
+# Copyright (C) 2006-2008 MySQL AB, 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
diff --git a/mysql-test/mysql-stress-test.pl b/mysql-test/mysql-stress-test.pl
index bca7731d8a7..f2471d169d1 100755
--- a/mysql-test/mysql-stress-test.pl
+++ b/mysql-test/mysql-stress-test.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# Copyright (C) 2005, 2006 MySQL AB
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -12,10 +12,9 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
-# You should have received a copy of the GNU Library General Public
-# License along with this library; if not, write to the Free
-# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-# MA 02111-1307, USA
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# ======================================================================
# MySQL server stress test system
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index b786066faf6..5e61b4f1867 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# -*- cperl -*-
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
##############################################################################
@@ -108,6 +108,7 @@ require "lib/mtr_misc.pl";
$SIG{INT}= sub { mtr_error("Got ^C signal"); };
our $mysql_version_id;
+my $mysql_version_extra;
our $glob_mysql_test_dir;
our $basedir;
our $bindir;
@@ -175,6 +176,7 @@ our $opt_big_test= 0;
our @opt_combinations;
our @opt_extra_mysqld_opt;
+our @opt_mysqld_envs;
my $opt_compress;
my $opt_ssl;
@@ -189,6 +191,7 @@ my $opt_view_protocol;
our $opt_debug;
my $debug_d= "d";
my $opt_debug_common;
+our $opt_debug_server;
our @opt_cases; # The test cases names in argv
our $opt_embedded_server;
@@ -291,8 +294,10 @@ our $opt_include_ndbcluster= 0;
our $opt_skip_ndbcluster= 1;
my $exe_ndbd;
+my $exe_ndbmtd;
my $exe_ndb_mgmd;
my $exe_ndb_waiter;
+my $exe_ndb_mgm;
our $debug_compiled_binaries;
@@ -413,6 +418,14 @@ sub main {
my $server_port = $server->sockport();
mtr_report("Using server port $server_port");
+ # --------------------------------------------------------------------------
+ # Read definitions from include/plugin.defs
+ #
+ read_plugin_defs("include/plugin.defs");
+
+ # Simplify reference to semisync plugins
+ $ENV{'SEMISYNC_PLUGIN_OPT'}= $ENV{'SEMISYNC_MASTER_PLUGIN_OPT'};
+
# Create child processes
my %children;
for my $child_num (1..$opt_parallel){
@@ -505,8 +518,8 @@ sub run_test_server ($$$) {
my $num_failed_test= 0; # Number of tests failed so far
# Scheduler variables
- my $max_ndb= $childs / 2;
- $max_ndb = 4 if $max_ndb > 4;
+ my $max_ndb= $ENV{MTR_MAX_NDB} || $childs / 2;
+ $max_ndb = $childs if $max_ndb > $childs;
$max_ndb = 1 if $max_ndb < 1;
my $num_ndb_tests= 0;
@@ -959,6 +972,7 @@ sub command_line_setup {
# Extra options used when starting mysqld
'mysqld=s' => \@opt_extra_mysqld_opt,
+ 'mysqld-env=s' => \@opt_mysqld_envs,
# Run test on running server
'extern=s' => \%opts_extern, # Append to hash
@@ -966,6 +980,7 @@ sub command_line_setup {
# Debugging
'debug' => \$opt_debug,
'debug-common' => \$opt_debug_common,
+ 'debug-server' => \$opt_debug_server,
'gdb' => \$opt_gdb,
'client-gdb' => \$opt_client_gdb,
'manual-gdb' => \$opt_manual_gdb,
@@ -1122,6 +1137,9 @@ sub command_line_setup {
($auth_plugin)= find_plugin("auth_test_plugin", "plugin/auth");
+ # --debug[-common] implies we run debug server
+ $opt_debug_server= 1 if $opt_debug || $opt_debug_common;
+
if (using_extern())
{
# Connect to the running mysqld and find out what it supports
@@ -1665,12 +1683,13 @@ sub collect_mysqld_features {
# Look for version
my $exe_name= basename($exe_mysqld);
mtr_verbose("exe_name: $exe_name");
- if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ )
+ if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)([^\s]*)/ )
{
#print "Major: $1 Minor: $2 Build: $3\n";
$mysql_version_id= $1*10000 + $2*100 + $3;
#print "mysql_version_id: $mysql_version_id\n";
mtr_report("MySQL Version $1.$2.$3");
+ $mysql_version_extra= $4;
}
}
else
@@ -1755,12 +1774,13 @@ sub collect_mysqld_features_from_running_server ()
# Parse version
my $version_str= $mysqld_variables{'version'};
- if ( $version_str =~ /^([0-9]*)\.([0-9]*)\.([0-9]*)/ )
+ if ( $version_str =~ /^([0-9]*)\.([0-9]*)\.([0-9]*)([^\s]*)/ )
{
#print "Major: $1 Minor: $2 Build: $3\n";
$mysql_version_id= $1*10000 + $2*100 + $3;
#print "mysql_version_id: $mysql_version_id\n";
mtr_report("MySQL Version $1.$2.$3");
+ $mysql_version_extra= $4;
}
mtr_error("Could not find version of MySQL") unless $mysql_version_id;
}
@@ -1772,7 +1792,7 @@ sub find_mysqld {
my @mysqld_names= ("mysqld", "mysqld-max-nt", "mysqld-max",
"mysqld-nt");
- if ( $opt_debug ){
+ if ( $opt_debug_server ){
# Put mysqld-debug first in the list of binaries to look for
mtr_verbose("Adding mysqld-debug first in list of binaries to look for");
unshift(@mysqld_names, "mysqld-debug");
@@ -1807,16 +1827,42 @@ sub executable_setup () {
if ( ! $opt_skip_ndbcluster )
{
+ # Look for single threaded NDB
$exe_ndbd=
my_find_bin($bindir,
["storage/ndb/src/kernel", "libexec", "sbin", "bin"],
"ndbd");
+ # Look for multi threaded NDB
+ $exe_ndbmtd=
+ my_find_bin($bindir,
+ ["storage/ndb/src/kernel", "libexec", "sbin", "bin"],
+ "ndbmtd", NOT_REQUIRED);
+ if ($exe_ndbmtd)
+ {
+ my $mtr_ndbmtd = $ENV{MTR_NDBMTD};
+ if ($mtr_ndbmtd)
+ {
+ mtr_report(" - multi threaded ndbd found, will be used always");
+ $exe_ndbd = $exe_ndbmtd;
+ }
+ else
+ {
+ mtr_report(" - multi threaded ndbd found, will be ".
+ "used \"round robin\"");
+ }
+ }
+
$exe_ndb_mgmd=
my_find_bin($bindir,
["storage/ndb/src/mgmsrv", "libexec", "sbin", "bin"],
"ndb_mgmd");
+ $exe_ndb_mgm=
+ my_find_bin($bindir,
+ ["storage/ndb/src/mgmclient", "bin"],
+ "ndb_mgm");
+
$exe_ndb_waiter=
my_find_bin($bindir,
["storage/ndb/tools/", "bin"],
@@ -1843,9 +1889,12 @@ sub executable_setup () {
sub client_debug_arg($$) {
my ($args, $client_name)= @_;
+ # Workaround for Bug #50627: drop any debug opt
+ return if $client_name =~ /^mysqlbinlog/;
+
if ( $opt_debug ) {
mtr_add_arg($args,
- "--debug=$debug_d:t:A,%s/log/%s.trace",
+ "--loose-debug=$debug_d:t:A,%s/log/%s.trace",
$path_vardir_trace, $client_name)
}
}
@@ -1940,7 +1989,7 @@ sub find_plugin($$)
{
my ($plugin, $location) = @_;
my $plugin_filename;
-
+
if (IS_WINDOWS)
{
$plugin_filename = $plugin.".dll";
@@ -1950,13 +1999,13 @@ sub find_plugin($$)
$plugin_filename = $plugin.".so";
}
- my $lib_example_plugin=
+ my $lib_plugin=
mtr_file_exists(vs_config_dirs($location,$plugin_filename),
"$basedir/lib/plugin/".$plugin_filename,
"$basedir/$location/.libs/".$plugin_filename,
"$basedir/lib/mysql/plugin/".$plugin_filename,
);
- return $lib_example_plugin;
+ return $lib_plugin;
}
#
@@ -1966,10 +2015,16 @@ sub find_plugin($$)
sub read_plugin_defs($)
{
my ($defs_file)= @_;
+ my $running_debug= 0;
open(PLUGDEF, '<', $defs_file)
or mtr_error("Can't read plugin defintions file $defs_file");
+ # Need to check if we will be running mysqld-debug
+ if ($opt_debug_server) {
+ $running_debug= 1 if find_mysqld($basedir) =~ /mysqld-debug/;
+ }
+
while (<PLUGDEF>) {
next if /^#/;
my ($plug_file, $plug_loc, $plug_var, $plug_names)= split;
@@ -1977,6 +2032,9 @@ sub read_plugin_defs($)
next unless $plug_file;
mtr_error("Lines in $defs_file must have 3 or 4 items") unless $plug_var;
+ # If running debug server, plugins will be in 'debug' subdirectory
+ $plug_file= "debug/$plug_file" if $running_debug;
+
my ($plugin)= find_plugin($plug_file, $plug_loc);
# Set env. variables that tests may use, set to empty if plugin
@@ -2041,19 +2099,10 @@ sub environment_setup {
push(@ld_library_paths, "$basedir/storage/ndb/src/.libs");
}
- # --------------------------------------------------------------------------
- # Read definitions from include/plugin.defs
- #
# Plugin settings should no longer be added here, instead
# place definitions in include/plugin.defs.
# See comment in that file for details.
# --------------------------------------------------------------------------
- read_plugin_defs("include/plugin.defs");
-
- # Simplify reference to semisync plugins
- $ENV{'SEMISYNC_PLUGIN_OPT'}= $ENV{'SEMISYNC_MASTER_PLUGIN_OPT'};
-
- # --------------------------------------------------------------------------
# Valgrind need to be run with debug libraries otherwise it's almost
# impossible to add correct supressions, that means if "/usr/lib/debug"
# is available, it should be added to
@@ -2119,6 +2168,16 @@ sub environment_setup {
$ENV{'MYSQL_LIBDIR'}= "$basedir/lib";
$ENV{'MYSQL_SHAREDIR'}= $path_language;
$ENV{'MYSQL_CHARSETSDIR'}= $path_charsetsdir;
+
+ if (IS_WINDOWS)
+ {
+ $ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."\\std_data";
+ }
+ else
+ {
+ $ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."/std_data";
+ }
+
# ----------------------------------------------------
# Setup env for NDB
@@ -2472,9 +2531,9 @@ sub check_debug_support ($) {
#mtr_report(" - binaries are not debug compiled");
$debug_compiled_binaries= 0;
- if ( $opt_debug )
+ if ( $opt_debug_server )
{
- mtr_error("Can't use --debug, binaries does not support it");
+ mtr_error("Can't use --debug[-server], binary does not support it");
}
return;
}
@@ -2510,6 +2569,17 @@ sub vs_config_dirs ($$) {
sub check_ndbcluster_support ($) {
my $mysqld_variables= shift;
+ # Check if this is MySQL Cluster, ie. mysql version string ends
+ # with -ndb-Y.Y.Y[-status]
+ if ( defined $mysql_version_extra &&
+ $mysql_version_extra =~ /^-ndb-/ )
+ {
+ mtr_report(" - MySQL Cluster");
+ # Enable ndb engine and add more test suites
+ $opt_include_ndbcluster = 1;
+ $DEFAULT_SUITES.=",ndb";
+ }
+
if ($opt_include_ndbcluster)
{
$opt_skip_ndbcluster= 0;
@@ -2622,6 +2692,27 @@ sub ndb_mgmd_wait_started($) {
return 1;
}
+sub ndb_mgmd_stop{
+ my $ndb_mgmd= shift or die "usage: ndb_mgmd_stop(<ndb_mgmd>)";
+
+ my $host=$ndb_mgmd->value('HostName');
+ my $port=$ndb_mgmd->value('PortNumber');
+ mtr_verbose("Stopping cluster '$host:$port'");
+
+ my $args;
+ mtr_init_args(\$args);
+ mtr_add_arg($args, "--ndb-connectstring=%s:%s", $host,$port);
+ mtr_add_arg($args, "-e");
+ mtr_add_arg($args, "shutdown");
+
+ My::SafeProcess->run
+ (
+ name => "ndb_mgm shutdown $host:$port",
+ path => $exe_ndb_mgm,
+ args => \$args,
+ output => "/dev/null",
+ );
+}
sub ndb_mgmd_start ($$) {
my ($cluster, $ndb_mgmd)= @_;
@@ -2649,6 +2740,7 @@ sub ndb_mgmd_start ($$) {
error => $path_ndb_mgmd_log,
append => 1,
verbose => $opt_verbose,
+ shutdown => sub { ndb_mgmd_stop($ndb_mgmd) },
);
mtr_verbose("Started $ndb_mgmd->{proc}");
@@ -2664,6 +2756,12 @@ sub ndb_mgmd_start ($$) {
return 0;
}
+sub ndbd_stop {
+ # Intentionally left empty, ndbd nodes will be shutdown
+ # by sending "shutdown" to ndb_mgmd
+}
+
+my $exe_ndbmtd_counter= 0;
sub ndbd_start {
my ($cluster, $ndbd)= @_;
@@ -2681,17 +2779,24 @@ sub ndbd_start {
# > 5.0 { 'character-sets-dir' => \&fix_charset_dir },
+ my $exe= $exe_ndbd;
+ if ($exe_ndbmtd and ($exe_ndbmtd_counter++ % 2) == 0)
+ {
+ # Use ndbmtd every other time
+ $exe= $exe_ndbmtd;
+ }
my $path_ndbd_log= "$dir/ndbd.log";
my $proc= My::SafeProcess->new
(
name => $ndbd->after('cluster_config.'),
- path => $exe_ndbd,
+ path => $exe,
args => \$args,
output => $path_ndbd_log,
error => $path_ndbd_log,
append => 1,
verbose => $opt_verbose,
+ shutdown => sub { ndbd_stop($ndbd) },
);
mtr_verbose("Started $proc");
@@ -4157,8 +4262,10 @@ sub check_expected_crash_and_restart {
{
mtr_verbose("Crash was expected, file '$expect_file' exists");
- for (my $waits = 0; $waits < 50; $waits++)
+ for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++)
{
+ # Race condition seen on Windows: try again until file not empty
+ next if -z $expect_file;
# If last line in expect file starts with "wait"
# sleep a little and try again, thus allowing the
# test script to control when the server should start
@@ -4167,10 +4274,11 @@ sub check_expected_crash_and_restart {
if ($last_line =~ /^wait/ )
{
mtr_verbose("Test says wait before restart") if $waits == 0;
- mtr_milli_sleep(100);
next;
}
+ # Ignore any partial or unknown command
+ next unless $last_line =~ /^restart/;
# If last line begins "restart:", the rest of the line is read as
# extra command line options to add to the restarted mysqld.
# Anything other than 'wait' or 'restart:' (with a colon) will
@@ -4554,6 +4662,8 @@ sub mysqld_start ($$) {
my @all_opts= @$extra_opts;
if (exists $mysqld->{'restart_opts'}) {
push (@all_opts, @{$mysqld->{'restart_opts'}});
+ mtr_verbose(My::Options::toStr("mysqld_start restart",
+ @{$mysqld->{'restart_opts'}}));
}
mysqld_arguments($args,$mysqld,\@all_opts);
@@ -4628,6 +4738,7 @@ sub mysqld_start ($$) {
nocore => $opt_skip_core,
host => undef,
shutdown => sub { mysqld_stop($mysqld) },
+ envs => \@opt_mysqld_envs,
);
mtr_verbose("Started $mysqld->{proc}");
}
@@ -5642,9 +5753,10 @@ Options for test case authoring
check-testcases Check testcases for sideeffects
mark-progress Log line number and elapsed time to <testname>.progress
-Options that pass on options
+Options that pass on options (these may be repeated)
mysqld=ARGS Specify additional arguments to "mysqld"
+ mysqld-env=VAR=VAL Specify additional environment settings for "mysqld"
Options to run test on running server
@@ -5663,6 +5775,8 @@ Options for debugging the product
debug Dump trace output for all servers and client programs
debug-common Same as debug, but sets 'd' debug flags to
"query,info,error,enter,exit"
+ debug-server Use debug version of server, but without turning on
+ tracing
debugger=NAME Start mysqld in the selected debugger
gdb Start the mysqld(s) in gdb
manual-debug Let user manually start mysqld in debugger, before
diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
index 993d33d7a38..fb1552b6c28 100644
--- a/mysql-test/r/commit_1innodb.result
+++ b/mysql-test/r/commit_1innodb.result
@@ -519,21 +519,21 @@ SUCCESS
# 12. Read-write statement: IODKU, change 0 rows.
#
insert t1 set a=2 on duplicate key update a=2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
SUCCESS
commit;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
SUCCESS
# 13. Read-write statement: INSERT IGNORE, change 0 rows.
#
insert ignore t1 set a=2;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
SUCCESS
commit;
-call p_verify_status_increment(1, 0, 1, 0);
+call p_verify_status_increment(2, 2, 1, 0);
SUCCESS
# 14. Read-write statement: INSERT IGNORE, change 1 row.
diff --git a/mysql-test/r/csv_not_null.result b/mysql-test/r/csv_not_null.result
index af583a36837..aed9bcb1587 100644
--- a/mysql-test/r/csv_not_null.result
+++ b/mysql-test/r/csv_not_null.result
@@ -19,13 +19,16 @@ INSERT INTO t1 VALUES();
SELECT * FROM t1;
a b c d e f
0 foo 0000-00-00
+INSERT INTO t1 VALUES(default,default,default,default,default,default);
SELECT * FROM t1;
a b c d e f
0 foo 0000-00-00
+0 foo 0000-00-00
INSERT INTO t1 VALUES(0,'abc','def','ghi','bar','1999-12-31');
SELECT * FROM t1;
a b c d e f
0 foo 0000-00-00
+0 foo 0000-00-00
0 abc def ghi bar 1999-12-31
# === insert failures ===
INSERT INTO t1 VALUES(NULL,'ab','a','b','foo','2007-01-01');
diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result
index 4d526a86ade..58cd4b3524b 100644
--- a/mysql-test/r/ctype_binary.result
+++ b/mysql-test/r/ctype_binary.result
@@ -2767,6 +2767,46 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range date_column date_column 9 NULL 1 Using where
DROP TABLE t1;
#
+# Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+#
+SELECT @@collation_connection, @@character_set_results;
+@@collation_connection @@character_set_results
+binary binary
+CREATE TABLE t1 AS
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `field_str1` varbinary(29) DEFAULT NULL,
+ `field1_str2` varbinary(29) DEFAULT NULL,
+ `field_date` date DEFAULT NULL,
+ `field_datetime` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def field_str1 254 29 10 Y 128 31 63
+def field1_str2 254 29 19 Y 128 31 63
+def field_date 10 29 10 Y 128 31 63
+def field_datetime 12 29 19 Y 128 31 63
+field_str1 field1_str2 field_date field_datetime
+2007-08-02 2007-08-03 17:32:00 2007-08-02 2007-08-03 17:32:00
+SELECT
+HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+field_str1 field1_str2 field_date field_datetime
+323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030
+#
# Bug#52159 returning time type from function and empty left join causes debug assertion
#
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result
index b65230e94b4..9a781c61e91 100644
--- a/mysql-test/r/ctype_cp1251.result
+++ b/mysql-test/r/ctype_cp1251.result
@@ -3157,6 +3157,46 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range date_column date_column 9 NULL 1 Using where
DROP TABLE t1;
#
+# Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+#
+SELECT @@collation_connection, @@character_set_results;
+@@collation_connection @@character_set_results
+cp1251_general_ci cp1251
+CREATE TABLE t1 AS
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `field_str1` varchar(29) CHARACTER SET cp1251 DEFAULT NULL,
+ `field1_str2` varchar(29) CHARACTER SET cp1251 DEFAULT NULL,
+ `field_date` date DEFAULT NULL,
+ `field_datetime` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def field_str1 254 29 10 Y 0 31 51
+def field1_str2 254 29 19 Y 0 31 51
+def field_date 10 29 10 Y 128 31 63
+def field_datetime 12 29 19 Y 128 31 63
+field_str1 field1_str2 field_date field_datetime
+2007-08-02 2007-08-03 17:32:00 2007-08-02 2007-08-03 17:32:00
+SELECT
+HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+field_str1 field1_str2 field_date field_datetime
+323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030
+#
# Bug#52159 returning time type from function and empty left join causes debug assertion
#
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index ac84b169ec3..6f773270dff 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/ctype_latin1.result
@@ -3186,6 +3186,46 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range date_column date_column 9 NULL 1 Using where
DROP TABLE t1;
#
+# Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+#
+SELECT @@collation_connection, @@character_set_results;
+@@collation_connection @@character_set_results
+latin1_swedish_ci latin1
+CREATE TABLE t1 AS
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `field_str1` varchar(29) DEFAULT NULL,
+ `field1_str2` varchar(29) DEFAULT NULL,
+ `field_date` date DEFAULT NULL,
+ `field_datetime` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def field_str1 254 29 10 Y 0 31 8
+def field1_str2 254 29 19 Y 0 31 8
+def field_date 10 29 10 Y 128 31 63
+def field_datetime 12 29 19 Y 128 31 63
+field_str1 field1_str2 field_date field_datetime
+2007-08-02 2007-08-03 17:32:00 2007-08-02 2007-08-03 17:32:00
+SELECT
+HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+field_str1 field1_str2 field_date field_datetime
+323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030
+#
# Bug#52159 returning time type from function and empty left join causes debug assertion
#
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 11d5117bbe1..0ee80b921a1 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -4009,6 +4009,46 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
DROP TABLE t1;
#
+# Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+#
+SELECT @@collation_connection, @@character_set_results;
+@@collation_connection @@character_set_results
+ucs2_general_ci latin1
+CREATE TABLE t1 AS
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `field_str1` varchar(29) CHARACTER SET ucs2 DEFAULT NULL,
+ `field1_str2` varchar(29) CHARACTER SET ucs2 DEFAULT NULL,
+ `field_date` date DEFAULT NULL,
+ `field_datetime` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def field_str1 254 29 10 Y 0 31 8
+def field1_str2 254 29 19 Y 0 31 8
+def field_date 10 29 10 Y 128 31 63
+def field_datetime 12 29 19 Y 128 31 63
+field_str1 field1_str2 field_date field_datetime
+2007-08-02 2007-08-03 17:32:00 2007-08-02 2007-08-03 17:32:00
+SELECT
+HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+field_str1 field1_str2 field_date field_datetime
+0032003000300037002D00300038002D00300032002000320033003A00350039003A00300030 0032003000300037002D00300038002D00300033002000310037003A00330032003A00300030 323030372D30382D3032 323030372D30382D30332031373A33323A3030
+#
# Bug#52159 returning time type from function and empty left join causes debug assertion
#
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 5763885d5f3..ababfe51621 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -4898,6 +4898,46 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range date_column date_column 9 NULL 1 Using where
DROP TABLE t1;
#
+# Bug #31384 DATE_ADD() and DATE_SUB() return binary data
+#
+SELECT @@collation_connection, @@character_set_results;
+@@collation_connection @@character_set_results
+utf8_general_ci utf8
+CREATE TABLE t1 AS
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 MINUTE) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `field_str1` varchar(29) CHARACTER SET utf8 DEFAULT NULL,
+ `field1_str2` varchar(29) CHARACTER SET utf8 DEFAULT NULL,
+ `field_date` date DEFAULT NULL,
+ `field_datetime` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT
+DATE_SUB('2007-08-03', INTERVAL 1 DAY) AS field_str1,
+DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE) AS field1_str2,
+DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY) AS field_date,
+DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE) AS field_datetime;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def field_str1 254 87 10 Y 0 31 33
+def field1_str2 254 87 19 Y 0 31 33
+def field_date 10 29 10 Y 128 31 63
+def field_datetime 12 29 19 Y 128 31 63
+field_str1 field1_str2 field_date field_datetime
+2007-08-02 2007-08-03 17:32:00 2007-08-02 2007-08-03 17:32:00
+SELECT
+HEX(DATE_SUB('2007-08-03', INTERVAL 1 MINUTE)) AS field_str1,
+HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2,
+HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date,
+HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime;
+field_str1 field1_str2 field_date field_datetime
+323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030
+#
# Bug#52159 returning time type from function and empty left join causes debug assertion
#
CREATE FUNCTION f1() RETURNS TIME RETURN 1;
diff --git a/mysql-test/r/filesort_debug.result b/mysql-test/r/filesort_debug.result
new file mode 100644
index 00000000000..cb62e5e7a21
--- /dev/null
+++ b/mysql-test/r/filesort_debug.result
@@ -0,0 +1,16 @@
+SET @old_debug= @@session.debug;
+#
+# Bug#36022 please log more information about "Sort aborted" queries
+#
+CREATE TABLE t1(f0 int auto_increment primary key, f1 int);
+INSERT INTO t1(f1) VALUES (0),(1),(2),(3),(4),(5);
+SET session debug= '+d,make_char_array_fail';
+CALL mtr.add_suppression("Out of sort memory");
+SELECT * FROM t1 ORDER BY f1 ASC, f0;
+ERROR HY001: Out of sort memory, consider increasing server sort buffer size
+SET session debug= @old_debug;
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+DELETE FROM t1 ORDER BY (f1(10)) LIMIT 1;
+ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got 1
+DROP TABLE t1;
+DROP FUNCTION f1;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 1f6e01da0c9..2716a06b22f 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1739,6 +1739,16 @@ SELECT RELEASE_LOCK('aaaaaaaaaaaaaaaaa');
#
End of 5.1 tests
#
+# Bug#52123 Assertion failed: aggregator == aggr->Aggrtype(),
+# file .\item_sum.cc, line 587
+#
+CREATE TABLE t1(a int, KEY(a));
+INSERT INTO t1 VALUES (1), (2);
+SELECT 1 FROM t1 ORDER BY AVG(DISTINCT a);
+1
+1
+DROP TABLE t1;
+#
# Bug#55648: Server crash on MIN/MAX on maximum time value
#
CREATE TABLE t1(c1 TIME NOT NULL);
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 34987530b5a..2a95b234548 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1273,6 +1273,24 @@ date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond)
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond)
1000-01-01 00:00:01.020000
+#
+# Bug #52315 part 2 : utc_date() crashes when system time > year 2037
+#
+SET TIMESTAMP=-147490000;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483648;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483646;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483647;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=0;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=-1;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=1;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=0;
End of 5.0 tests
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 7939d01beff..5706f076c6c 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -960,6 +960,18 @@ COUNT(*)
2
DROP TABLE t1, t2;
End of 5.0 tests
+#
+# Test for bug #58650 "Failing assertion: primary_key_no == -1 ||
+# primary_key_no == 0".
+#
+drop table if exists t1;
+# The minimal test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)), unique key a (a));
+drop table t1;
+# The original test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)));
+create unique index a on t1(a);
+drop table t1;
create table `t1` (`col002` point)engine=myisam;
insert into t1 values (),(),();
select min(`col002`) from t1 union select `col002` from t1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 60053b29125..38f09d3b759 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -594,6 +594,7 @@ Index Tables To create or drop indexes
Insert Tables To insert data into tables
Lock tables Databases To use LOCK TABLES (together with SELECT privilege)
Process Server Admin To view the plain text of currently executing queries
+Proxy Server Admin To make proxy user possible
References Databases,Tables To have references on tables
Reload Server Admin To reload or refresh tables, logs and privileges
Replication client Server Admin To ask where the slave or master servers are
@@ -1377,6 +1378,80 @@ CURRENT_USER()
root@localhost
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
+
+# Bug#57952
+
+DROP DATABASE IF EXISTS mysqltest1;
+DROP DATABASE IF EXISTS mysqltest2;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+use mysqltest1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2(a INT);
+INSERT INTO t2 VALUES (2);
+CREATE TABLE mysqltest2.t3(a INT);
+INSERT INTO mysqltest2.t3 VALUES (4);
+CREATE USER testuser@localhost;
+GRANT CREATE ROUTINE, EXECUTE ON mysqltest1.* TO testuser@localhost;
+GRANT SELECT(b) ON t1 TO testuser@localhost;
+GRANT SELECT ON t2 TO testuser@localhost;
+GRANT SELECT ON mysqltest2.* TO testuser@localhost;
+
+# Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
+PREPARE s1 FROM 'SELECT b FROM t1';
+PREPARE s2 FROM 'SELECT a FROM t2';
+PREPARE s3 FROM 'SHOW TABLES FROM mysqltest2';
+CREATE PROCEDURE p1() SELECT b FROM t1;
+CREATE PROCEDURE p2() SELECT a FROM t2;
+CREATE PROCEDURE p3() SHOW TABLES FROM mysqltest2;
+CALL p1;
+b
+1
+CALL p2;
+a
+2
+CALL p3;
+Tables_in_mysqltest2
+t3
+
+# Connection: default
+REVOKE SELECT ON t1 FROM testuser@localhost;
+GRANT SELECT(a) ON t1 TO testuser@localhost;
+REVOKE SELECT ON t2 FROM testuser@localhost;
+REVOKE SELECT ON mysqltest2.* FROM testuser@localhost;
+
+# Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
+# - Check column-level privileges...
+EXECUTE s1;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
+SELECT b FROM t1;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
+EXECUTE s1;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
+CALL p1;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for column 'b' in table 't1'
+# - Check table-level privileges...
+SELECT a FROM t2;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
+EXECUTE s2;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
+CALL p2;
+ERROR 42000: SELECT command denied to user 'testuser'@'localhost' for table 't2'
+# - Check database-level privileges...
+SHOW TABLES FROM mysqltest2;
+ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
+EXECUTE s3;
+ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
+CALL p3;
+ERROR 42000: Access denied for user 'testuser'@'localhost' to database 'mysqltest2'
+
+# Connection: default
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+DROP USER testuser@localhost;
+use test;
+
End of 5.0 tests
set names utf8;
grant select on test.* to юзер_юзер@localhost;
diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result
index d0ba7b0f2e9..58948835f66 100644
--- a/mysql-test/r/innodb_mysql_sync.result
+++ b/mysql-test/r/innodb_mysql_sync.result
@@ -90,3 +90,68 @@ test.t1 optimize status Operation failed
# Connection default
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
+#
+# Bug#42230 during add index, cannot do queries on storage engines
+# that implement add_index
+#
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t1;
+# Test 1: Secondary index, should not block reads (original test case).
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb;
+INSERT INTO db1.t1(value) VALUES (1), (2);
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE db1.t1 ADD INDEX(value);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE db1;
+SELECT * FROM t1;
+id value
+1 1
+2 2
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE db1.t1 ADD INDEX(value)
+DROP DATABASE db1;
+# Test 2: Primary index (implicit), should block reads.
+CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE t1 ADD UNIQUE INDEX(a);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE test;
+# Sending:
+SELECT * FROM t1;
+# Connection con2
+# Waiting for SELECT to be blocked by the metadata lock on t1
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a)
+# Connection con1
+# Reaping: SELECT * FROM t1
+a b
+# Test 3: Primary index (explicit), should block reads.
+# Connection default
+ALTER TABLE t1 DROP INDEX a;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+# Sending:
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+# Connection con1
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+# Sending:
+SELECT * FROM t1;
+# Connection con2
+# Waiting for SELECT to be blocked by the metadata lock on t1
+SET DEBUG_SYNC= "now SIGNAL query";
+# Connection default
+# Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a)
+# Connection con1
+# Reaping: SELECT * FROM t1
+a b
+# Test 4: Secondary unique index, should not block reads.
+# Connection default
+SET DEBUG_SYNC= "RESET";
+DROP TABLE t1;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index ecd53003513..2320d399078 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1502,4 +1502,146 @@ WHERE 7;
col_datetime_key
NULL
DROP TABLE BB;
+#
+# Bug#58490: Incorrect result in multi level OUTER JOIN
+# in combination with IS NULL
+#
+CREATE TABLE t1 (i INT NOT NULL);
+INSERT INTO t1 VALUES (0), (2),(3),(4);
+CREATE TABLE t2 (i INT NOT NULL);
+INSERT INTO t2 VALUES (0),(1), (3),(4);
+CREATE TABLE t3 (i INT NOT NULL);
+INSERT INTO t3 VALUES (0),(1),(2), (4);
+CREATE TABLE t4 (i INT NOT NULL);
+INSERT INTO t4 VALUES (0),(1),(2),(3) ;
+SELECT * FROM
+t1 LEFT JOIN
+( t2 LEFT JOIN
+( t3 LEFT JOIN
+t4
+ON t4.i = t3.i
+)
+ON t3.i = t2.i
+)
+ON t2.i = t1.i
+;
+i i i i
+0 0 0 0
+2 NULL NULL NULL
+3 3 NULL NULL
+4 4 4 NULL
+SELECT * FROM
+t1 LEFT JOIN
+( t2 LEFT JOIN
+( t3 LEFT JOIN
+t4
+ON t4.i = t3.i
+)
+ON t3.i = t2.i
+)
+ON t2.i = t1.i
+WHERE t4.i IS NULL;
+i i i i
+2 NULL NULL NULL
+3 3 NULL NULL
+4 4 4 NULL
+SELECT * FROM
+t1 LEFT JOIN
+( ( t2 LEFT JOIN
+t3
+ON t3.i = t2.i
+)
+)
+ON t2.i = t1.i
+WHERE t3.i IS NULL;
+i i i
+2 NULL NULL
+3 3 NULL
+SELECT * FROM
+t1 LEFT JOIN
+( ( t2 LEFT JOIN
+t3
+ON t3.i = t2.i
+)
+JOIN t4
+ON t4.i=t2.i
+)
+ON t2.i = t1.i
+WHERE t3.i IS NULL;
+i i i i
+2 NULL NULL NULL
+3 3 NULL 3
+4 NULL NULL NULL
+SELECT * FROM
+t1 LEFT JOIN
+( ( t2 LEFT JOIN
+t3
+ON t3.i = t2.i
+)
+JOIN (t4 AS t4a JOIN t4 AS t4b ON t4a.i=t4b.i)
+ON t4a.i=t2.i
+)
+ON t2.i = t1.i
+WHERE t3.i IS NULL;
+i i i i i
+2 NULL NULL NULL NULL
+3 3 NULL 3 3
+4 NULL NULL NULL NULL
+SELECT * FROM
+t1 LEFT JOIN
+( ( t2 LEFT JOIN
+t3
+ON t3.i = t2.i
+)
+JOIN (t4 AS t4a, t4 AS t4b)
+ON t4a.i=t2.i
+)
+ON t2.i = t1.i
+WHERE t3.i IS NULL;
+i i i i i
+2 NULL NULL NULL NULL
+3 3 NULL 3 0
+3 3 NULL 3 1
+3 3 NULL 3 2
+3 3 NULL 3 3
+4 NULL NULL NULL NULL
+DROP TABLE t1,t2,t3,t4;
+#
+# Bug#49322(Duplicate): Server is adding extra NULL row
+# on processing a WHERE clause
+#
+CREATE TABLE h (pk INT NOT NULL, col_int_key INT);
+INSERT INTO h VALUES (1,NULL),(4,2),(5,2),(3,4),(2,8);
+CREATE TABLE m (pk INT NOT NULL, col_int_key INT);
+INSERT INTO m VALUES (1,2),(2,7),(3,5),(4,7),(5,5),(6,NULL),(7,NULL),(8,9);
+CREATE TABLE k (pk INT NOT NULL, col_int_key INT);
+INSERT INTO k VALUES (1,9),(2,2),(3,5),(4,2),(5,7),(6,0),(7,5);
+SELECT TABLE1.pk FROM k TABLE1
+RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key
+RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key;
+pk
+2
+4
+2
+4
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+SELECT TABLE1.pk FROM k TABLE1
+RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key
+RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key
+WHERE TABLE1.pk IS NULL;
+pk
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+DROP TABLE h,m,k;
End of 5.1 tests
diff --git a/mysql-test/r/mysqld--defaults-file.result b/mysql-test/r/mysqld--defaults-file.result
new file mode 100644
index 00000000000..5fd5ca8d95a
--- /dev/null
+++ b/mysql-test/r/mysqld--defaults-file.result
@@ -0,0 +1,12 @@
+Could not open required defaults file: /path/with/no/extension
+Fatal error in defaults handling. Program aborted
+Could not open required defaults file: /path/with.ext
+Fatal error in defaults handling. Program aborted
+Could not open required defaults file: MYSQL_TEST_DIR/relative/path/with.ext
+Fatal error in defaults handling. Program aborted
+Could not open required defaults file: MYSQL_TEST_DIR/relative/path/without/extension
+Fatal error in defaults handling. Program aborted
+Could not open required defaults file: MYSQL_TEST_DIR/with.ext
+Fatal error in defaults handling. Program aborted
+Could not open required defaults file: MYSQL_TEST_DIR/no_extension
+Fatal error in defaults handling. Program aborted
diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
index 1f8fdb65407..eccf6151d33 100644
--- a/mysql-test/r/not_embedded_server.result
+++ b/mysql-test/r/not_embedded_server.result
@@ -3,6 +3,10 @@ SHOW VARIABLES like 'slave_skip_errors';
Variable_name Value
slave_skip_errors OFF
#
+# Bug#58026: massive recursion and crash in regular expression handling
+#
+SELECT '1' RLIKE RPAD('1', 10000, '(');
+#
# WL#4284: Transactional DDL locking
#
# FLUSH PRIVILEGES should not implicitly unlock locked tables.
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 51c8f0cc741..f03ab28b484 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1425,8 +1425,9 @@ set session sort_buffer_size= 30000;
Warnings:
Warning 1292 Truncated incorrect sort_buffer_size value: '30000'
set session max_sort_length= 2180;
+CALL mtr.add_suppression("Out of sort memory");
select * from t1 order by b;
-ERROR HY001: Out of sort memory; increase server sort buffer size
+ERROR HY001: Out of sort memory, consider increasing server sort buffer size
drop table t1;
#
# Bug #39844: Query Crash Mysql Server 5.0.67
@@ -1638,6 +1639,31 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 8 NULL 10 Using index; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where
DROP TABLE t1, t2;
+#
+# Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
+# and
+# Bug #59308: Incorrect result for
+SELECT DISTINCT <col>... ORDER BY <col> DESC
+
+# Use Valgrind to detect #59110!
+#
+CREATE TABLE t1 (a INT,KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+EXPLAIN SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index a a 5 NULL 10 Using where; Using index; Using filesort
+SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
+a 1
+10 1
+9 1
+8 1
+7 1
+6 1
+5 1
+4 1
+3 1
+2 1
+DROP TABLE t1;
End of 5.1 tests
#
# Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY
diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index 1dcb2fdebb8..87eafb234a8 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -1,5 +1,18 @@
drop table if exists t1, t2;
#
+# Bug#57924: crash when creating partitioned table with
+# multiple columns in the partition key
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(a, b, a);
+ERROR HY000: Duplicate partition field name 'a'
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(A, b);
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(a, b, A);
+ERROR HY000: Duplicate partition field name 'a'
+#
# Bug#54483: valgrind errors when making warnings for multiline inserts
# into partition
#
diff --git a/mysql-test/r/plugin_auth.result b/mysql-test/r/plugin_auth.result
index fa6908530b7..7f26cdf447a 100644
--- a/mysql-test/r/plugin_auth.result
+++ b/mysql-test/r/plugin_auth.result
@@ -330,4 +330,16 @@ mysqld is alive
# Executing 'mysqldump'
# Executing 'mysql_upgrade'
The --upgrade-system-tables option was used, databases won't be touched.
+#
+# Bug #59657: Move the client authentication_pam plugin into the
+# server repository
+#
+CREATE USER uplain@localhost IDENTIFIED WITH 'cleartext_plugin_server'
+ AS 'cleartext_test';
+## test plugin auth
+ERROR 28000: Access denied for user 'uplain'@'localhost' (using password: YES)
+select USER(),CURRENT_USER();
+USER() CURRENT_USER()
+uplain@localhost uplain@localhost
+DROP USER uplain@localhost;
End of 5.5 tests
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 62acb2a7710..d8f1f45de0c 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1666,4 +1666,105 @@ c_key c_notkey
1 1
3 3
DROP TABLE t1;
+#
+# Bug #57030: 'BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT);
+CREATE UNIQUE INDEX i4_uq ON t1(i4);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30);
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using where
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+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
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using where
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+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
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+pk i4
+1 10
+2 20
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+pk i4 pk i4
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+pk i4 pk i4
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/ssl_and_innodb.result b/mysql-test/r/ssl_and_innodb.result
new file mode 100644
index 00000000000..71373fc4033
--- /dev/null
+++ b/mysql-test/r/ssl_and_innodb.result
@@ -0,0 +1,8 @@
+CREATE TABLE t1(a int) engine=innodb;
+INSERT INTO t1 VALUES (1);
+SELECT DISTINCT
+convert((SELECT des_decrypt(2,1) AS a FROM t1 WHERE @a:=1), signed) as d
+FROM t1 ;
+d
+2
+DROP TABLE t1;
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 4dac7443135..e7ee871b55b 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -22,7 +22,8 @@ insert into t1 (b) select b from t2;
insert into t2 (b) select b from t1;
insert into t1 (b) select b from t2;
drop table t2;
-create table t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="MYSQLTEST_VARDIR/tmp" index directory="MYSQLTEST_VARDIR/run";
+create table t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam data directory="MYSQLTEST_VARDIR/tmp" index directory="MYSQLTEST_VARDIR/run";
insert into t9 select * from t1;
check table t9;
Table Op Msg_type Msg_text
@@ -56,11 +57,17 @@ t9 CREATE TABLE `t9` (
PRIMARY KEY (`a`)
) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/'
create database mysqltest;
-create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="/this-dir-does-not-exist";
Got one of the listed errors
-create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="MYSQLTEST_VARDIR/run";
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="not-hard-path";
+ERROR 42000: Incorrect table name 'not-hard-path'
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="MYSQLTEST_VARDIR/run";
Got one of the listed errors
-create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="MYSQLTEST_VARDIR/tmp";
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam data directory="MYSQLTEST_VARDIR/tmp";
Got one of the listed errors
alter table t9 rename mysqltest.t9;
select count(*) from mysqltest.t9;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 958285d6a23..7d7acb3d8ac 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -637,6 +637,17 @@ CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7))
20080729104251.1234560
Warnings:
Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567'
+#
+# Bug#59173: Failure to handle DATE(TIME) values where Year, Month or
+# Day is ZERO
+#
+CREATE TABLE t1 (dt1 DATETIME);
+INSERT INTO t1 (dt1) VALUES ('0000-00-01 00:00:01');
+DELETE FROM t1 WHERE dt1 = '0000-00-01 00:00:01';
+# Should be empty
+SELECT * FROM t1;
+dt1
+DROP TABLE t1;
End of 5.1 tests
#
# Start of 5.5 tests
diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result
index 8948214f565..2dc491c6166 100644
--- a/mysql-test/r/type_year.result
+++ b/mysql-test/r/type_year.result
@@ -341,4 +341,18 @@ ta_y s tb_y s
2001 2001 2001 2001
DROP TABLE t1;
#
+# Bug #59211: Select Returns Different Value for min(year) Function
+#
+CREATE TABLE t1(c1 YEAR(4));
+INSERT INTO t1 VALUES (1901),(2155),(0000);
+SELECT * FROM t1;
+c1
+1901
+2155
+0000
+SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
+total_rows min_value MAX(c1)
+3 0 2155
+DROP TABLE t1;
+#
End of 5.1 tests
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index e41a9bc7637..589186184c3 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -448,6 +448,12 @@ DROP TABLE t1;
select @v:=@v:=sum(1) from dual;
@v:=@v:=sum(1)
1
+CREATE TABLE t1(a DECIMAL(31,21));
+INSERT INTO t1 VALUES (0);
+SELECT (@v:=a) <> (@v:=1) FROM t1;
+(@v:=a) <> (@v:=1)
+1
+DROP TABLE t1;
End of 5.1 tests
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index ee180169916..5d6caf21182 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1732,3 +1732,25 @@ set @@session.autocommit=t1_min(), @@session.autocommit=t1_max(),
drop table t1;
drop function t1_min;
drop function t1_max;
+#
+# Bug #59884: setting charset to 2048 crashes
+#
+set session character_set_results = 2048;
+ERROR 42000: Unknown character set: '2048'
+set session character_set_client=2048;
+ERROR 42000: Unknown character set: '2048'
+set session character_set_connection=2048;
+ERROR 42000: Unknown character set: '2048'
+set session character_set_server=2048;
+ERROR 42000: Unknown character set: '2048'
+set session collation_server=2048;
+ERROR HY000: Unknown collation: '2048'
+set session character_set_filesystem=2048;
+ERROR 42000: Unknown character set: '2048'
+set session character_set_database=2048;
+ERROR 42000: Unknown character set: '2048'
+set session collation_connection=2048;
+ERROR HY000: Unknown collation: '2048'
+set session collation_database=2048;
+ERROR HY000: Unknown collation: '2048'
+End of 5.5 tests
diff --git a/mysql-test/std_data/checkDBI_DBD-mysql.pl b/mysql-test/std_data/checkDBI_DBD-mysql.pl
new file mode 100644
index 00000000000..f001e471081
--- /dev/null
+++ b/mysql-test/std_data/checkDBI_DBD-mysql.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+################################################################################
+#
+# This perl script checks for availability of the Perl modules DBI and
+# DBD::mysql using the "current" perl interpreter.
+#
+# Useful for test environment checking before testing executable perl scripts
+# in the MySQL Server distribution.
+#
+# NOTE: The "shebang" on the first line of this script should always point to
+# /usr/bin/perl, so that we can use this script to check whether or not we
+# support running perl scripts with such a shebang without specifying the
+# perl interpreter on the command line. Such a script is mysqlhotcopy.
+#
+# When run as "checkDBI_DBD-mysql.pl" the shebang line will be evaluated
+# and used. When run as "perl checkDBI_DBD-mysql.pl" the shebang line is
+# not used.
+#
+# NOTE: This script will create a temporary file in MTR's tmp dir.
+# If modules are found, a mysql-test statement which sets a special
+# variable is written to this file. If one of the modules is not found
+# (or cannot be loaded), the file will remain empty.
+# A test (or include file) which sources that file can then easily do
+# an if-check on the special variable to determine success or failure.
+#
+# Example:
+#
+# --let $perlChecker= $MYSQLTEST_VARDIR/std_data/checkDBI_DBD-mysql.pl
+# --let $resultFile= $MYSQL_TMP_DIR/dbidbd-mysql.txt
+# --chmod 0755 $perlChecker
+# --exec $perlChecker
+# --source $resultFile
+# if (!$dbidbd) {
+# --skip Test needs Perl modules DBI and DBD::mysql
+# }
+#
+# The calling script is also responsible for cleaning up after use:
+#
+# --remove_file $resultFile
+#
+# Windows notes:
+# - shebangs may work differently - call this script with "perl " in front.
+#
+# See mysql-test/include/have_dbi_dbd-mysql.inc for example use of this script.
+# This script should be executable for the user running MTR.
+#
+################################################################################
+
+BEGIN {
+ # By using eval inside BEGIN we can suppress warnings and continue after.
+ # We need to catch "Can't locate" as well as "Can't load" errors.
+ eval{
+ $FOUND_DBI=0;
+ $FOUND_DBD_MYSQL=0;
+
+ # Check for DBI module:
+ $FOUND_DBI=1 if require DBI;
+
+ # Check for DBD::mysql module
+ $FOUND_DBD_MYSQL=1 if require DBD::mysql;
+ };
+};
+
+# Open a file to be used for transfer of result back to mysql-test.
+# The file must be created whether we write to it or not, otherwise mysql-test
+# will complain if trying to source it.
+# An empty file indicates failure to load modules.
+open(FILE, ">", $ENV{'MYSQL_TMP_DIR'}.'/dbidbd-mysql.txt');
+
+if ($FOUND_DBI && $FOUND_DBD_MYSQL) {
+ # write a mysql-test command setting a variable to indicate success
+ print(FILE 'let $dbidbd= FOUND_DBI_DBD-MYSQL;'."\n");
+}
+
+# close the file.
+close(FILE);
+
+1;
+
diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result
index 7222f384a1f..9f35f09e220 100644
--- a/mysql-test/suite/binlog/r/binlog_unsafe.result
+++ b/mysql-test/suite/binlog/r/binlog_unsafe.result
@@ -2418,7 +2418,7 @@ INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
DROP TABLE t1,t2;
"Should NOT have any warning message issued in the following func7() and trig"
CREATE TABLE t1 (a INT);
-CREATE TABLE t2 (a CHAR(40));
+CREATE TABLE t2 (a TEXT);
CREATE TABLE trigger_table (a CHAR(7));
CREATE FUNCTION func7()
RETURNS INT
diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test
index 7d10bb73824..0dcf965112b 100644
--- a/mysql-test/suite/binlog/t/binlog_unsafe.test
+++ b/mysql-test/suite/binlog/t/binlog_unsafe.test
@@ -481,7 +481,7 @@ DROP TABLE t1,t2;
--echo "Should NOT have any warning message issued in the following func7() and trig"
CREATE TABLE t1 (a INT);
-CREATE TABLE t2 (a CHAR(40));
+CREATE TABLE t2 (a TEXT);
CREATE TABLE trigger_table (a CHAR(7));
DELIMITER |;
CREATE FUNCTION func7()
diff --git a/mysql-test/suite/engines/funcs/r/ps_string_not_null.result b/mysql-test/suite/engines/funcs/r/ps_string_not_null.result
index 859fab8b490..5f2a630811c 100644
--- a/mysql-test/suite/engines/funcs/r/ps_string_not_null.result
+++ b/mysql-test/suite/engines/funcs/r/ps_string_not_null.result
Binary files differ
diff --git a/mysql-test/suite/engines/funcs/t/ps_string_not_null.test b/mysql-test/suite/engines/funcs/t/ps_string_not_null.test
index f9e937cb24d..662adfd7a88 100644
--- a/mysql-test/suite/engines/funcs/t/ps_string_not_null.test
+++ b/mysql-test/suite/engines/funcs/t/ps_string_not_null.test
@@ -1,5 +1,5 @@
--disable_warnings
-DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1(c1 CHAR(100) NOT NULL);
PREPARE stmt1 FROM 'INSERT INTO t1 (c1) VALUES(?)';
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc-56228.result b/mysql-test/suite/innodb/r/innodb-autoinc-56228.result
new file mode 100644
index 00000000000..492130d1f08
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-autoinc-56228.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS t1_56228;
+Warnings:
+Note 1051 Unknown table 't1_56228'
+DROP TABLE IF EXISTS t2_56228;
+Warnings:
+Note 1051 Unknown table 't2_56228'
+DROP FUNCTION IF EXISTS bug56228;
+Warnings:
+Note 1305 FUNCTION test.bug56228 does not exist
+CREATE TEMPORARY TABLE t1_56228(
+c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2_56228(
+c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
+BEGIN
+INSERT INTO t1_56228 VALUES(NULL);
+INSERT INTO t2_56228 VALUES(NULL);
+INSERT INTO t1_56228 VALUES(NULL);
+INSERT INTO t2_56228 VALUES(NULL);
+DROP TEMPORARY TABLE t1_56228;
+RETURN 42;
+END //
+SELECT bug56228();
+bug56228()
+42
+DROP FUNCTION bug56228;
+DROP TEMPORARY TABLE t2_56228;
+DROP TEMPORARY TABLE IF EXISTS t1_56228;
+Warnings:
+Note 1051 Unknown table 't1_56228'
diff --git a/mysql-test/suite/innodb/r/innodb_bug30423.result b/mysql-test/suite/innodb/r/innodb_bug30423.result
new file mode 100644
index 00000000000..d7b72b1ec2a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug30423.result
@@ -0,0 +1,95 @@
+set global innodb_stats_method = default;
+select @@innodb_stats_method;
+@@innodb_stats_method
+nulls_equal
+select count(*) from bug30243_3 where org_id is not NULL;
+count(*)
+20
+select count(*) from bug30243_3 where org_id is NULL;
+count(*)
+16384
+select count(*) from bug30243_2 where org_id is not NULL;
+count(*)
+224
+select count(*) from bug30243_2 where org_id is NULL;
+count(*)
+65536
+select @@innodb_stats_method;
+@@innodb_stats_method
+nulls_equal
+analyze table bug30243_1;
+Table Op Msg_type Msg_text
+test.bug30243_1 analyze status OK
+analyze table bug30243_2;
+Table Op Msg_type Msg_text
+test.bug30243_2 analyze status OK
+analyze table bug30243_3;
+Table Op Msg_type Msg_text
+test.bug30243_3 analyze status OK
+set global innodb_stats_method = "NULL";
+ERROR 42000: Variable 'innodb_stats_method' can't be set to the value of 'NULL'
+set global innodb_stats_method = "nulls_ignored";
+select @@innodb_stats_method;
+@@innodb_stats_method
+nulls_ignored
+analyze table bug30243_1;
+Table Op Msg_type Msg_text
+test.bug30243_1 analyze status OK
+analyze table bug30243_2;
+Table Op Msg_type Msg_text
+test.bug30243_2 analyze status OK
+analyze table bug30243_3;
+Table Op Msg_type Msg_text
+test.bug30243_3 analyze status OK
+explain SELECT COUNT(*), 0
+FROM bug30243_1 orgs
+LEFT JOIN bug30243_3 sa_opportunities
+ON orgs.org_id=sa_opportunities.org_id
+LEFT JOIN bug30243_2 contacts
+ON orgs.org_id=contacts.org_id ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE orgs index NULL org_id 4 NULL 128 Using index
+1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id 1 Using index
+1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id 1 Using index
+select @@innodb_stats_method;
+@@innodb_stats_method
+nulls_ignored
+set global innodb_stats_method = "nulls_unequal";
+select @@innodb_stats_method;
+@@innodb_stats_method
+nulls_unequal
+analyze table bug30243_1;
+Table Op Msg_type Msg_text
+test.bug30243_1 analyze status OK
+analyze table bug30243_2;
+Table Op Msg_type Msg_text
+test.bug30243_2 analyze status OK
+analyze table bug30243_3;
+Table Op Msg_type Msg_text
+test.bug30243_3 analyze status OK
+explain SELECT COUNT(*), 0
+FROM bug30243_1 orgs
+LEFT JOIN bug30243_3 sa_opportunities
+ON orgs.org_id=sa_opportunities.org_id
+LEFT JOIN bug30243_2 contacts
+ON orgs.org_id=contacts.org_id;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE orgs index NULL org_id 4 NULL 128 Using index
+1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id 1 Using index
+1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id 1 Using index
+SELECT COUNT(*) FROM table_bug30423 WHERE org_id IS NULL;
+COUNT(*)
+1024
+set global innodb_stats_method = "nulls_unequal";
+analyze table table_bug30423;
+Table Op Msg_type Msg_text
+test.table_bug30423 analyze status OK
+set global innodb_stats_method = "nulls_ignored";
+analyze table table_bug30423;
+Table Op Msg_type Msg_text
+test.table_bug30423 analyze status OK
+set global innodb_stats_method = nulls_equal;
+drop table bug30243_2;
+drop table bug30243_1;
+drop table bug30243_3;
+drop table table_bug30423;
diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result
index 5712d08c9fa..9d015d91c0d 100644
--- a/mysql-test/suite/innodb/r/innodb_gis.result
+++ b/mysql-test/suite/innodb/r/innodb_gis.result
@@ -585,5 +585,17 @@ COUNT(*)
2
DROP TABLE t1, t2;
End of 5.0 tests
+#
+# Test for bug #58650 "Failing assertion: primary_key_no == -1 ||
+# primary_key_no == 0".
+#
+drop table if exists t1;
+# The minimal test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)), unique key a (a));
+drop table t1;
+# The original test case.
+create table t1 (a int not null, b linestring not null, unique key b (b(12)));
+create unique index a on t1(a);
+drop table t1;
create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
ERROR HY000: The used table type doesn't support SPATIAL indexes
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt b/mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt
new file mode 100644
index 00000000000..0eed7aaadad
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-autoinc-56228-master.opt
@@ -0,0 +1 @@
+--innodb_autoinc_lock_mode=0
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc-56228.test b/mysql-test/suite/innodb/t/innodb-autoinc-56228.test
new file mode 100644
index 00000000000..626efcf9897
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-autoinc-56228.test
@@ -0,0 +1,33 @@
+-- source include/have_innodb.inc
+
+##
+# Bug #56228: dropping tables from within an active statement crashes server
+#
+DROP TABLE IF EXISTS t1_56228;
+DROP TABLE IF EXISTS t2_56228;
+DROP FUNCTION IF EXISTS bug56228;
+
+CREATE TEMPORARY TABLE t1_56228(
+ c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2_56228(
+ c1 iNT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+
+DELIMITER //;
+
+CREATE FUNCTION bug56228() RETURNS INT DETERMINISTIC
+BEGIN
+ INSERT INTO t1_56228 VALUES(NULL);
+ INSERT INTO t2_56228 VALUES(NULL);
+ INSERT INTO t1_56228 VALUES(NULL);
+ INSERT INTO t2_56228 VALUES(NULL);
+ DROP TEMPORARY TABLE t1_56228;
+ RETURN 42;
+END //
+
+DELIMITER ;//
+
+SELECT bug56228();
+
+DROP FUNCTION bug56228;
+DROP TEMPORARY TABLE t2_56228;
+DROP TEMPORARY TABLE IF EXISTS t1_56228;
diff --git a/mysql-test/suite/innodb/t/innodb_bug30423.test b/mysql-test/suite/innodb/t/innodb_bug30423.test
new file mode 100644
index 00000000000..f2a3ee8d099
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug30423.test
@@ -0,0 +1,211 @@
+# Test for Bug #30423, InnoDBs treatment of NULL in index stats causes
+# bad "rows examined" estimates.
+# Implemented InnoDB system variable "innodb_stats_method" with
+# "nulls_equal" (default), "nulls_unequal", and "nulls_ignored" options.
+
+-- source include/have_innodb.inc
+
+let $innodb_stats_method_orig = `select @@innodb_stats_method`;
+
+# default setting for innodb_stats_method is "nulls_equal"
+set global innodb_stats_method = default;
+
+select @@innodb_stats_method;
+
+# create three tables, bug30243_1, bug30243_2 and bug30243_3.
+# The test scenario is adopted from original bug #30423 report.
+# table bug30243_1 and bug30243_3 have many NULL values
+
+-- disable_result_log
+-- disable_query_log
+
+DROP TABLE IF EXISTS bug30243_1;
+CREATE TABLE bug30243_1 (
+ org_id int(11) NOT NULL default '0',
+ UNIQUE KEY (org_id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+LOCK TABLES bug30243_1 WRITE;
+INSERT INTO bug30243_1 VALUES (11),(15),(16),(17),(19),(20),(21),(23),(24),
+(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(37),(38),(40),(41),
+(42),(43),(44),(45),(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),
+(57),(58),(59),(60),(61),(62),(63),(64),(65),(66),(67),(68),(69),(70),(71),
+(72),(73),(74),(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),
+(87),(88),(89),(90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100),(101),
+(102),(103),(104),(105),(106),(107),(108),(109),(110),(111),(112),(113),(114),
+(115),(116),(117),(118),(119),(120),(121),(122),(123),(124),(125),(126),(127),
+(128),(129),(130),(131),(132),(133),(134),(135),(136),(137),(138),(139),(140),
+(141),(142),(143),(144),(145);
+UNLOCK TABLES;
+
+DROP TABLE IF EXISTS bug30243_3;
+CREATE TABLE bug30243_3 (
+ org_id int(11) default NULL,
+ KEY (org_id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO bug30243_3 VALUES (NULL);
+
+begin;
+let $i=14;
+while ($i)
+{
+ INSERT INTO bug30243_3 SELECT NULL FROM bug30243_3;
+ dec $i;
+}
+
+INSERT INTO bug30243_3 VALUES (34),(34),(35),(56),(58),(62),(62),(64),(65),(66),(80),(135),(137),(138),(139),(140),(142),(143),(144),(145);
+commit;
+
+DROP TABLE IF EXISTS bug30243_2;
+CREATE TABLE bug30243_2 (
+ org_id int(11) default NULL,
+ KEY `contacts$org_id` (org_id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO bug30243_2 VALUES (NULL);
+
+begin;
+let $i=16;
+while ($i)
+{
+ INSERT INTO bug30243_2 SELECT NULL FROM bug30243_2;
+ dec $i;
+}
+
+INSERT INTO bug30243_2 VALUES (11),(15),(16),(17),(20),(21),(23),(24),(25),
+(26),(27),(28),(29),(30),(31),(32),(33),(34),(37),(38),(40),(41),(42),(43),
+(44),(45),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),
+(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),
+(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),
+(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),
+(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),
+(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(46),(48),
+(48),(50),(51),(52),(52),(53),(54),(55),(57),(60),(61),(62),(62),(62),(62),
+(62),(63),(64),(64),(65),(66),(66),(67),(68),(69),(70),(71),(72),(73),(74),
+(75),(76),(77),(78),(79),(80),(80),(81),(82),(83),(84),(85),(86),(87),(88),
+(89),(90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100),(101),(102),
+(103),(104),(105),(106),(107),(108),(109),(110),(111),(112),(113),(114),
+(115),(116),(117),(118),(119),(120),(121),(122),(123),(124),(125),(126),
+(127),(128),(129),(130),(131),(132),(133),(133),(135),(135),(135),(135),
+(136),(136),(138),(138),(139),(139),(139),(140),(141),(141),(142),(143),
+(143),(145),(145);
+commit;
+
+
+-- enable_result_log
+-- enable_query_log
+
+# check tables's value
+select count(*) from bug30243_3 where org_id is not NULL;
+select count(*) from bug30243_3 where org_id is NULL;
+
+select count(*) from bug30243_2 where org_id is not NULL;
+select count(*) from bug30243_2 where org_id is NULL;
+
+select @@innodb_stats_method;
+
+analyze table bug30243_1;
+analyze table bug30243_2;
+analyze table bug30243_3;
+
+# Following query plan shows that we over estimate the rows per
+# unique value (since there are many NULLs).
+# Skip this query log since the stats estimate could vary from runs
+-- disable_query_log
+-- disable_result_log
+explain SELECT COUNT(*), 0
+ FROM bug30243_1 orgs
+ LEFT JOIN bug30243_3 sa_opportunities
+ ON orgs.org_id=sa_opportunities.org_id
+ LEFT JOIN bug30243_2 contacts
+ ON orgs.org_id=contacts.org_id ;
+-- enable_query_log
+-- enable_result_log
+
+# following set operation will fail
+#--error ER_WRONG_VALUE_FOR_VAR
+--error 1231
+set global innodb_stats_method = "NULL";
+
+set global innodb_stats_method = "nulls_ignored";
+
+select @@innodb_stats_method;
+
+# Regenerate the stats with "nulls_ignored" option
+
+analyze table bug30243_1;
+analyze table bug30243_2;
+analyze table bug30243_3;
+
+# Following query plan shows that we get the correct rows per
+# unique value (should be approximately 1 row per value)
+explain SELECT COUNT(*), 0
+ FROM bug30243_1 orgs
+ LEFT JOIN bug30243_3 sa_opportunities
+ ON orgs.org_id=sa_opportunities.org_id
+ LEFT JOIN bug30243_2 contacts
+ ON orgs.org_id=contacts.org_id ;
+
+select @@innodb_stats_method;
+
+# Try the "nulls_unequal" option
+set global innodb_stats_method = "nulls_unequal";
+
+select @@innodb_stats_method;
+
+analyze table bug30243_1;
+analyze table bug30243_2;
+analyze table bug30243_3;
+
+# Following query plan shows that we get the correct rows per
+# unique value (~1)
+explain SELECT COUNT(*), 0
+ FROM bug30243_1 orgs
+ LEFT JOIN bug30243_3 sa_opportunities
+ ON orgs.org_id=sa_opportunities.org_id
+ LEFT JOIN bug30243_2 contacts
+ ON orgs.org_id=contacts.org_id;
+
+
+# Create a table with all NULL values, make sure the stats calculation
+# does not crash with table of all NULL values
+-- disable_query_log
+CREATE TABLE table_bug30423 (
+ org_id int(11) default NULL,
+ KEY(org_id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO `table_bug30423` VALUES (NULL);
+
+begin;
+let $i=10;
+while ($i)
+{
+ INSERT INTO table_bug30423 SELECT NULL FROM table_bug30423;
+ dec $i;
+}
+commit;
+
+-- enable_query_log
+
+SELECT COUNT(*) FROM table_bug30423 WHERE org_id IS NULL;
+
+# calculate the statistics for the table for "nulls_ignored" and
+# "nulls_unequal" option
+set global innodb_stats_method = "nulls_unequal";
+analyze table table_bug30423;
+
+set global innodb_stats_method = "nulls_ignored";
+analyze table table_bug30423;
+
+
+eval set global innodb_stats_method = $innodb_stats_method_orig;
+
+drop table bug30243_2;
+
+drop table bug30243_1;
+
+drop table bug30243_3;
+
+drop table table_bug30423;
diff --git a/mysql-test/suite/innodb/t/innodb_bug56143.test b/mysql-test/suite/innodb/t/innodb_bug56143.test
index 3b46f7e1621..c21de09892c 100644
--- a/mysql-test/suite/innodb/t/innodb_bug56143.test
+++ b/mysql-test/suite/innodb/t/innodb_bug56143.test
@@ -8,6 +8,11 @@
-- disable_query_log
-- disable_result_log
+if ($VALGRIND_TEST)
+{
+ call mtr.add_suppression("InnoDB: Warning: a long semaphore wait:");
+}
+
SET foreign_key_checks=0;
DROP TABLE IF EXISTS bug56143_1;
diff --git a/mysql-test/suite/parts/inc/partition_layout_check1.inc b/mysql-test/suite/parts/inc/partition_layout_check1.inc
index 1b0b24f1088..de35d3f2cad 100644
--- a/mysql-test/suite/parts/inc/partition_layout_check1.inc
+++ b/mysql-test/suite/parts/inc/partition_layout_check1.inc
@@ -29,14 +29,10 @@ DELETE FROM t0_definition;
let $MYSQLD_DATADIR= `select LEFT(@@datadir, LENGTH(@@datadir)-1)`;
#echo MYSQLD_DATADIR: $MYSQLD_DATADIR;
-# Dump the current definition of the table t1 to tmp1
-# This complicated method - let another mysqltest collect the output - is used
-# because of two reasons
+# Save the current definition of the table t1
# - SHOW CREATE TABLE t1 is at least currently most probably more reliable than
# the corresponding SELECT on the INFORMATION_SCHEMA
-# - SHOW CREATE TABLE .. cannot write its out put into a file like SELECT
-let $show_file= $MYSQLD_DATADIR/test/tmp1;
---exec echo "SHOW CREATE TABLE t1; exit; " | $MYSQL_TEST > $show_file 2>&1
+let $show_create= `SHOW CREATE TABLE t1`;
if ($do_file_tests)
{
# List the files belonging to the table t1
@@ -57,12 +53,13 @@ if (!$do_file_tests)
# Insert the current definition of the table t1 into t0_definition
eval INSERT INTO t0_definition SET state = 'old',
- create_command = load_file('$show_file'),
+ create_command = "$show_create",
file_list = @aux;
# Print the create table statement into the protocol
+# Added the concat to avoid changing the result files
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR '\r' ''
-SELECT create_command FROM t0_definition WHERE state = 'old';
+SELECT concat('SHOW CREATE TABLE t1;\nTable\tCreate Table\n',create_command,'\n') as `create_command` FROM t0_definition WHERE state = 'old';
if ($do_file_tests)
{
# We stored the list of files, therefore printing the content makes sense
diff --git a/mysql-test/suite/parts/inc/partition_layout_check2.inc b/mysql-test/suite/parts/inc/partition_layout_check2.inc
index b1ec56ceedd..028b1242e90 100644
--- a/mysql-test/suite/parts/inc/partition_layout_check2.inc
+++ b/mysql-test/suite/parts/inc/partition_layout_check2.inc
@@ -28,9 +28,8 @@ DELETE FROM t0_definition WHERE state = 'new';
let $MYSQLD_DATADIR= `select LEFT(@@datadir, LENGTH(@@datadir)-1)`;
#echo MYSQLD_DATADIR: $MYSQLD_DATADIR;
-# Dump the current definition of the table t1 to tmp1
-let $show_file= $MYSQLD_DATADIR/test/tmp1;
---exec echo "SHOW CREATE TABLE t1; exit; " | $MYSQL_TEST > $show_file 2>&1
+# Save the current definition of the table t1
+let $show_create= `SHOW CREATE TABLE t1`;
if ($do_file_tests)
{
@@ -52,7 +51,7 @@ if (!$do_file_tests)
# Insert the current definition of the table t1 into t0_definition
eval INSERT INTO t0_definition SET state = 'new',
- create_command = load_file('$show_file'),
+ create_command = "$show_create",
file_list = @aux;
# Print the old and new table layout, if they differ
diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.test b/mysql-test/suite/parts/t/partition_recover_myisam.test
index ecc83629768..79a85ca222f 100644
--- a/mysql-test/suite/parts/t/partition_recover_myisam.test
+++ b/mysql-test/suite/parts/t/partition_recover_myisam.test
@@ -20,6 +20,8 @@ FLUSH TABLES;
let $MYSQLD_DATADIR= `select @@datadir`;
--remove_file $MYSQLD_DATADIR/test/t1_will_crash.MYI
--copy_file std_data/corrupt_t1.MYI $MYSQLD_DATADIR/test/t1_will_crash.MYI
+--replace_result \\ /
+--replace_regex /Table '.*data/Table './
SELECT * FROM t1_will_crash;
DROP TABLE t1_will_crash;
CREATE TABLE t1_will_crash (a INT, KEY (a))
@@ -33,5 +35,7 @@ FLUSH TABLES;
--echo # head -c1024 t1#P#p1.MYI > corrupt_t1#P#p1.MYI
--remove_file $MYSQLD_DATADIR/test/t1_will_crash#P#p1.MYI
--copy_file std_data/corrupt_t1#P#p1.MYI $MYSQLD_DATADIR/test/t1_will_crash#P#p1.MYI
+--replace_result \\ /
+--replace_regex /Table '.*data/Table './
SELECT * FROM t1_will_crash;
DROP TABLE t1_will_crash;
diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test
index 1c36299f4bd..1fc9ac7fafc 100644
--- a/mysql-test/suite/parts/t/partition_special_innodb.test
+++ b/mysql-test/suite/parts/t/partition_special_innodb.test
@@ -58,8 +58,8 @@ ENGINE = InnoDB
PARTITION BY HASH (a)
PARTITIONS 2;
-connect (con1,127.0.0.1,root,,test,$MASTER_MYPORT,);
-connect (con2,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (con1, localhost, root,,);
+connect (con2, localhost, root,,);
--connection con1
SET autocommit=OFF;
diff --git a/mysql-test/suite/rpl/r/rpl_circular_for_4_hosts.result b/mysql-test/suite/rpl/r/rpl_circular_for_4_hosts.result
index fb1d3f8258e..6981e549918 100644
--- a/mysql-test/suite/rpl/r/rpl_circular_for_4_hosts.result
+++ b/mysql-test/suite/rpl/r/rpl_circular_for_4_hosts.result
@@ -121,11 +121,11 @@ Master D 12 D
* Remove wrong event from C and restore B->C->D *
include/stop_slave.inc
DELETE FROM t1 WHERE a = 6;
-START SLAVE;
+include/start_slave.inc
RESET MASTER;
RESET SLAVE;
include/rpl_change_topology.inc [new topology=1->2->3->4->1]
-START SLAVE;
+include/start_slave.inc
include/rpl_sync.inc
* Check data inserted before restoring schema A->B->C->D->A *
diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_2slaves.result b/mysql-test/suite/rpl/r/rpl_heartbeat_2slaves.result
index 198d89ae3d6..e0e6df064b9 100644
--- a/mysql-test/suite/rpl/r/rpl_heartbeat_2slaves.result
+++ b/mysql-test/suite/rpl/r/rpl_heartbeat_2slaves.result
@@ -2,13 +2,21 @@ include/rpl_init.inc [topology=1->2,1->3]
include/rpl_connect.inc [creating master]
include/rpl_connect.inc [creating slave_1]
include/rpl_connect.inc [creating slave_2]
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 0.1;
+include/start_slave.inc
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 1;
+include/start_slave.inc
Slave has received heartbeat event
-slave_2 has received heartbeat event
-slave_1 has received more heartbeats than slave_2 (1 means 'yes'): 0
+include/assert.inc [slave_1 should have received more heartbeats than slave_2]
include/rpl_stop_slaves.inc
include/rpl_change_topology.inc [new topology=1->3->2]
include/rpl_start_slaves.inc
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=0.1;
+include/start_slave.inc
slave_1 has received heartbeat event
[on master]
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10), c LONGTEXT);
@@ -26,7 +34,7 @@ Tables_in_test
[on master]
creating updates on master and send to slave_2 during 5 second
[on slave_1]
-slave_1 has received heartbeats (1 means 'yes'): 0
+include/assert.inc [slave_1 should have received heartbeats]
*** Clean up ***
DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/r/rpl_insert_duplicate.result b/mysql-test/suite/rpl/r/rpl_insert_duplicate.result
new file mode 100644
index 00000000000..61ebbaaa5a9
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_insert_duplicate.result
@@ -0,0 +1,29 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (
+a INT UNSIGNED NOT NULL PRIMARY KEY
+) ENGINE=innodb;
+CREATE TABLE t2 (
+a INT UNSIGNED
+) ENGINE=innodb;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+INSERT INTO t1 SELECT t2.a FROM t2 ORDER BY t2.a ON DUPLICATE KEY UPDATE t1.a= t1.a;
+include/assert.inc [Sum of elements in t1 should be 1.]
+include/assert.inc [In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.]
+include/diff_tables.inc [master:test.t1 , slave:test.t1]
+drop table t1, t2;
+CREATE TABLE t1 (
+a INT UNSIGNED NOT NULL PRIMARY KEY
+) ENGINE=myisam;
+CREATE TABLE t2 (
+a INT UNSIGNED
+) ENGINE=myisam;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+INSERT INTO t1 SELECT t2.a FROM t2 ORDER BY t2.a ON DUPLICATE KEY UPDATE t1.a= t1.a;
+include/assert.inc [Sum of elements in t1 should be 1.]
+include/assert.inc [In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.]
+include/diff_tables.inc [master:test.t1 , slave:test.t1]
+drop table t1, t2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_insert_ignore.result b/mysql-test/suite/rpl/r/rpl_insert_ignore.result
index e31272f5300..04b64359126 100644
--- a/mysql-test/suite/rpl/r/rpl_insert_ignore.result
+++ b/mysql-test/suite/rpl/r/rpl_insert_ignore.result
@@ -21,48 +21,36 @@ INSERT INTO t2 VALUES (4, 3);
INSERT INTO t2 VALUES (5, 4);
INSERT INTO t2 VALUES (6, 6);
INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
-SELECT * FROM t1 ORDER BY a;
-a b
-1 1
-2 2
-3 3
-4 4
-5 5
-6 6
-SELECT * FROM t1 ORDER BY a;
-a b
-1 1
-2 2
-3 3
-4 4
-5 5
-6 6
-drop table t1;
+include/assert.inc [Count of elements in t1 should be 6.]
+include/diff_tables.inc [master:test.t1 , slave:test.t1]
+INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
+include/assert.inc [Count of elements in t1 should be 6.]
+include/assert.inc [In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.]
+drop table t1, t2;
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned,
unique (b)
) ENGINE=myisam;
-INSERT INTO t1 VALUES (1, 1);
-INSERT INTO t1 VALUES (2, 2);
-INSERT INTO t1 VALUES (3, 3);
-INSERT INTO t1 VALUES (4, 4);
+CREATE TABLE t2 (
+a int unsigned, # to force INSERT SELECT to have a certain order
+b int unsigned
+) ENGINE=myisam;
+INSERT INTO t1 VALUES (NULL, 1);
+INSERT INTO t1 VALUES (NULL, 2);
+INSERT INTO t1 VALUES (NULL, 3);
+INSERT INTO t1 VALUES (NULL, 4);
+INSERT INTO t2 VALUES (1, 1);
+INSERT INTO t2 VALUES (2, 2);
+INSERT INTO t2 VALUES (3, 5);
+INSERT INTO t2 VALUES (4, 3);
+INSERT INTO t2 VALUES (5, 4);
+INSERT INTO t2 VALUES (6, 6);
+INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
+include/assert.inc [Count of elements in t1 should be 6.]
+include/diff_tables.inc [master:test.t1 , slave:test.t1]
INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
-SELECT * FROM t1 ORDER BY a;
-a b
-1 1
-2 2
-3 3
-4 4
-5 5
-6 6
-SELECT * FROM t1 ORDER BY a;
-a b
-1 1
-2 2
-3 3
-4 4
-5 5
-6 6
+include/assert.inc [Count of elements in t1 should be 6.]
+include/assert.inc [In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.]
drop table t1, t2;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
index 37936871993..2fd9dc6294e 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
@@ -74,6 +74,21 @@ LOAD/*!99999 special comments that do not expand */DATA/*!99999 code from the fu
SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER';
LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
[slave]
+
+Bug #59267:
+"LOAD DATA LOCAL INFILE not executed on slave with SBR"
+
+[master]
+SELECT * INTO OUTFILE 'MYSQLD_DATADIR/bug59267.sql' FROM t1;
+TRUNCATE TABLE t1;
+LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1;
+SELECT 'Master', COUNT(*) FROM t1;
+Master COUNT(*)
+Master 44
+[slave]
+SELECT 'Slave', COUNT(*) FROM t1;
+Slave COUNT(*)
+Slave 44
[master]
DROP TABLE t1;
SET SESSION sql_mode=@old_mode;
diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result
index b2224dcd725..91d307008f0 100644
--- a/mysql-test/suite/rpl/r/rpl_log_pos.result
+++ b/mysql-test/suite/rpl/r/rpl_log_pos.result
@@ -9,7 +9,7 @@ change master to master_log_pos=MASTER_LOG_POS;
Read_Master_Log_Pos = '75'
start slave;
include/wait_for_slave_io_error.inc [errno=1236]
-Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event''
+Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master''
include/stop_slave_sql.inc
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def
index f4806bdba1e..1aa596ec783 100644
--- a/mysql-test/suite/rpl/t/disabled.def
+++ b/mysql-test/suite/rpl/t/disabled.def
@@ -14,5 +14,6 @@ rpl_failed_optimize : WL#4284: Can't optimize table used by a pending tran
rpl_read_only : WL#4284: Setting Read only won't succeed until all metadata locks are released.
rpl_row_create_table : Bug#51574 2010-02-27 andrei failed different way than earlier with bug#45576
rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
-rpl_log_pos : BUG#55675 2010-09-10 alfranio rpl.rpl_log_pos fails sporadically with error binlog truncated in the middle
rpl_get_master_version_and_clock : Bug#59178 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock
+rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
+rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
diff --git a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test
index 888f09fcfa1..750f399ce99 100644
--- a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test
+++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test
@@ -178,7 +178,7 @@ SELECT 'Master D',a,b FROM t1 WHERE c = 3 ORDER BY a,b;
source include/stop_slave.inc;
--connection server_3
DELETE FROM t1 WHERE a = 6;
-START SLAVE;
+--source include/start_slave.inc
--connection server_2
--sync_slave_with_master server_3
RESET MASTER;
@@ -192,7 +192,7 @@ RESET SLAVE;
--source include/rpl_change_topology.inc
#--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 $file_d LOG_FILE $pos_d LOG_POS
#--eval CHANGE MASTER TO master_host='127.0.0.1',master_port=$SERVER_MYPORT_3,master_user='root',master_log_file='$file_d',master_log_pos=$pos_d
-START SLAVE;
+--source include/start_slave.inc
--connection server_3
--sync_slave_with_master server_4
--source include/rpl_sync.inc
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test
index a7b44215779..6bdd2bbee63 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test
@@ -20,7 +20,19 @@
--source include/rpl_connect.inc
#
-# Testing heartbeat
+# Set different heartbeat periods for slaves
+#
+--connection slave_1
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 0.1;
+--source include/start_slave.inc
+--connection slave_2
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 1;
+--source include/start_slave.inc
+
+#
+# Testing heartbeat for one master and two slaves
#
# Check that heartbeat events sent to both slaves with correct periods
@@ -35,15 +47,11 @@ let $status_var= slave_received_heartbeats;
let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
let $status_var_comparsion= >;
--source include/wait_for_status_var.inc
-let $slave_2_rcvd_heartbeats= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
---echo slave_2 has received heartbeat event
---connection slave_1
-let $slave_1_rcvd_heartbeats= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
-let $result= query_get_value(SELECT ($slave_1_rcvd_heartbeats DIV $slave_2_rcvd_heartbeats) > 1 AS Result, Result, 1);
---echo slave_1 has received more heartbeats than slave_2 (1 means 'yes'): $result
+--let $assert_cond= [slave_1:SHOW STATUS LIKE "slave_received_heartbeats", Value, 1] > [slave_2:SHOW STATUS LIKE "slave_received_heartbeats", Value, 1]
+--let $assert_text= slave_1 should have received more heartbeats than slave_2
+--source include/assert.inc
--echo
-
# Create topology master->slave_2->slave_1 and check that slave_1
# receives heartbeat while slave_2 gets data.
@@ -54,6 +62,10 @@ let $result= query_get_value(SELECT ($slave_1_rcvd_heartbeats DIV $slave_2_rcvd_
--let $rpl_topology= 1->3->2
--source include/rpl_change_topology.inc
--source include/rpl_start_slaves.inc
+--connection slave_1
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=0.1;
+--source include/start_slave.inc
# Check heartbeat for new replication channel slave_2->slave
let $status_var= slave_received_heartbeats;
@@ -93,8 +105,6 @@ while ($i) {
let $time_before = `SELECT NOW()`;
}
if (`SELECT ((1-$k)*TIMESTAMPDIFF(SECOND,'$time_before',NOW())) > 5`) {
- --connection slave_1
- let $slave_1_rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
let $i= 0;
}
--connection master
@@ -104,8 +114,9 @@ while ($i) {
--enable_query_log
--connection slave_1
--echo [on slave_1]
-let $result= query_get_value(SELECT ($slave_1_rcvd_heartbeats_after - $slave_1_rcvd_heartbeats_before) > 0 AS Result, Result, 1);
---echo slave_1 has received heartbeats (1 means 'yes'): $result
+--let $assert_cond= [SHOW STATUS LIKE "slave_received_heartbeats", Value, 1] > $slave_1_rcvd_heartbeats_before
+--let $assert_text= slave_1 should have received heartbeats
+--source include/assert.inc
--echo
#
diff --git a/mysql-test/suite/rpl/t/rpl_insert_duplicate.test b/mysql-test/suite/rpl/t/rpl_insert_duplicate.test
new file mode 100644
index 00000000000..7dd38a696ae
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_insert_duplicate.test
@@ -0,0 +1,14 @@
+#########################################
+# Wrapper for rpl_insert_duplicate.test #
+#########################################
+-- source include/master-slave.inc
+-- source include/have_innodb.inc
+#-- source include/have_binlog_format_mixed_or_statement.inc
+
+let $engine_type=innodb;
+-- source extra/rpl_tests/rpl_insert_duplicate.test
+
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_insert_duplicate.test
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_insert_ignore.test b/mysql-test/suite/rpl/t/rpl_insert_ignore.test
index f8887c96b55..0346975fcee 100644
--- a/mysql-test/suite/rpl/t/rpl_insert_ignore.test
+++ b/mysql-test/suite/rpl/t/rpl_insert_ignore.test
@@ -7,7 +7,10 @@
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-let $engine_type=innodb;
-let $engine_type2=myisam;
+-- let $engine_type=innodb
-- source extra/rpl_tests/rpl_insert_ignore.test
+
+-- let $engine_type=myisam
+-- source extra/rpl_tests/rpl_insert_ignore.test
+
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
index 8848903a30c..a54d216cb7c 100644
--- a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
+++ b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
@@ -151,12 +151,34 @@ eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
--echo [slave]
sync_slave_with_master;
-# cleanup
+--echo
+--echo Bug #59267:
+--echo "LOAD DATA LOCAL INFILE not executed on slave with SBR"
+--echo
---remove_file $MYSQLD_DATADIR/bug43746.sql
+--echo [master]
+connection master;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval SELECT * INTO OUTFILE '$MYSQLD_DATADIR/bug59267.sql' FROM t1;
+TRUNCATE TABLE t1;
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1;
+
+SELECT 'Master', COUNT(*) FROM t1;
+
+--echo [slave]
+--sync_slave_with_master
+SELECT 'Slave', COUNT(*) FROM t1;
+
+# cleanup
--echo [master]
connection master;
+
+--remove_file $MYSQLD_DATADIR/bug43746.sql
+--remove_file $MYSQLD_DATADIR/bug59267.sql
+
DROP TABLE t1;
SET SESSION sql_mode=@old_mode;
diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result
index e635f1201a3..418330f078d 100644
--- a/mysql-test/suite/sys_vars/r/all_vars.result
+++ b/mysql-test/suite/sys_vars/r/all_vars.result
@@ -11,7 +11,9 @@ There should be *no* long test name listed below:
select variable_name as `There should be *no* variables listed below:` from t2
left join t1 on variable_name=test_name where test_name is null;
There should be *no* variables listed below:
+INNODB_STATS_METHOD
INNODB_FILE_FORMAT_MAX
+INNODB_STATS_METHOD
INNODB_FILE_FORMAT_MAX
drop table t1;
drop table t2;
diff --git a/mysql-test/suite/sys_vars/r/secure_file_priv2.result b/mysql-test/suite/sys_vars/r/secure_file_priv2.result
new file mode 100644
index 00000000000..ec91b6037d0
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/secure_file_priv2.result
@@ -0,0 +1,6 @@
+CREATE TABLE t1 (c1 INT);
+LOAD DATA INFILE "t1.MYI" into table t1;
+ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
+LOAD DATA INFILE "/test" into table t1;
+ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
+DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt b/mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt
new file mode 100644
index 00000000000..1d9a49c8f75
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv2-master.opt
@@ -0,0 +1 @@
+--secure_file_priv=$SECURE_LOAD_PATH
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv2.test b/mysql-test/suite/sys_vars/t/secure_file_priv2.test
new file mode 100644
index 00000000000..0ca0a1839e1
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv2.test
@@ -0,0 +1,23 @@
+#
+# Bug58747 breaks secure_file_priv+not secure yet+still accesses other folders
+#
+CREATE TABLE t1 (c1 INT);
+#
+# Before the patch this statement failed with
+# Linux:
+# -> errno 13: 'Can't get stat of '
+# Windows:
+# -> Warning 1366 Incorrect integer value: '■■☺' for
+# -> column 'c1' at row 1
+# Now it should consistently fail with ER_OPTION_PREVENTS_STATEMENT
+# on all platforms.
+--error ER_OPTION_PREVENTS_STATEMENT
+LOAD DATA INFILE "t1.MYI" into table t1;
+
+#
+# The following test makes the assuption that /test isn't a valid path in any
+# operating system running the test suite.
+--error ER_OPTION_PREVENTS_STATEMENT
+LOAD DATA INFILE "/test" into table t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/csv_not_null.test b/mysql-test/t/csv_not_null.test
index 03ed566fb22..bebea53b2f7 100644
--- a/mysql-test/t/csv_not_null.test
+++ b/mysql-test/t/csv_not_null.test
@@ -55,10 +55,8 @@ INSERT INTO t1 VALUES();
SELECT * FROM t1;
-- disable_warnings
-# NOTE - Test disabled due to enum crash for this INSERT
-# See Bug#33717 - INSERT...(default) fails for enum.
-# Crashes CSV tables, loads spaces for MyISAM
-#INSERT INTO t1 VALUES(default,default,default,default,default,default);
+# Bug#33717 - INSERT...(default) fails for enum.
+INSERT INTO t1 VALUES(default,default,default,default,default,default);
-- enable_warnings
SELECT * FROM t1;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 60af4159650..985493481e9 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -11,8 +11,6 @@
##############################################################################
lowercase_table3 : Bug#54845 2010-06-30 alik main.lowercase_table3 on Mac OSX
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
-main.mysqlhotcopy_myisam : Bug#56817 2010-10-21 anitha mysqlhotcopy* fails
-main.mysqlhotcopy_archive: Bug#56817 2010-10-21 anitha mysqlhotcopy* fails
log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists
read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists
sum_distinct-big : Bug#56927 2010-11-15 mattiasj was not tested
diff --git a/mysql-test/t/filesort_debug.test b/mysql-test/t/filesort_debug.test
new file mode 100644
index 00000000000..0058a6a3aa7
--- /dev/null
+++ b/mysql-test/t/filesort_debug.test
@@ -0,0 +1,23 @@
+--source include/have_debug.inc
+
+SET @old_debug= @@session.debug;
+
+--echo #
+--echo # Bug#36022 please log more information about "Sort aborted" queries
+--echo #
+
+CREATE TABLE t1(f0 int auto_increment primary key, f1 int);
+INSERT INTO t1(f1) VALUES (0),(1),(2),(3),(4),(5);
+
+SET session debug= '+d,make_char_array_fail';
+CALL mtr.add_suppression("Out of sort memory");
+--error ER_OUT_OF_SORTMEMORY
+SELECT * FROM t1 ORDER BY f1 ASC, f0;
+SET session debug= @old_debug;
+
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+--error ER_SP_WRONG_NO_OF_ARGS
+DELETE FROM t1 ORDER BY (f1(10)) LIMIT 1;
+
+DROP TABLE t1;
+DROP FUNCTION f1;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 2c4a7f4c7b1..a0527f70b25 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -1120,6 +1120,17 @@ SELECT RELEASE_LOCK('aaaaaaaaaaaaaaaaa');
--echo #
--echo End of 5.1 tests
+###
+--echo #
+--echo # Bug#52123 Assertion failed: aggregator == aggr->Aggrtype(),
+--echo # file .\item_sum.cc, line 587
+--echo #
+
+CREATE TABLE t1(a int, KEY(a));
+INSERT INTO t1 VALUES (1), (2);
+SELECT 1 FROM t1 ORDER BY AVG(DISTINCT a);
+DROP TABLE t1;
+
--echo #
--echo # Bug#55648: Server crash on MIN/MAX on maximum time value
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 25600a2d583..eaa592c2ad5 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -802,6 +802,26 @@ select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND;
select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
+
+--echo #
+--echo # Bug #52315 part 2 : utc_date() crashes when system time > year 2037
+--echo #
+
+--disable_result_log
+SET TIMESTAMP=-147490000; SELECT UTC_TIMESTAMP();
+--error ER_WRONG_VALUE_FOR_VAR
+SET TIMESTAMP=2147483648; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483646; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483647; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=0; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=-1; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=1; SELECT UTC_TIMESTAMP();
+--enable_result_log
+
+#reset back the timestamp value
+SET TIMESTAMP=0;
+
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 4eefb9beded..845b976c031 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1295,6 +1295,107 @@ SELECT CURRENT_USER();
SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin");
SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
+#
+# Bug#57952: privilege change is not taken into account by EXECUTE.
+#
+
+--echo
+--echo # Bug#57952
+--echo
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest1;
+DROP DATABASE IF EXISTS mysqltest2;
+--enable_warnings
+
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+
+use mysqltest1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 1);
+
+CREATE TABLE t2(a INT);
+INSERT INTO t2 VALUES (2);
+
+CREATE TABLE mysqltest2.t3(a INT);
+INSERT INTO mysqltest2.t3 VALUES (4);
+
+CREATE USER testuser@localhost;
+GRANT CREATE ROUTINE, EXECUTE ON mysqltest1.* TO testuser@localhost;
+GRANT SELECT(b) ON t1 TO testuser@localhost;
+GRANT SELECT ON t2 TO testuser@localhost;
+GRANT SELECT ON mysqltest2.* TO testuser@localhost;
+
+--echo
+--echo # Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
+--connect (bug57952_con1,localhost,testuser,,mysqltest1)
+PREPARE s1 FROM 'SELECT b FROM t1';
+PREPARE s2 FROM 'SELECT a FROM t2';
+PREPARE s3 FROM 'SHOW TABLES FROM mysqltest2';
+
+CREATE PROCEDURE p1() SELECT b FROM t1;
+CREATE PROCEDURE p2() SELECT a FROM t2;
+CREATE PROCEDURE p3() SHOW TABLES FROM mysqltest2;
+
+CALL p1;
+CALL p2;
+CALL p3;
+
+--echo
+--echo # Connection: default
+--connection default
+REVOKE SELECT ON t1 FROM testuser@localhost;
+GRANT SELECT(a) ON t1 TO testuser@localhost;
+REVOKE SELECT ON t2 FROM testuser@localhost;
+REVOKE SELECT ON mysqltest2.* FROM testuser@localhost;
+
+--echo
+--echo # Connection: bug57952_con1 (testuser@localhost, db: mysqltest1)
+--connection bug57952_con1
+--echo # - Check column-level privileges...
+--error ER_COLUMNACCESS_DENIED_ERROR
+EXECUTE s1;
+
+--error ER_COLUMNACCESS_DENIED_ERROR
+SELECT b FROM t1;
+
+--error ER_COLUMNACCESS_DENIED_ERROR
+EXECUTE s1;
+
+--error ER_COLUMNACCESS_DENIED_ERROR
+CALL p1;
+
+--echo # - Check table-level privileges...
+--error ER_TABLEACCESS_DENIED_ERROR
+SELECT a FROM t2;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+EXECUTE s2;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+CALL p2;
+
+--echo # - Check database-level privileges...
+--error ER_DBACCESS_DENIED_ERROR
+SHOW TABLES FROM mysqltest2;
+
+--error ER_DBACCESS_DENIED_ERROR
+EXECUTE s3;
+
+--error ER_DBACCESS_DENIED_ERROR
+CALL p3;
+
+--echo
+--echo # Connection: default
+--connection default
+--disconnect bug57952_con1
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+DROP USER testuser@localhost;
+use test;
+--echo
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/innodb_mysql_sync.test b/mysql-test/t/innodb_mysql_sync.test
index 22c6f3874bc..a8925306c70 100644
--- a/mysql-test/t/innodb_mysql_sync.test
+++ b/mysql-test/t/innodb_mysql_sync.test
@@ -147,6 +147,139 @@ SET DEBUG_SYNC= 'RESET';
disconnect con1;
+--echo #
+--echo # Bug#42230 during add index, cannot do queries on storage engines
+--echo # that implement add_index
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect(con1,localhost,root);
+connect(con2,localhost,root);
+
+--echo # Test 1: Secondary index, should not block reads (original test case).
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, value INT) engine=innodb;
+INSERT INTO db1.t1(value) VALUES (1), (2);
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE db1.t1 ADD INDEX(value)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+# Neither of these two statements should be blocked
+USE db1;
+SELECT * FROM t1;
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE db1.t1 ADD INDEX(value)
+--reap
+DROP DATABASE db1;
+
+--echo # Test 2: Primary index (implicit), should block reads.
+
+CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE t1 ADD UNIQUE INDEX(a)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+USE test;
+--echo # Sending:
+--send SELECT * FROM t1
+
+--echo # Connection con2
+connection con2;
+--echo # Waiting for SELECT to be blocked by the metadata lock on t1
+let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
+ WHERE state= 'Waiting for table metadata lock'
+ AND info='SELECT * FROM t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE t1 ADD UNIQUE INDEX(a)
+--reap
+
+--echo # Connection con1
+connection con1;
+--echo # Reaping: SELECT * FROM t1
+--reap
+
+--echo # Test 3: Primary index (explicit), should block reads.
+
+--echo # Connection default
+connection default;
+ALTER TABLE t1 DROP INDEX a;
+SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+--echo # Sending:
+--send ALTER TABLE t1 ADD PRIMARY KEY (a)
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= "now WAIT_FOR manage";
+--echo # Sending:
+--send SELECT * FROM t1
+
+--echo # Connection con2
+connection con2;
+--echo # Waiting for SELECT to be blocked by the metadata lock on t1
+let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
+ WHERE state= 'Waiting for table metadata lock'
+ AND info='SELECT * FROM t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= "now SIGNAL query";
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER TABLE t1 ADD PRIMARY KEY (a)
+--reap
+
+--echo # Connection con1
+connection con1;
+--echo # Reaping: SELECT * FROM t1
+--reap
+
+--echo # Test 4: Secondary unique index, should not block reads.
+# This requires HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE to be supported
+# by InnoDB. Adding this flag currently introduces a regression so
+# this test is disabled until the regression has been fixed.
+
+--echo # Connection default
+connection default;
+#SET DEBUG_SYNC= "alter_table_manage_keys SIGNAL manage WAIT_FOR query";
+#--echo # Sending:
+#--send ALTER TABLE t1 ADD UNIQUE (b)
+
+#--echo # Connection con1
+#connection con1;
+#SET DEBUG_SYNC= "now WAIT_FOR manage";
+#SELECT * FROM t1;
+#SET DEBUG_SYNC= "now SIGNAL query";
+
+#--echo # Connection default
+#connection default;
+#--echo # Reaping: ALTER TABLE t1 ADD UNIQUE (b)
+#--reap
+
+disconnect con1;
+disconnect con2;
+SET DEBUG_SYNC= "RESET";
+DROP TABLE t1;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 72d27d3571a..991854cfb78 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1092,4 +1092,128 @@ FROM BB table1 RIGHT JOIN BB table2
DROP TABLE BB;
+
+--echo #
+--echo # Bug#58490: Incorrect result in multi level OUTER JOIN
+--echo # in combination with IS NULL
+--echo #
+
+CREATE TABLE t1 (i INT NOT NULL);
+INSERT INTO t1 VALUES (0), (2),(3),(4);
+CREATE TABLE t2 (i INT NOT NULL);
+INSERT INTO t2 VALUES (0),(1), (3),(4);
+CREATE TABLE t3 (i INT NOT NULL);
+INSERT INTO t3 VALUES (0),(1),(2), (4);
+CREATE TABLE t4 (i INT NOT NULL);
+INSERT INTO t4 VALUES (0),(1),(2),(3) ;
+
+SELECT * FROM
+ t1 LEFT JOIN
+ ( t2 LEFT JOIN
+ ( t3 LEFT JOIN
+ t4
+ ON t4.i = t3.i
+ )
+ ON t3.i = t2.i
+ )
+ ON t2.i = t1.i
+ ;
+
+SELECT * FROM
+ t1 LEFT JOIN
+ ( t2 LEFT JOIN
+ ( t3 LEFT JOIN
+ t4
+ ON t4.i = t3.i
+ )
+ ON t3.i = t2.i
+ )
+ ON t2.i = t1.i
+ WHERE t4.i IS NULL;
+
+
+# Most simplified testcase to reproduce the bug.
+# (Has to be at least a two level nested outer join)
+SELECT * FROM
+ t1 LEFT JOIN
+ ( ( t2 LEFT JOIN
+ t3
+ ON t3.i = t2.i
+ )
+ )
+ ON t2.i = t1.i
+ WHERE t3.i IS NULL;
+
+
+# Extended testing:
+# We then add some equi-join inside the query above:
+# (There Used to be some problems here with first
+# proposed patch for this bug)
+SELECT * FROM
+ t1 LEFT JOIN
+ ( ( t2 LEFT JOIN
+ t3
+ ON t3.i = t2.i
+ )
+ JOIN t4
+ ON t4.i=t2.i
+ )
+ ON t2.i = t1.i
+ WHERE t3.i IS NULL;
+
+SELECT * FROM
+ t1 LEFT JOIN
+ ( ( t2 LEFT JOIN
+ t3
+ ON t3.i = t2.i
+ )
+ JOIN (t4 AS t4a JOIN t4 AS t4b ON t4a.i=t4b.i)
+ ON t4a.i=t2.i
+ )
+ ON t2.i = t1.i
+ WHERE t3.i IS NULL;
+
+SELECT * FROM
+ t1 LEFT JOIN
+ ( ( t2 LEFT JOIN
+ t3
+ ON t3.i = t2.i
+ )
+ JOIN (t4 AS t4a, t4 AS t4b)
+ ON t4a.i=t2.i
+ )
+ ON t2.i = t1.i
+ WHERE t3.i IS NULL;
+
+
+DROP TABLE t1,t2,t3,t4;
+
+## Bug#49322 & bug#58490 are duplicates. However, we include testcases
+## for both.
+--echo #
+--echo # Bug#49322(Duplicate): Server is adding extra NULL row
+--echo # on processing a WHERE clause
+--echo #
+
+CREATE TABLE h (pk INT NOT NULL, col_int_key INT);
+INSERT INTO h VALUES (1,NULL),(4,2),(5,2),(3,4),(2,8);
+
+CREATE TABLE m (pk INT NOT NULL, col_int_key INT);
+INSERT INTO m VALUES (1,2),(2,7),(3,5),(4,7),(5,5),(6,NULL),(7,NULL),(8,9);
+CREATE TABLE k (pk INT NOT NULL, col_int_key INT);
+INSERT INTO k VALUES (1,9),(2,2),(3,5),(4,2),(5,7),(6,0),(7,5);
+
+# Baseline query wo/ 'WHERE ... IS NULL' - was correct
+SELECT TABLE1.pk FROM k TABLE1
+RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key
+RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key;
+
+# Adding 'WHERE ... IS NULL' -> incorrect result
+SELECT TABLE1.pk FROM k TABLE1
+RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key
+RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key
+WHERE TABLE1.pk IS NULL;
+
+DROP TABLE h,m,k;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 7b5b2a0ded0..a7c9dc54042 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -425,6 +425,12 @@ drop table t1;
--echo
--exec $MYSQL --skip-column-names --vertical test -e "select 1 as a"
+#
+# Bug#57450: mysql client enter in an infinite loop if the standard input is a directory
+#
+--error 1
+--exec $MYSQL < .
+
--echo
--echo #
diff --git a/mysql-test/t/mysqld--defaults-file.test b/mysql-test/t/mysqld--defaults-file.test
new file mode 100644
index 00000000000..065436c38aa
--- /dev/null
+++ b/mysql-test/t/mysqld--defaults-file.test
@@ -0,0 +1,47 @@
+# BUG#58455
+# Starting mysqld with defaults file without extension cause
+# segmentation fault
+
+source include/not_embedded.inc;
+source include/not_windows.inc;
+
+# We need to use a plain "mysqld" without any other options to trigger
+# the bug. In particular, it seems that passing --bootstrap does not
+# trigger the bug. To do that, we extract the "command name" from the
+# MYSQLD_BOOTSTRAP_CMD variable and store that in a file, which we
+# then load into the test case.
+
+perl;
+ my ($mysqld)= split " ", $ENV{MYSQLD_BOOTSTRAP_CMD};
+ open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/mysqld.inc") or die;
+ print FILE "let \$MYSQLD= $mysqld;\n";
+ close FILE;
+EOF
+
+source $MYSQL_TMP_DIR/mysqld.inc;
+
+# All these tests refer to configuration files that do not exist
+
+--error 1
+exec $MYSQLD --defaults-file=/path/with/no/extension --print-defaults 2>&1;
+
+--error 1
+exec $MYSQLD --defaults-file=/path/with.ext --print-defaults 2>&1;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--error 1
+exec $MYSQLD --defaults-file=relative/path/with.ext --print-defaults 2>&1;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--error 1
+exec $MYSQLD --defaults-file=relative/path/without/extension --print-defaults 2>&1;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--error 1
+exec $MYSQLD --defaults-file=with.ext --print-defaults 2>&1;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--error 1
+exec $MYSQLD --defaults-file=no_extension --print-defaults 2>&1;
+
+remove_file $MYSQL_TMP_DIR/mysqld.inc;
diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
index c1dbba82292..5b99c37ee29 100644
--- a/mysql-test/t/not_embedded_server.test
+++ b/mysql-test/t/not_embedded_server.test
@@ -14,6 +14,16 @@ call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was
SHOW VARIABLES like 'slave_skip_errors';
+--echo #
+--echo # Bug#58026: massive recursion and crash in regular expression handling
+--echo #
+
+--disable_result_log
+--error ER_STACK_OVERRUN_NEED_MORE
+SELECT '1' RLIKE RPAD('1', 10000, '(');
+--enable_result_log
+
+
# End of 5.1 tests
--echo #
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 7869a01a84d..5998d6269fb 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -843,7 +843,8 @@ create table t1(a int, b tinytext);
insert into t1 values (1,2),(3,2);
set session sort_buffer_size= 30000;
set session max_sort_length= 2180;
---error 1038
+CALL mtr.add_suppression("Out of sort memory");
+--error ER_OUT_OF_SORTMEMORY
select * from t1 order by b;
drop table t1;
@@ -1492,6 +1493,23 @@ LIMIT 2;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug #59110: Memory leak of QUICK_SELECT_I allocated memory
+--echo # and
+--echo # Bug #59308: Incorrect result for
+--echo SELECT DISTINCT <col>... ORDER BY <col> DESC
+--echo
+--echo # Use Valgrind to detect #59110!
+--echo #
+
+CREATE TABLE t1 (a INT,KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+
+EXPLAIN SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
+SELECT DISTINCT a,1 FROM t1 WHERE a <> 1 ORDER BY a DESC;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test
index 1e0032a2bfa..61b14b81fca 100644
--- a/mysql-test/t/partition_error.test
+++ b/mysql-test/t/partition_error.test
@@ -11,6 +11,21 @@ drop table if exists t1, t2;
let $MYSQLD_DATADIR= `SELECT @@datadir`;
--echo #
+--echo # Bug#57924: crash when creating partitioned table with
+--echo # multiple columns in the partition key
+--echo #
+--error ER_SAME_NAME_PARTITION_FIELD
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(a, b, a);
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(A, b);
+DROP TABLE t1;
+--error ER_SAME_NAME_PARTITION_FIELD
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b))
+PARTITION BY KEY(a, b, A);
+
+
+--echo #
--echo # Bug#54483: valgrind errors when making warnings for multiline inserts
--echo # into partition
--echo #
@@ -670,7 +685,6 @@ PARTITION BY HASH (TIME_TO_SEC(a));
CREATE TABLE t1 (a INT)
PARTITION BY HASH (TIME_TO_SEC(a));
-
--echo #
--echo # Bug#50036: Inconsistent errors when using TIMESTAMP
--echo # columns/expressions
diff --git a/mysql-test/t/plugin_auth.test b/mysql-test/t/plugin_auth.test
index 5efb50a41e1..753593efc94 100644
--- a/mysql-test/t/plugin_auth.test
+++ b/mysql-test/t/plugin_auth.test
@@ -411,4 +411,26 @@ FLUSH PRIVILEGES;
--echo # Executing 'mysql_upgrade'
--exec $MYSQL_UPGRADE -u root -S $MASTER_MYSOCK -P $MASTER_MYPORT --default-auth=auth_test_plugin $PLUGIN_AUTH_OPT --skip-verbose --force --upgrade-system-tables
+--echo #
+--echo # Bug #59657: Move the client authentication_pam plugin into the
+--echo # server repository
+--echo #
+
+CREATE USER uplain@localhost IDENTIFIED WITH 'cleartext_plugin_server'
+ AS 'cleartext_test';
+
+--echo ## test plugin auth
+--disable_query_log
+--error ER_ACCESS_DENIED_ERROR : this should fail : no grant
+connect(cleartext_fail_con,localhost,uplain,cleartext_test2);
+--enable_query_log
+
+connect(cleartext_con,localhost,uplain,cleartext_test);
+connection cleartext_con;
+select USER(),CURRENT_USER();
+
+connection default;
+disconnect cleartext_con;
+DROP USER uplain@localhost;
+
--echo End of 5.5 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 0ad3d3e8504..6c9320b708a 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1325,4 +1325,71 @@ SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
DROP TABLE t1;
+--echo #
+--echo # Bug #57030: 'BETWEEN' evaluation is incorrect
+--echo #
+
+# Test some BETWEEN predicates which does *not* follow the
+# 'normal' pattern of <field> BETWEEN <low const> AND <high const>
+
+CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT);
+CREATE UNIQUE INDEX i4_uq ON t1(i4);
+
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30);
+
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+
+#Should detect the EQ_REF 't2.pk=t1.i4'
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/ssl_and_innodb.test b/mysql-test/t/ssl_and_innodb.test
new file mode 100644
index 00000000000..4966f05b37b
--- /dev/null
+++ b/mysql-test/t/ssl_and_innodb.test
@@ -0,0 +1,11 @@
+-- source include/have_innodb.inc
+-- source include/have_ssl_crypto_functs.inc
+
+CREATE TABLE t1(a int) engine=innodb;
+INSERT INTO t1 VALUES (1);
+
+SELECT DISTINCT
+convert((SELECT des_decrypt(2,1) AS a FROM t1 WHERE @a:=1), signed) as d
+FROM t1 ;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index 073fcd28246..87b874bc81f 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -39,7 +39,8 @@ drop table t2;
#
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-eval create table t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="$MYSQLTEST_VARDIR/tmp" index directory="$MYSQLTEST_VARDIR/run";
+eval create table t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam data directory="$MYSQLTEST_VARDIR/tmp" index directory="$MYSQLTEST_VARDIR/run";
insert into t9 select * from t1;
check table t9;
@@ -71,21 +72,25 @@ SHOW CREATE TABLE t9;
create database mysqltest;
--error 1,1
-create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="/this-dir-does-not-exist";
# temporarily disabled as it returns different result in the embedded server
-# --error ER_WRONG_ARGUMENTS, ER_WRONG_ARGUMENTS
-# create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
+--error ER_WRONG_TABLE_NAME
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="not-hard-path";
# Should fail becasue the file t9.MYI already exist in 'run'
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1,1,ER_UNKNOWN_ERROR
-eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="$MYSQLTEST_VARDIR/run";
+eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam index directory="$MYSQLTEST_VARDIR/run";
# Should fail becasue the file t9.MYD already exist in 'tmp'
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1,1
-eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="$MYSQLTEST_VARDIR/tmp";
+eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a))
+engine=myisam data directory="$MYSQLTEST_VARDIR/tmp";
# Check moving table t9 from default database to mysqltest;
# In this case the symlinks should be removed.
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index ca2a7804907..25d3c8f7e91 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -445,6 +445,17 @@ SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS
# show we truncate microseconds from the right
SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
+--echo #
+--echo # Bug#59173: Failure to handle DATE(TIME) values where Year, Month or
+--echo # Day is ZERO
+--echo #
+CREATE TABLE t1 (dt1 DATETIME);
+INSERT INTO t1 (dt1) VALUES ('0000-00-01 00:00:01');
+DELETE FROM t1 WHERE dt1 = '0000-00-01 00:00:01';
+--echo # Should be empty
+SELECT * FROM t1;
+DROP TABLE t1;
+
--echo End of 5.1 tests
--echo #
diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test
index d8da4ccc82c..1a9e66478e1 100644
--- a/mysql-test/t/type_year.test
+++ b/mysql-test/t/type_year.test
@@ -150,5 +150,15 @@ SELECT ta.y AS ta_y, ta.s, tb.y AS tb_y, tb.s FROM t1 ta, t1 tb HAVING ta_y = tb
DROP TABLE t1;
--echo #
+--echo # Bug #59211: Select Returns Different Value for min(year) Function
+--echo #
+
+CREATE TABLE t1(c1 YEAR(4));
+INSERT INTO t1 VALUES (1901),(2155),(0000);
+SELECT * FROM t1;
+SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
+DROP TABLE t1;
+
+--echo #
--echo End of 5.1 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index b1a54495330..6a64343b609 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -351,6 +351,18 @@ DROP TABLE t1;
select @v:=@v:=sum(1) from dual;
+#
+# Bug #57187: more user variable fun with multiple assignments and
+# comparison in query
+#
+
+CREATE TABLE t1(a DECIMAL(31,21));
+INSERT INTO t1 VALUES (0);
+
+SELECT (@v:=a) <> (@v:=1) FROM t1;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests
#
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index d31939ed3dd..2b20bbdc13b 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -779,7 +779,7 @@ SET @@myisam_mmap_size= 500M;
--echo # Bug #52315: utc_date() crashes when system time > year 2037
--echo #
---error 0, ER_UNKNOWN_ERROR
+--error 0, ER_WRONG_VALUE_FOR_VAR
SET TIMESTAMP=2*1024*1024*1024;
--echo #Should not crash
--disable_result_log
@@ -1476,3 +1476,29 @@ drop function t1_max;
###########################################################################
+
+
+--echo #
+--echo # Bug #59884: setting charset to 2048 crashes
+--echo #
+
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_results = 2048;
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_client=2048;
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_connection=2048;
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_server=2048;
+--error ER_UNKNOWN_COLLATION
+set session collation_server=2048;
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_filesystem=2048;
+--error ER_UNKNOWN_CHARACTER_SET
+set session character_set_database=2048;
+--error ER_UNKNOWN_COLLATION
+set session collation_connection=2048;
+--error ER_UNKNOWN_COLLATION
+set session collation_database=2048;
+
+--echo End of 5.5 tests
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 4526575dafa..e641efbdecc 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2008 MySQL AB
+# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -10,10 +10,9 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
-# You should have received a copy of the GNU Library General Public
-# License along with this library; if not, write to the Free
-# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-# MA 02111-1307, USA
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Suppress some common (not fatal) errors in system libraries found by valgrind
@@ -807,7 +806,6 @@
fun:my_malloc
fun:_lf_dynarray_lvalue
fun:_lf_pinbox_get_pins
- fun:lf_pinbox_get_pins
}
{
@@ -837,3 +835,45 @@
fun:lf_hash_search
}
+{
+ Bug 59874 Valgrind warning in InnoDB compression code
+ Memcheck:Cond
+ fun:*
+ fun:*
+ fun:deflate
+ fun:btr_store_big_rec_extern_fields_func
+ fun:row_ins_index_entry_low
+ fun:row_ins_index_entry
+ fun:row_ins_index_entry_step
+ fun:row_ins
+ fun:row_ins_step
+ fun:row_insert_for_mysql
+}
+
+{
+ In page0zip.c we have already checked that the memory is initialized before calling deflate()
+ Memcheck:Cond
+ fun:*
+ fun:*
+ fun:deflate
+ fun:page_zip_compress
+}
+
+{
+ In page0zip.c we have already checked that the memory is initialized before calling deflate()
+ Memcheck:Cond
+ fun:*
+ fun:*
+ fun:deflate
+ fun:page_zip_compress_deflate
+}
+
+{
+ Bug 59875 Valgrind warning in buf0buddy.c
+ Memcheck:Addr1
+ fun:mach_read_from_4
+ fun:buf_buddy_relocate
+ fun:buf_buddy_free_low
+ fun:buf_buddy_free
+ fun:buf_LRU_block_remove_hashed_page
+}
diff --git a/mysys/charset.c b/mysys/charset.c
index 167d6b8ff6e..c2c46ba3fb4 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -419,6 +419,7 @@ CHARSET_INFO *default_charset_info = &my_charset_latin1;
void add_compiled_collation(CHARSET_INFO *cs)
{
+ DBUG_ASSERT(cs->number < array_elements(all_charsets));
all_charsets[cs->number]= cs;
cs->state|= MY_CS_AVAILABLE;
}
@@ -529,14 +530,17 @@ uint get_charset_number(const char *charset_name, uint cs_flags)
const char *get_charset_name(uint charset_number)
{
- CHARSET_INFO *cs;
my_pthread_once(&charsets_initialized, init_available_charsets);
- cs=all_charsets[charset_number];
- if (cs && (cs->number == charset_number) && cs->name )
- return (char*) cs->name;
+ if (charset_number < array_elements(all_charsets))
+ {
+ CHARSET_INFO *cs= all_charsets[charset_number];
+
+ if (cs && (cs->number == charset_number) && cs->name)
+ return (char*) cs->name;
+ }
- return (char*) "?"; /* this mimics find_type() */
+ return "?"; /* this mimics find_type() */
}
@@ -545,6 +549,8 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
char buf[FN_REFLEN];
CHARSET_INFO *cs;
+ DBUG_ASSERT(cs_number < array_elements(all_charsets));
+
if ((cs= all_charsets[cs_number]))
{
if (cs->state & MY_CS_READY) /* if CS is already initialized */
@@ -589,8 +595,8 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags)
return default_charset_info;
my_pthread_once(&charsets_initialized, init_available_charsets);
-
- if (!cs_number || cs_number > array_elements(all_charsets))
+
+ if (cs_number >= array_elements(all_charsets))
return NULL;
cs=get_internal_charset(cs_number, flags);
diff --git a/mysys/default.c b/mysys/default.c
index 432c3086254..9a4b990f003 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -179,7 +179,7 @@ fn_expand(const char *filename, char *result_buf)
if (my_getwd(dir, sizeof(dir), MYF(0)))
DBUG_RETURN(3);
DBUG_PRINT("debug", ("dir: %s", dir));
- if (fn_format(result_buf, filename, dir, NULL, flags) == NULL)
+ if (fn_format(result_buf, filename, dir, "", flags) == NULL)
DBUG_RETURN(2);
DBUG_PRINT("return", ("result: %s", result_buf));
DBUG_RETURN(0);
diff --git a/mysys/mf_format.c b/mysys/mf_format.c
index 6afa2938fa3..74f114a966f 100644
--- a/mysys/mf_format.c
+++ b/mysys/mf_format.c
@@ -31,6 +31,8 @@ char * fn_format(char * to, const char *name, const char *dir,
reg1 size_t length;
size_t dev_length;
DBUG_ENTER("fn_format");
+ DBUG_ASSERT(name != NULL);
+ DBUG_ASSERT(extension != NULL);
DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
name,dir,extension,flag));
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index e184c8308fc..6e81b644bae 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 01b3b912aae..63280f40f2a 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/plugin/auth/auth_socket.c b/plugin/auth/auth_socket.c
index dbd440025d7..b8ae00b6949 100644
--- a/plugin/auth/auth_socket.c
+++ b/plugin/auth/auth_socket.c
@@ -79,7 +79,7 @@ mysql_declare_plugin(socket_auth)
{
MYSQL_AUTHENTICATION_PLUGIN,
&socket_auth_handler,
- "socket_peercred",
+ "auth_socket",
"Sergei Golubchik",
"Unix Socket based authentication",
PLUGIN_LICENSE_GPL,
diff --git a/plugin/auth/test_plugin.c b/plugin/auth/test_plugin.c
index 161062d5b6c..d38b2782285 100644
--- a/plugin/auth/test_plugin.c
+++ b/plugin/auth/test_plugin.c
@@ -82,6 +82,36 @@ static struct st_mysql_auth auth_test_handler=
auth_test_plugin
};
+/**
+ dialog test plugin mimicking the ordinary auth mechanism. Used to test the clear text plugin API
+*/
+static int auth_cleartext_plugin(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info)
+{
+ unsigned char *pkt;
+ int pkt_len;
+
+ /* read the password */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ return CR_ERROR;
+
+ info->password_used= PASSWORD_USED_YES;
+
+ /* fail if the password is wrong */
+ if (strcmp((const char *) pkt, info->auth_string))
+ return CR_ERROR;
+
+ return CR_OK;
+}
+
+
+static struct st_mysql_auth auth_cleartext_handler=
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "mysql_clear_password", /* requires the clear text plugin */
+ auth_cleartext_plugin
+};
+
mysql_declare_plugin(test_plugin)
{
MYSQL_AUTHENTICATION_PLUGIN,
@@ -96,9 +126,24 @@ mysql_declare_plugin(test_plugin)
NULL,
NULL,
NULL
+},
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &auth_cleartext_handler,
+ "cleartext_plugin_server",
+ "Georgi Kodinov",
+ "cleartext plugin API test plugin",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ NULL
}
mysql_declare_plugin_end;
+
/********************* CLIENT SIDE ***************************************/
/*
client plugin used for testing the plugin API
diff --git a/regex/my_regex.h b/regex/my_regex.h
index 0d1cedf5430..30896e29b91 100644
--- a/regex/my_regex.h
+++ b/regex/my_regex.h
@@ -28,6 +28,7 @@ typedef struct {
/* === regcomp.c === */
+typedef int (*my_regex_stack_check_t)();
extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset);
#define REG_BASIC 0000
#define REG_EXTENDED 0001
@@ -76,7 +77,8 @@ extern void my_regfree(my_regex_t *);
/* === reginit.c === */
-extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */
+/* Should be called for multithread progs */
+extern void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func);
extern void my_regex_end(void); /* If one wants a clean end */
#ifdef __cplusplus
diff --git a/regex/regcomp.c b/regex/regcomp.c
index b41a1ae6da9..6e2d2511fc1 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -31,6 +31,9 @@ struct parse {
CHARSET_INFO *charset; /* for ctype things */
};
+/* Check if there is enough stack space for recursion. */
+my_regex_stack_check_t my_regex_enough_mem_in_stack= NULL;
+
#include "regcomp.ih"
static char nuls[10]; /* place to point scanner in event of error */
@@ -117,7 +120,7 @@ CHARSET_INFO *charset;
# define GOODFLAGS(f) ((f)&~REG_DUMP)
#endif
- my_regex_init(charset); /* Init cclass if neaded */
+ my_regex_init(charset, NULL); /* Init cclass if neaded */
preg->charset=charset;
cflags = GOODFLAGS(cflags);
if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
@@ -222,7 +225,15 @@ int stop; /* character this ERE should end at */
/* do a bunch of concatenated expressions */
conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop)
- p_ere_exp(p);
+ {
+ if (my_regex_enough_mem_in_stack &&
+ my_regex_enough_mem_in_stack())
+ {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+ p_ere_exp(p);
+ }
if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */
if (!EAT('|'))
diff --git a/regex/reginit.c b/regex/reginit.c
index 5980de24030..3d2cd64d1e7 100644
--- a/regex/reginit.c
+++ b/regex/reginit.c
@@ -4,10 +4,12 @@
#include <m_ctype.h>
#include <m_string.h>
#include "cclass.h"
+#include "my_regex.h"
static my_bool regex_inited=0;
+extern my_regex_stack_check_t my_regex_enough_mem_in_stack;
-void my_regex_init(CHARSET_INFO *cs)
+void my_regex_init(CHARSET_INFO *cs, my_regex_stack_check_t func)
{
char buff[CCLASS_LAST][256];
int count[CCLASS_LAST];
@@ -16,6 +18,7 @@ void my_regex_init(CHARSET_INFO *cs)
if (!regex_inited)
{
regex_inited=1;
+ my_regex_enough_mem_in_stack= func;
bzero((uchar*) &count,sizeof(count));
for (i=1 ; i<= 255; i++)
@@ -74,6 +77,7 @@ void my_regex_end()
int i;
for (i=0; i < CCLASS_LAST ; i++)
free((char*) cclasses[i].chars);
+ my_regex_enough_mem_in_stack= NULL;
regex_inited=0;
}
}
diff --git a/sql-common/client.c b/sql-common/client.c
index 3b7fc11a537..0ff03f6609b 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -2261,6 +2261,7 @@ typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+static int clear_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
static auth_plugin_t native_password_client_plugin=
{
@@ -2294,10 +2295,27 @@ static auth_plugin_t old_password_client_plugin=
old_password_auth_client
};
+static auth_plugin_t clear_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ "mysql_clear_password",
+ "Georgi Kodinov",
+ "Clear password authentication plugin",
+ {0,1,0},
+ "GPL",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ clear_password_auth_client
+};
+
struct st_mysql_client_plugin *mysql_client_builtins[]=
{
(struct st_mysql_client_plugin *)&native_password_client_plugin,
(struct st_mysql_client_plugin *)&old_password_client_plugin,
+ (struct st_mysql_client_plugin *)&clear_password_client_plugin,
0
};
@@ -4271,3 +4289,20 @@ static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
DBUG_RETURN(CR_OK);
}
+
+/**
+ The main function of the mysql_clear_password authentication plugin.
+*/
+
+static int clear_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ int res;
+
+ /* send password in clear text */
+ res= vio->write_packet(vio, (const unsigned char *) mysql->passwd,
+ strlen(mysql->passwd) + 1);
+
+ return res ? CR_ERROR : CR_OK;
+}
+
+
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 38384600fc1..39eee57a1c0 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -992,7 +992,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
with unsigned time_t tmp+= shift*86400L might result in a number,
larger then TIMESTAMP_MAX_VALUE, so another check will work.
*/
- if ((tmp < TIMESTAMP_MIN_VALUE) || (tmp > TIMESTAMP_MAX_VALUE))
+ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp))
tmp= 0;
return (my_time_t) tmp;
diff --git a/sql/field.cc b/sql/field.cc
index 50db2da97e4..01c4459c06c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -9073,6 +9073,7 @@ void Create_field::create_length_to_internal_length(void)
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VARCHAR:
diff --git a/sql/filesort.cc b/sql/filesort.cc
index f888206f730..cf5334cd87f 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -324,8 +324,24 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
}
if (error)
- my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
- MYF(ME_ERROR+ME_WAITTANG));
+ {
+ DBUG_ASSERT(thd->is_error());
+ my_printf_error(ER_FILSORT_ABORT,
+ "%s: %s",
+ MYF(ME_ERROR + ME_WAITTANG),
+ ER_THD(thd, ER_FILSORT_ABORT),
+ thd->stmt_da->message());
+
+ if (global_system_variables.log_warnings > 1)
+ {
+ sql_print_warning("%s, host: %s, user: %s, thread: %lu, query: %-.4096s",
+ ER_THD(thd, ER_FILSORT_ABORT),
+ thd->security_ctx->host_or_ip,
+ &thd->security_ctx->priv_user[0],
+ (ulong) thd->thread_id,
+ thd->query());
+ }
+ }
else
statistic_add(thd->status_var.filesort_rows,
(ulong) records, &LOCK_status);
@@ -369,6 +385,9 @@ static char **make_char_array(char **old_pos, register uint fields,
char *char_pos;
DBUG_ENTER("make_char_array");
+ DBUG_EXECUTE_IF("make_char_array_fail",
+ DBUG_SET("+d,simulate_out_of_memory"););
+
if (old_pos ||
(old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
my_flag)))
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index f717870915f..74f5e116ccf 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,4 +1,4 @@
-/* Copyright 2005-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -6432,28 +6432,28 @@ uint ha_partition::alter_table_flags(uint flags)
already altered, partitions. So both ADD and DROP can only be supported in
pairs.
*/
- flags_to_check= HA_ONLINE_ADD_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
- flags_to_check|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
+ flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_INDEX;
- flags_to_check|= HA_ONLINE_DROP_INDEX;
+ flags_to_check= HA_INPLACE_ADD_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX;
- flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX;
+ flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
- flags_to_check= HA_ONLINE_ADD_PK_INDEX;
- flags_to_check|= HA_ONLINE_DROP_PK_INDEX;
+ flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_WRITE;
if ((flags_to_return & flags_to_check) != flags_to_check)
flags_to_return&= ~flags_to_check;
DBUG_RETURN(flags_to_return);
diff --git a/sql/handler.cc b/sql/handler.cc
index 783e4d9ae20..f7690c28827 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/handler.h b/sql/handler.h
index 0e03ea17dde..3cd4acee80d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,7 +1,7 @@
#ifndef HANDLER_INCLUDED
#define HANDLER_INCLUDED
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -172,28 +172,31 @@
bits in alter_table_flags:
*/
/*
- These bits are set if different kinds of indexes can be created
- off-line without re-create of the table (but with a table lock).
+ These bits are set if different kinds of indexes can be created or dropped
+ in-place without re-creating the table using a temporary table.
+ NO_READ_WRITE indicates that the handler needs concurrent reads and writes
+ of table data to be blocked.
Partitioning needs both ADD and DROP to be supported by its underlying
handlers, due to error handling, see bug#57778.
*/
-#define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/
-#define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES (1L << 2) /*add unique w/lock*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES (1L << 3) /*drop uniq. w/lock*/
-#define HA_ONLINE_ADD_PK_INDEX_NO_WRITES (1L << 4) /*add prim. w/lock*/
-#define HA_ONLINE_DROP_PK_INDEX_NO_WRITES (1L << 5) /*drop prim. w/lock*/
+#define HA_INPLACE_ADD_INDEX_NO_READ_WRITE (1L << 0)
+#define HA_INPLACE_DROP_INDEX_NO_READ_WRITE (1L << 1)
+#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE (1L << 2)
+#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1L << 3)
+#define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE (1L << 4)
+#define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE (1L << 5)
/*
- These are set if different kinds of indexes can be created on-line
- (without a table lock). If a handler is capable of one or more of
- these, it should also set the corresponding *_NO_WRITES bit(s).
+ These are set if different kinds of indexes can be created or dropped
+ in-place while still allowing concurrent reads (but not writes) of table
+ data. If a handler is capable of one or more of these, it should also set
+ the corresponding *_NO_READ_WRITE bit(s).
*/
-#define HA_ONLINE_ADD_INDEX (1L << 6) /*add index online*/
-#define HA_ONLINE_DROP_INDEX (1L << 7) /*drop index online*/
-#define HA_ONLINE_ADD_UNIQUE_INDEX (1L << 8) /*add unique online*/
-#define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
-#define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
-#define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
+#define HA_INPLACE_ADD_INDEX_NO_WRITE (1L << 6)
+#define HA_INPLACE_DROP_INDEX_NO_WRITE (1L << 7)
+#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE (1L << 8)
+#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1L << 9)
+#define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1L << 10)
+#define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1L << 11)
/*
HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
supported at all.
diff --git a/sql/item.h b/sql/item.h
index d86e64eac09..fc203f03e79 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,7 +1,7 @@
#ifndef ITEM_INCLUDED
#define ITEM_INCLUDED
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3203,11 +3203,10 @@ class Item_cache: public Item_basic_constant
protected:
Item *example;
table_map used_table_map;
- /*
- Field that this object will get value from. This is set/used by
+ /**
+ Field that this object will get value from. This is used by
index-based subquery engines to detect and remove the equality injected
by IN->EXISTS transformation.
- For all other uses of Item_cache, cached_field doesn't matter.
*/
Field *cached_field;
enum enum_field_types cached_field_type;
@@ -3275,6 +3274,14 @@ public:
{
return (value_cached || cache_value()) && !null_value;
}
+
+ /**
+ If this item caches a field value, return pointer to underlying field.
+
+ @return Pointer to field, or NULL if this is not a cache for a field value.
+ */
+ Field* field() { return cached_field; }
+
virtual void store(Item *item);
virtual bool cache_value()= 0;
bool basic_const_item() const
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 5e9c0fc78b8..67635c73b43 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -918,7 +918,7 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
cache_converted_constant can't be used here because it can't
correctly convert a DATETIME value from string to int representation.
*/
- Item_cache_int *cache= new Item_cache_int();
+ Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
if (!(*a)->is_datetime())
@@ -1208,9 +1208,12 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
value of 2000.
*/
Item *real_item= item->real_item();
- if (!(real_item->type() == Item::FIELD_ITEM &&
- ((Item_field *)real_item)->field->type() == MYSQL_TYPE_YEAR &&
- ((Item_field *)real_item)->field->field_length == 4))
+ Field *field= NULL;
+ if (real_item->type() == Item::FIELD_ITEM)
+ field= ((Item_field *)real_item)->field;
+ else if (real_item->type() == Item::CACHE_ITEM)
+ field= ((Item_cache *)real_item)->field();
+ if (!(field && field->type() == MYSQL_TYPE_YEAR && field->field_length == 4))
{
if (value < 70)
value+= 100;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index b7532951230..e28d8b8bcc4 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4484,7 +4484,7 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val);
break;
case DECIMAL_RESULT:
- val= (my_decimal *)value;
+ my_decimal2decimal((my_decimal *) value, val);
break;
case STRING_RESULT:
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
diff --git a/sql/item_func.h b/sql/item_func.h
index 937907c9404..e60effc352c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1,7 +1,7 @@
#ifndef ITEM_FUNC_INCLUDED
#define ITEM_FUNC_INCLUDED
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 6145f72b665..c5c1eae2d39 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -1,7 +1,7 @@
#ifndef ITEM_GEOFUNC_INCLUDED
#define ITEM_GEOFUNC_INCLUDED
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 25eb08ffa75..0248c133f60 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -70,7 +70,7 @@ String my_empty_string("",default_charset_info);
Normally conversion does not happen, and val_str_ascii() is immediately
returned instead.
*/
-String *Item_str_ascii_func::val_str(String *str)
+String *Item_str_func::val_str_from_val_str_ascii(String *str, String *str2)
{
DBUG_ASSERT(fixed == 1);
@@ -82,19 +82,19 @@ String *Item_str_ascii_func::val_str(String *str)
return res;
}
- DBUG_ASSERT(str != &ascii_buf);
+ DBUG_ASSERT(str != str2);
uint errors;
- String *res= val_str_ascii(&ascii_buf);
+ String *res= val_str_ascii(str);
if (!res)
return 0;
- if ((null_value= str->copy(res->ptr(), res->length(),
- &my_charset_latin1, collation.collation,
- &errors)))
+ if ((null_value= str2->copy(res->ptr(), res->length(),
+ &my_charset_latin1, collation.collation,
+ &errors)))
return 0;
- return str;
+ return str2;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 24d8d354670..fef4f9f975d 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1,7 +1,7 @@
#ifndef ITEM_STRFUNC_INCLUDED
#define ITEM_STRFUNC_INCLUDED
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -51,6 +51,7 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length();
bool fix_fields(THD *thd, Item **ref);
+ String *val_str_from_val_str_ascii(String *str, String *str2);
};
@@ -66,8 +67,10 @@ public:
Item_str_ascii_func(Item *a) :Item_str_func(a) {}
Item_str_ascii_func(Item *a,Item *b) :Item_str_func(a,b) {}
Item_str_ascii_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
- String *val_str_convert_from_ascii(String *str, String *ascii_buf);
- String *val_str(String *str);
+ String *val_str(String *str)
+ {
+ return val_str_from_val_str_ascii(str, &ascii_buf);
+ }
virtual String *val_str_ascii(String *)= 0;
};
@@ -361,7 +364,9 @@ public:
{
maybe_null=1;
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
- max_length = args[0]->max_length - 9;
+ max_length= args[0]->max_length;
+ if (max_length >= 9U)
+ max_length-= 9U;
}
const char *func_name() const { return "des_decrypt"; }
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 0fd526184c4..adfa1ea66f0 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -556,24 +556,27 @@ Item *Item_sum::set_arg(uint i, THD *thd, Item *new_val)
int Item_sum::set_aggregator(Aggregator::Aggregator_type aggregator)
{
- if (aggr)
+ /*
+ Dependent subselects may be executed multiple times, making
+ set_aggregator to be called multiple times. The aggregator type
+ will be the same, but it needs to be reset so that it is
+ reevaluated with the new dependent data.
+ This function may also be called multiple times during query optimization.
+ In this case, the type may change, so we delete the old aggregator,
+ and create a new one.
+ */
+ if (aggr && aggregator == aggr->Aggrtype())
{
- /*
- Dependent subselects may be executed multiple times, making
- set_aggregator to be called multiple times. The aggregator type
- will be the same, but it needs to be reset so that it is
- reevaluated with the new dependent data.
- */
- DBUG_ASSERT(aggregator == aggr->Aggrtype());
aggr->clear();
return FALSE;
}
+
+ delete aggr;
switch (aggregator)
{
case Aggregator::DISTINCT_AGGREGATOR:
aggr= new Aggregator_distinct(this);
break;
-
case Aggregator::SIMPLE_AGGREGATOR:
aggr= new Aggregator_simple(this);
break;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 81e5e10fffa..4e2334b6c3b 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -461,10 +461,9 @@ public:
*/
virtual void no_rows_in_result()
{
- if (!aggr)
- set_aggregator(with_distinct ?
- Aggregator::DISTINCT_AGGREGATOR :
- Aggregator::SIMPLE_AGGREGATOR);
+ set_aggregator(with_distinct ?
+ Aggregator::DISTINCT_AGGREGATOR :
+ Aggregator::SIMPLE_AGGREGATOR);
aggregator_clear();
}
virtual void make_unique() { force_copy_fields= TRUE; }
@@ -515,11 +514,10 @@ public:
quick_group= with_distinct ? 0 : 1;
}
- /**
+ /*
Set the type of aggregation : DISTINCT or not.
- Called when the final determination is done about the aggregation
- type and the object is about to be used.
+ May be called multiple times.
*/
int set_aggregator(Aggregator::Aggregator_type aggregator);
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 73b8b6047e0..3d587ace335 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2205,8 +2205,6 @@ void Item_date_add_interval::fix_length_and_dec()
enum_field_types arg0_field_type;
maybe_null=1;
- fix_length_and_charset_datetime(MAX_DATETIME_FULL_WIDTH);
- value.alloc(max_length);
/*
The field type for the result of an Item_date function is defined as
@@ -2231,6 +2229,21 @@ void Item_date_add_interval::fix_length_and_dec()
else
cached_field_type= MYSQL_TYPE_DATETIME;
}
+
+ if (cached_field_type == MYSQL_TYPE_STRING)
+ {
+ /* Behave as a usual string function when return type is VARCHAR. */
+ fix_length_and_charset(MAX_DATETIME_FULL_WIDTH, default_charset());
+ }
+ else
+ {
+ /*
+ Follow the "Number-to-string conversion" rules as in WorkLog 2649
+ when return type is DATE or DATETIME.
+ */
+ fix_length_and_charset_datetime(MAX_DATETIME_FULL_WIDTH);
+ }
+ value.alloc(max_length);
}
@@ -2253,7 +2266,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
}
-String *Item_date_add_interval::val_str(String *str)
+String *Item_date_add_interval::val_str_ascii(String *str)
{
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 622d6a76e50..9732e8dc360 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1,7 +1,7 @@
#ifndef ITEM_TIMEFUNC_INCLUDED
#define ITEM_TIMEFUNC_INCLUDED
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -773,16 +773,32 @@ class Item_date_add_interval :public Item_date_func
{
String value;
enum_field_types cached_field_type;
-
+ String ascii_buf;
public:
const interval_type int_type; // keep it public
const bool date_sub_interval; // keep it public
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
:Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
- String *val_str(String *);
+ String *val_str_ascii(String *str);
+ String *val_str(String *str)
+ {
+ return val_str_from_val_str_ascii(str, &ascii_buf);
+ }
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec();
enum_field_types field_type() const { return cached_field_type; }
+ CHARSET_INFO *charset_for_protocol(void) const
+ {
+ /*
+ DATE_ADD() can return DATE, DATETIME or VARCHAR depending on arguments.
+ Send using "binary" when DATE or DATETIME,
+ or using collation.collation when VARCHAR
+ (which was fixed from @collation_connection in fix_length_and_dec).
+ */
+ DBUG_ASSERT(fixed == 1);
+ return cached_field_type == MYSQL_TYPE_STRING ?
+ collation.collation : &my_charset_bin;
+ }
longlong val_int();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
diff --git a/sql/log.cc b/sql/log.cc
index 17efbca8bb2..36501b4a007 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 02e8d8de42f..38dc3d6557e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2880,6 +2880,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
#endif
+#ifndef EMBEDDED_LIBRARY
+static
+int
+check_enough_stack_size()
+{
+ uchar stack_top;
+
+ return check_stack_overrun(current_thd, STACK_MIN_SIZE,
+ &stack_top);
+}
+#endif
+
+
/**
Initialize one of the global date/time format variables.
@@ -3081,12 +3094,6 @@ static int init_common_variables()
max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= flush_status_time= my_time(0);
- /* TODO: remove this when my_time_t is 64 bit compatible */
- if (server_start_time >= (time_t) MY_TIME_T_MAX)
- {
- sql_print_error("This MySQL server doesn't support dates later then 2038");
- return 1;
- }
rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter;
@@ -3125,6 +3132,13 @@ static int init_common_variables()
*/
mysql_bin_log.init_pthread_objects();
+ /* TODO: remove this when my_time_t is 64 bit compatible */
+ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
+ {
+ sql_print_error("This MySQL server doesn't support dates later then 2038");
+ return 1;
+ }
+
if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
{
strmake(glob_hostname, STRING_WITH_LEN("localhost"));
@@ -3340,7 +3354,11 @@ static int init_common_variables()
if (item_create_init())
return 1;
item_init();
- my_regex_init(&my_charset_latin1);
+#ifndef EMBEDDED_LIBRARY
+ my_regex_init(&my_charset_latin1, check_enough_stack_size);
+#else
+ my_regex_init(&my_charset_latin1, NULL);
+#endif
/*
Process a comma-separated character set list and choose
the first available character set. This is mostly for
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index d60e2051ccd..e2cc32015b1 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 03b151e4346..c50861d73a0 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -543,9 +543,10 @@ bool Protocol::send_ok(uint server_status, uint statement_warn_count,
const char *message)
{
DBUG_ENTER("Protocol::send_ok");
-
- DBUG_RETURN(net_send_ok(thd, server_status, statement_warn_count,
- affected_rows, last_insert_id, message));
+ const bool retval=
+ net_send_ok(thd, server_status, statement_warn_count,
+ affected_rows, last_insert_id, message);
+ DBUG_RETURN(retval);
}
@@ -558,8 +559,8 @@ bool Protocol::send_ok(uint server_status, uint statement_warn_count,
bool Protocol::send_eof(uint server_status, uint statement_warn_count)
{
DBUG_ENTER("Protocol::send_eof");
-
- DBUG_RETURN(net_send_eof(thd, server_status, statement_warn_count));
+ const bool retval= net_send_eof(thd, server_status, statement_warn_count);
+ DBUG_RETURN(retval);
}
@@ -573,8 +574,8 @@ bool Protocol::send_error(uint sql_errno, const char *err_msg,
const char *sql_state)
{
DBUG_ENTER("Protocol::send_error");
-
- DBUG_RETURN(net_send_error_packet(thd, sql_errno, err_msg, sql_state));
+ const bool retval= net_send_error_packet(thd, sql_errno, err_msg, sql_state);
+ DBUG_RETURN(retval);
}
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index b0dc4d9195b..a8b0c27d115 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -897,7 +897,7 @@ ER_OUT_OF_SORTMEMORY HY001 S1001
cze "M-Bálo paměti pro třídění. Zvyšte velikost třídícího bufferu"
dan "Ikke mere sorteringshukommelse. Øg sorteringshukommelse (sort buffer size) for serveren"
nla "Geen geheugen om te sorteren. Verhoog de server sort buffer size"
- eng "Out of sort memory; increase server sort buffer size"
+ eng "Out of sort memory, consider increasing server sort buffer size"
jps "Out of sort memory. sort buffer size が足りないようです.",
est "Mälu sai sorteerimisel otsa. Suurenda MySQL-i sorteerimispuhvrit"
fre "Manque de mémoire pour le tri. Augmentez-la."
@@ -907,10 +907,10 @@ ER_OUT_OF_SORTMEMORY HY001 S1001
ita "Memoria per gli ordinamenti esaurita. Incrementare il 'sort_buffer' al demone"
jpn "Out of sort memory. sort buffer size が足りないようです."
kor "Out of sort memory. daemon sort buffer의 크기를 증가시키세요"
- nor "Ikke mer sorteringsminne. Øk sorteringsminnet (sort buffer size) for tjenesten"
- norwegian-ny "Ikkje meir sorteringsminne. Auk sorteringsminnet (sorteringsbffer storleik) for tenesten"
+ nor "Ikke mer sorteringsminne. Vurder å øke sorteringsminnet (sort buffer size) for tjenesten"
+ norwegian-ny "Ikkje meir sorteringsminne. Vurder å auke sorteringsminnet (sorteringsbuffer storleik) for tenesten"
pol "Zbyt mało pamięci dla sortowania. Zwiększ wielko?ć bufora demona dla sortowania"
- por "Sem memória para ordenação. Aumente tamanho do 'buffer' de ordenação"
+ por "Não há memória suficiente para ordenação. Considere aumentar o tamanho do retentor (buffer) de ordenação."
rum "Out of memory pentru sortare. Largeste marimea buffer-ului pentru sortare in daemon (sort buffer size)"
rus "Недостаточно памяти для сортировки. Увеличьте размер буфера сортировки на сервере"
serbian "Nema memorije za sortiranje. Povećajte veličinu sort buffer-a MySQL server-u"
diff --git a/sql/slave.cc b/sql/slave.cc
index e9daa804cc3..a96ee505fe9 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (C) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5ac31d1f578..427e2eb7346 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -8014,7 +8014,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
end= strmake(end, plugin_name(mpvio->plugin)->str,
plugin_name(mpvio->plugin)->length);
- int res= my_net_write(mpvio->net, (uchar*) buff, (size_t) (end - buff)) ||
+ int res= my_net_write(mpvio->net, (uchar*) buff, (size_t) (end - buff + 1)) ||
net_flush(mpvio->net);
my_afree(buff);
DBUG_RETURN (res);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ab8dfd54768..8b6cc2caf10 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -6155,6 +6155,8 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
/*
Find field by name in a base table or a view with temp table algorithm.
+ The caller is expected to check column-level privileges.
+
SYNOPSIS
find_field_in_table()
thd thread handler
@@ -6262,6 +6264,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
This procedure detects the type of the table reference 'table_list'
and calls the corresponding search routine.
+ The routine checks column-level privieleges for the found field.
+
RETURN
0 field is not found
view_ref_found found value in VIEW (real result is in *ref)
@@ -6537,8 +6541,16 @@ find_field_in_tables(THD *thd, Item_ident *item,
when table_ref->field_translation != NULL.
*/
if (table_ref->table && !table_ref->view)
+ {
found= find_field_in_table(thd, table_ref->table, name, length,
TRUE, &(item->cached_field_index));
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /* Check if there are sufficient access rights to the found field. */
+ if (found && check_privileges &&
+ check_column_grant_in_table_ref(thd, table_ref, name, length))
+ found= WRONG_GRANT;
+#endif
+ }
else
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
NULL, NULL, ref, check_privileges,
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index efa125acb2e..f2a41bee707 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -272,10 +272,11 @@ const char *set_thd_proc_info(void *thd_arg, const char *info,
thd= current_thd;
const char *old_info= thd->proc_info;
- DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
- (info != NULL) ? info : "(null)"));
+ const char *basename= calling_file ? base_name(calling_file) : NULL;
+ DBUG_PRINT("proc_info", ("%s:%d %s", basename, calling_line, info));
+
#if defined(ENABLED_PROFILING)
- thd->profiling.status_change(info, calling_function, calling_file, calling_line);
+ thd->profiling.status_change(info, calling_function, basename, calling_line);
#endif
thd->proc_info= info;
return old_info;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 4104f15cfa4..5d600eab2a3 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2280,7 +2280,7 @@ public:
/*TODO: this will be obsolete when we have support for 64 bit my_time_t */
inline bool is_valid_time()
{
- return (start_time < (time_t) MY_TIME_T_MAX);
+ return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time));
}
void set_time_after_lock() { utime_after_lock= my_micro_time(); }
ulonglong current_utime() { return my_micro_time(); }
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 0b463ff1202..4475e087163 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -979,7 +979,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
- if ((changed && error <= 0) ||
+ if (error <= 0 ||
thd->transaction.stmt.modified_non_trans_table ||
was_insert_delayed)
{
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 5ec6e4a0467..a2d443fbbc8 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -363,58 +363,58 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(void) fn_format(name, ex->file_name, mysql_real_data_home, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME |
MY_RETURN_REAL_PATH);
-#if !defined(__WIN__)
- MY_STAT stat_info;
- if (!mysql_file_stat(key_file_load, name, &stat_info, MYF(MY_WME)))
- DBUG_RETURN(TRUE);
-
- // if we are not in slave thread, the file must be:
- if (!thd->slave_thread &&
- !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
- (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
- ((stat_info.st_mode & S_IFREG) == S_IFREG ||
- (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
- {
- my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
- DBUG_RETURN(TRUE);
- }
- if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
- is_fifo = 1;
-#endif
+ }
- if (thd->slave_thread)
- {
+ if (thd->slave_thread)
+ {
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
- if (strncmp(active_mi->rli.slave_patternload_file, name,
- active_mi->rli.slave_patternload_file_size))
- {
- /*
- LOAD DATA INFILE in the slave SQL Thread can only read from
- --slave-load-tmpdir". This should never happen. Please, report a bug.
- */
-
- sql_print_error("LOAD DATA INFILE in the slave SQL Thread can only read from --slave-load-tmpdir. " \
- "Please, report a bug.");
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--slave-load-tmpdir");
- DBUG_RETURN(TRUE);
- }
-#else
+ if (strncmp(active_mi->rli.slave_patternload_file, name,
+ active_mi->rli.slave_patternload_file_size))
+ {
/*
- This is impossible and should never happen.
+ LOAD DATA INFILE in the slave SQL Thread can only read from
+ --slave-load-tmpdir". This should never happen. Please, report a bug.
*/
- DBUG_ASSERT(FALSE);
-#endif
- }
- else if (!is_secure_file_path(name))
- {
- /* Read only allowed from within dir specified by secure_file_priv */
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+
+ sql_print_error("LOAD DATA INFILE in the slave SQL Thread can only read from --slave-load-tmpdir. " \
+ "Please, report a bug.");
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--slave-load-tmpdir");
DBUG_RETURN(TRUE);
}
+#else
+ /*
+ This is impossible and should never happen.
+ */
+ DBUG_ASSERT(FALSE);
+#endif
+ }
+ else if (!is_secure_file_path(name))
+ {
+ /* Read only allowed from within dir specified by secure_file_priv */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ DBUG_RETURN(TRUE);
+ }
+
+#if !defined(__WIN__) && ! defined(__NETWARE__)
+ MY_STAT stat_info;
+ if (!my_stat(name,&stat_info,MYF(MY_WME)))
+ DBUG_RETURN(TRUE);
+ // if we are not in slave thread, the file must be:
+ if (!thd->slave_thread &&
+ !((stat_info.st_mode & S_IFLNK) != S_IFLNK && // symlink
+ ((stat_info.st_mode & S_IFREG) == S_IFREG || // regular file
+ (stat_info.st_mode & S_IFIFO) == S_IFIFO))) // named pipe
+ {
+ my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
+ DBUG_RETURN(TRUE);
}
+ if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
+ is_fifo = 1;
+#endif
if ((file= mysql_file_open(key_file_load,
name, O_RDONLY, MYF(MY_WME))) < 0)
+
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0b4f956dd7f..5c2c0bb95d6 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,4 +1,4 @@
-/* Copyright 2005-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 5542a0342d1..bc0cca4d887 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB & Sasha, 2008-2009 Sun Microsystems, Inc
+/* Copyright (C) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -676,8 +676,11 @@ impossible position";
file */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg))
goto err;
+
+ my_off_t prev_pos= pos;
while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{
+ prev_pos= my_b_tell(&log);
#ifndef DBUG_OFF
if (max_binlog_dump_events && !left_events--)
{
@@ -767,8 +770,13 @@ impossible position";
here we were reading binlog that was not closed properly (as a result
of a crash ?). treat any corruption as EOF
*/
- if (binlog_can_be_corrupted && error != LOG_READ_MEM)
+ if (binlog_can_be_corrupted &&
+ error != LOG_READ_MEM && error != LOG_READ_EOF)
+ {
+ my_b_seek(&log, prev_pos);
error=LOG_READ_EOF;
+ }
+
/*
TODO: now that we are logging the offset, check to make sure
the recorded offset and the actual match.
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index fdce2510df4..3d073cf777e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3365,26 +3365,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
eq_func is NEVER true when num_values > 1
*/
if (!eq_func)
- {
- /*
- Additional optimization: if we're processing
- "t.key BETWEEN c1 AND c1" then proceed as if we were processing
- "t.key = c1".
- TODO: This is a very limited fix. A more generic fix is possible.
- There are 2 options:
- A) Make equality propagation code be able to handle BETWEEN
- (including cases like t1.key BETWEEN t2.key AND t3.key)
- B) Make range optimizer to infer additional "t.key = c" equalities
- and use them in equality propagation process (see details in
- OptimizerKBAndTodo)
- */
- if ((cond->functype() != Item_func::BETWEEN) ||
- ((Item_func_between*) cond)->negated ||
- !value[0]->eq(value[1], field->binary()))
- return;
- eq_func= TRUE;
- }
-
+ return;
if (field->result_type() == STRING_RESULT)
{
if ((*value)->result_type() != STRING_RESULT)
@@ -3580,9 +3561,65 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
case Item_func::OPTIMIZE_KEY:
{
Item **values;
- // BETWEEN, IN, NE
- if (is_local_field (cond_func->key_item()) &&
- !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
+ /*
+ Build list of possible keys for 'a BETWEEN low AND high'.
+ It is handled similar to the equivalent condition
+ 'a >= low AND a <= high':
+ */
+ if (cond_func->functype() == Item_func::BETWEEN)
+ {
+ Item_field *field_item;
+ bool equal_func= FALSE;
+ uint num_values= 2;
+ values= cond_func->arguments();
+
+ bool binary_cmp= (values[0]->real_item()->type() == Item::FIELD_ITEM)
+ ? ((Item_field*)values[0]->real_item())->field->binary()
+ : TRUE;
+
+ /*
+ Additional optimization: If 'low = high':
+ Handle as if the condition was "t.key = low".
+ */
+ if (!((Item_func_between*)cond_func)->negated &&
+ values[1]->eq(values[2], binary_cmp))
+ {
+ equal_func= TRUE;
+ num_values= 1;
+ }
+
+ /*
+ Append keys for 'field <cmp> value[]' if the
+ condition is of the form::
+ '<field> BETWEEN value[1] AND value[2]'
+ */
+ if (is_local_field (values[0]))
+ {
+ field_item= (Item_field *) (values[0]->real_item());
+ add_key_equal_fields(key_fields, *and_level, cond_func,
+ field_item, equal_func, &values[1],
+ num_values, usable_tables, sargables);
+ }
+ /*
+ Append keys for 'value[0] <cmp> field' if the
+ condition is of the form:
+ 'value[0] BETWEEN field1 AND field2'
+ */
+ for (uint i= 1; i <= num_values; i++)
+ {
+ if (is_local_field (values[i]))
+ {
+ field_item= (Item_field *) (values[i]->real_item());
+ add_key_equal_fields(key_fields, *and_level, cond_func,
+ field_item, equal_func, values,
+ 1, usable_tables, sargables);
+ }
+ }
+ } // if ( ... Item_func::BETWEEN)
+
+ // IN, NE
+ else if (is_local_field (cond_func->key_item()) &&
+ !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
{
values= cond_func->arguments()+1;
if (cond_func->functype() == Item_func::NE_FUNC &&
@@ -3596,21 +3633,6 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
cond_func->argument_count()-1,
usable_tables, sargables);
}
- if (cond_func->functype() == Item_func::BETWEEN)
- {
- values= cond_func->arguments();
- for (uint i= 1 ; i < cond_func->argument_count() ; i++)
- {
- Item_field *field_item;
- if (is_local_field (cond_func->arguments()[i]))
- {
- field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
- add_key_equal_fields(key_fields, *and_level, cond_func,
- field_item, 0, values, 1, usable_tables,
- sargables);
- }
- }
- }
break;
}
case Item_func::OPTIMIZE_OP:
@@ -11745,17 +11767,40 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
first_unmatched->found= 1;
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
- if (tab->table->reginfo.not_exists_optimize)
- return NESTED_LOOP_NO_MORE_ROWS;
/* Check all predicates that has just been activated. */
/*
Actually all predicates non-guarded by first_unmatched->found
will be re-evaluated again. It could be fixed, but, probably,
it's not worth doing now.
*/
+ /*
+ not_exists_optimize has been created from a
+ select_cond containing 'is_null'. This 'is_null'
+ predicate is still present on any 'tab' with
+ 'not_exists_optimize'. Furthermore, the usual rules
+ for condition guards also applies for
+ 'not_exists_optimize' -> When 'is_null==false' we
+ know all cond. guards are open and we can apply
+ the 'not_exists_optimize'.
+ */
+ DBUG_ASSERT(!(tab->table->reginfo.not_exists_optimize &&
+ !tab->select_cond));
+
if (tab->select_cond && !tab->select_cond->val_int())
{
/* The condition attached to table tab is false */
+
+ if (tab->table->reginfo.not_exists_optimize)
+ {
+ /*
+ When not_exists_optimize is set: No need to further
+ explore more rows of 'tab' for this partial result.
+ Any found 'tab' matches are known to evaluate to 'false'.
+ Returning .._NO_MORE_ROWS will skip rem. 'tab' rows.
+ */
+ return NESTED_LOOP_NO_MORE_ROWS;
+ }
+
if (tab == join_tab)
found= 0;
else
@@ -13574,12 +13619,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
{
int ref_key;
uint ref_key_parts;
- int order_direction;
+ int order_direction= 0;
uint used_key_parts;
TABLE *table=tab->table;
SQL_SELECT *select=tab->select;
key_map usable_keys;
QUICK_SELECT_I *save_quick= 0;
+ int best_key= -1;
+
DBUG_ENTER("test_if_skip_sort_order");
LINT_INIT(ref_key_parts);
@@ -13683,13 +13730,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
new_ref_key_map.clear_all(); // Force the creation of quick select
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
+ select->quick= 0;
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
(tab->join->select_options &
OPTION_FOUND_ROWS) ?
HA_POS_ERROR :
tab->join->unit->select_limit_cnt,0) <=
0)
- DBUG_RETURN(0);
+ goto use_filesort;
}
ref_key= new_ref_key;
}
@@ -13704,7 +13752,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
uint best_key_parts= 0;
uint saved_best_key_parts= 0;
int best_key_direction= 0;
- int best_key= -1;
JOIN *join= tab->join;
ha_rows table_records= table->file->stats.records;
@@ -13724,72 +13771,21 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
tab->join->tables > tab->join->const_tables + 1) &&
((unsigned) best_key != table->s->primary_key ||
!table->file->primary_key_is_clustered()))
- DBUG_RETURN(0);
+ goto use_filesort;
if (best_key >= 0)
{
- bool quick_created= FALSE;
if (table->quick_keys.is_set(best_key) && best_key != ref_key)
{
key_map map;
map.clear_all(); // Force the creation of quick select
map.set_bit(best_key); // only best_key.
- quick_created=
- select->test_quick_select(join->thd, map, 0,
- join->select_options & OPTION_FOUND_ROWS ?
- HA_POS_ERROR :
- join->unit->select_limit_cnt,
- 0) > 0;
- }
- if (!no_changes)
- {
- /*
- If ref_key used index tree reading only ('Using index' in EXPLAIN),
- and best_key doesn't, then revert the decision.
- */
- if (!table->covering_keys.is_set(best_key))
- table->set_keyread(FALSE);
- if (!quick_created)
- {
- tab->index= best_key;
- tab->read_first_record= best_key_direction > 0 ?
- join_read_first:join_read_last;
- tab->type=JT_NEXT; // Read with index_first(), index_next()
- if (select && select->quick)
- {
- delete select->quick;
- select->quick= 0;
- }
- if (table->covering_keys.is_set(best_key))
- table->set_keyread(TRUE);
- table->file->ha_index_or_rnd_end();
- if (join->select_options & SELECT_DESCRIBE)
- {
- tab->ref.key= -1;
- tab->ref.key_parts= 0;
- if (select_limit < table_records)
- tab->limit= select_limit;
- }
- }
- else if (tab->type != JT_ALL)
- {
- /*
- We're about to use a quick access to the table.
- We need to change the access method so as the quick access
- method is actually used.
- */
- DBUG_ASSERT(tab->select->quick);
- tab->type=JT_ALL;
- tab->use_quick=1;
- tab->ref.key= -1;
- tab->ref.key_parts=0; // Don't use ref key.
- tab->read_first_record= join_init_read_record;
- if (tab->is_using_loose_index_scan())
- join->tmp_table_param.precomputed_group_by= TRUE;
- /*
- TODO: update the number of records in join->best_positions[tablenr]
- */
- }
+ select->quick= 0;
+ select->test_quick_select(join->thd, map, 0,
+ join->select_options & OPTION_FOUND_ROWS ?
+ HA_POS_ERROR :
+ join->unit->select_limit_cnt,
+ 0);
}
order_direction= best_key_direction;
/*
@@ -13802,10 +13798,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
saved_best_key_parts : best_key_parts;
}
else
- DBUG_RETURN(0);
+ goto use_filesort;
}
check_reverse_order:
+ DBUG_ASSERT(order_direction != 0);
+
if (order_direction == -1) // If ORDER BY ... DESC
{
if (select && select->quick)
@@ -13814,9 +13812,10 @@ check_reverse_order:
Don't reverse the sort order, if it's already done.
(In some cases test_if_order_by_key() can be called multiple times
*/
- if (!select->quick->reverse_sorted())
+ if (select->quick->reverse_sorted())
+ goto skipped_filesort;
+ else
{
- QUICK_SELECT_I *tmp;
int quick_type= select->quick->get_type();
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
@@ -13824,37 +13823,128 @@ check_reverse_order:
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
{
tab->limit= 0;
- select->quick= save_quick;
- DBUG_RETURN(0); // Use filesort
+ goto use_filesort; // Use filesort
}
-
- /* ORDER BY range_key DESC */
- tmp= select->quick->make_reverse(used_key_parts);
- if (!tmp)
- {
- select->quick= save_quick;
- tab->limit= 0;
- DBUG_RETURN(0); // Reverse sort not supported
- }
- select->set_quick(tmp);
}
}
- else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
- tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
+ }
+
+ /*
+ Update query plan with access pattern for doing
+ ordered access according to what we have decided
+ above.
+ */
+ if (!no_changes) // We are allowed to update QEP
+ {
+ if (best_key >= 0)
{
- /*
- SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+ bool quick_created=
+ (select && select->quick && select->quick!=save_quick);
- Use a traversal function that starts by reading the last row
- with key part (A) and then traverse the index backwards.
+ /*
+ If ref_key used index tree reading only ('Using index' in EXPLAIN),
+ and best_key doesn't, then revert the decision.
*/
- tab->read_first_record= join_read_last_key;
- tab->read_record.read_record= join_read_prev_same;
+ if (!table->covering_keys.is_set(best_key))
+ table->set_keyread(FALSE);
+ if (!quick_created)
+ {
+ if (select) // Throw any existing quick select
+ select->quick= 0; // Cleanup either reset to save_quick,
+ // or 'delete save_quick'
+ tab->index= best_key;
+ tab->read_first_record= order_direction > 0 ?
+ join_read_first:join_read_last;
+ tab->type=JT_NEXT; // Read with index_first(), index_next()
+
+ if (table->covering_keys.is_set(best_key))
+ table->set_keyread(TRUE);
+ table->file->ha_index_or_rnd_end();
+ if (tab->join->select_options & SELECT_DESCRIBE)
+ {
+ tab->ref.key= -1;
+ tab->ref.key_parts= 0;
+ if (select_limit < table->file->stats.records)
+ tab->limit= select_limit;
+ }
+ }
+ else if (tab->type != JT_ALL)
+ {
+ /*
+ We're about to use a quick access to the table.
+ We need to change the access method so as the quick access
+ method is actually used.
+ */
+ DBUG_ASSERT(tab->select->quick);
+ tab->type=JT_ALL;
+ tab->use_quick=1;
+ tab->ref.key= -1;
+ tab->ref.key_parts=0; // Don't use ref key.
+ tab->read_first_record= join_init_read_record;
+ if (tab->is_using_loose_index_scan())
+ tab->join->tmp_table_param.precomputed_group_by= TRUE;
+ /*
+ TODO: update the number of records in join->best_positions[tablenr]
+ */
+ }
+ } // best_key >= 0
+
+ if (order_direction == -1) // If ORDER BY ... DESC
+ {
+ if (select && select->quick)
+ {
+ /* ORDER BY range_key DESC */
+ QUICK_SELECT_I *tmp= select->quick->make_reverse(used_key_parts);
+ if (!tmp)
+ {
+ tab->limit= 0;
+ goto use_filesort; // Reverse sort failed -> filesort
+ }
+ if (select->quick == save_quick)
+ save_quick= 0; // make_reverse() consumed it
+ select->set_quick(tmp);
+ }
+ else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
+ tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
+ {
+ /*
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+
+ Use a traversal function that starts by reading the last row
+ with key part (A) and then traverse the index backwards.
+ */
+ tab->read_first_record= join_read_last_key;
+ tab->read_record.read_record= join_read_prev_same;
+ }
}
+ else if (select && select->quick)
+ select->quick->sorted= 1;
+
+ } // QEP has been modified
+
+ /*
+ Cleanup:
+ We may have both a 'select->quick' and 'save_quick' (original)
+ at this point. Delete the one that we wan't use.
+ */
+
+skipped_filesort:
+ // Keep current (ordered) select->quick
+ if (select && save_quick != select->quick)
+ {
+ delete save_quick;
+ save_quick= NULL;
}
- else if (select && select->quick)
- select->quick->sorted= 1;
DBUG_RETURN(1);
+
+use_filesort:
+ // Restore original save_quick
+ if (select && select->quick != save_quick)
+ {
+ delete select->quick;
+ select->quick= save_quick;
+ }
+ DBUG_RETURN(0);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 9bf24bb88f9..abef175ab55 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -336,6 +336,7 @@ static struct show_privileges_st sys_privileges[]=
{"Insert", "Tables", "To insert data into tables"},
{"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
{"Process", "Server Admin", "To view the plain text of currently executing queries"},
+ {"Proxy", "Server Admin", "To make proxy user possible"},
{"References", "Databases,Tables", "To have references on tables"},
{"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
{"Replication client","Server Admin","To ask where the slave or master servers are"},
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 064c2b36e17..2855bb0ec4a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4745,7 +4745,7 @@ err:
@details Checks if any index is being modified (present as both DROP INDEX
and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling
- online ALTER TABLE.
+ in-place ALTER TABLE.
@param table The table being altered
@param alter_info The ALTER TABLE structure
@@ -4861,7 +4861,7 @@ mysql_compare_tables(TABLE *table,
like to keep mysql_compare_tables() idempotent (not altering any
of the arguments) we create a copy of alter_info here and
pass it to mysql_prepare_create_table, then use the result
- to evaluate possibility of fast ALTER TABLE, and then
+ to evaluate possibility of in-place ALTER TABLE, and then
destroy the copy.
*/
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
@@ -4902,9 +4902,9 @@ mysql_compare_tables(TABLE *table,
There was a bug prior to mysql-4.0.25. Number of null fields was
calculated incorrectly. As a result frm and data files gets out of
- sync after fast alter table. There is no way to determine by which
+ sync after in-place alter table. There is no way to determine by which
mysql version (in 4.0 and 4.1 branches) table was created, thus we
- disable fast alter table for all tables created by mysql versions
+ disable in-place alter table for all tables created by mysql versions
prior to 5.0 branch.
See BUG#6236.
*/
@@ -4927,7 +4927,7 @@ mysql_compare_tables(TABLE *table,
}
/*
- Use transformed info to evaluate possibility of fast ALTER TABLE
+ Use transformed info to evaluate possibility of in-place ALTER TABLE
but use the preserved field to persist modifications.
*/
new_field_it.init(alter_info->create_list);
@@ -5207,7 +5207,7 @@ blob_length_by_type(enum_field_types type)
semantic checks.
This function is invoked when we know that we're going to
- perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
+ perform ALTER TABLE via a temporary table -- i.e. in-place ALTER TABLE
is not possible, perhaps because the ALTER statement contains
instructions that require change in table data, not only in
table definition or indexes.
@@ -6102,7 +6102,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/*
- If there are index changes only, try to do them online. "Index
+ If there are index changes only, try to do them in-place. "Index
changes only" means also that the handler for the table does not
change. The table is open and locked. The handler can be accessed.
*/
@@ -6110,8 +6110,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
int pk_changed= 0;
ulong alter_flags= 0;
- ulong needed_online_flags= 0;
- ulong needed_fast_flags= 0;
+ ulong needed_inplace_with_read_flags= 0;
+ ulong needed_inplace_flags= 0;
KEY *key;
uint *idx_p;
uint *idx_end_p;
@@ -6135,8 +6135,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_PRINT("info", ("Dropping primary key"));
/* Primary key. */
- needed_online_flags|= HA_ONLINE_DROP_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_DROP_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE;
pk_changed++;
candidate_key_count--;
}
@@ -6146,8 +6146,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
bool is_candidate_key= true;
/* Non-primary unique key. */
- needed_online_flags|= HA_ONLINE_DROP_UNIQUE_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|=
+ HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE;
/*
Check if all fields in key are declared
@@ -6166,12 +6167,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
{
/* Non-unique key. */
- needed_online_flags|= HA_ONLINE_DROP_INDEX;
- needed_fast_flags|= HA_ONLINE_DROP_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_DROP_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_DROP_INDEX_NO_READ_WRITE;
}
}
no_pk= ((table->s->primary_key == MAX_KEY) ||
- (needed_online_flags & HA_ONLINE_DROP_PK_INDEX));
+ (needed_inplace_with_read_flags &
+ HA_INPLACE_DROP_PK_INDEX_NO_WRITE));
/* Check added indexes. */
for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
idx_p < idx_end_p;
@@ -6209,57 +6211,59 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_PRINT("info", ("Adding primary key"));
/* Primary key. */
- needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
pk_changed++;
no_pk= false;
}
else
{
/* Non-primary unique key. */
- needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE;
}
}
else
{
/* Non-unique key. */
- needed_online_flags|= HA_ONLINE_ADD_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_INDEX_NO_READ_WRITE;
}
}
- if ((candidate_key_count > 0) &&
- (needed_online_flags & HA_ONLINE_DROP_PK_INDEX))
+ if ((candidate_key_count > 0) &&
+ (needed_inplace_with_read_flags & HA_INPLACE_DROP_PK_INDEX_NO_WRITE))
{
/*
Dropped primary key when there is some other unique
not null key that should be converted to primary key
*/
- needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
- needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+ needed_inplace_with_read_flags|= HA_INPLACE_ADD_PK_INDEX_NO_WRITE;
+ needed_inplace_flags|= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE;
pk_changed= 2;
}
- DBUG_PRINT("info", ("needed_online_flags: 0x%lx, needed_fast_flags: 0x%lx",
- needed_online_flags, needed_fast_flags));
+ DBUG_PRINT("info",
+ ("needed_inplace_with_read_flags: 0x%lx, needed_inplace_flags: 0x%lx",
+ needed_inplace_with_read_flags, needed_inplace_flags));
/*
- Online or fast add/drop index is possible only if
+ In-place add/drop index is possible only if
the primary key is not added and dropped in the same statement.
Otherwise we have to recreate the table.
need_copy_table is no-zero at this place.
*/
if ( pk_changed < 2 )
{
- if ((alter_flags & needed_online_flags) == needed_online_flags)
+ if ((alter_flags & needed_inplace_with_read_flags) ==
+ needed_inplace_with_read_flags)
{
- /* All required online flags are present. */
+ /* All required in-place flags to allow concurrent reads are present. */
need_copy_table= ALTER_TABLE_METADATA_ONLY;
need_lock_for_indexes= FALSE;
}
- else if ((alter_flags & needed_fast_flags) == needed_fast_flags)
+ else if ((alter_flags & needed_inplace_flags) == needed_inplace_flags)
{
- /* All required fast flags are present. */
+ /* All required in-place flags are present. */
need_copy_table= ALTER_TABLE_METADATA_ONLY;
}
}
@@ -6413,10 +6417,18 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
else
{
- if (!table->s->tmp_table &&
+ /*
+ Ensure that we will upgrade the metadata lock if
+ handler::enable/disable_indexes() will be called.
+ */
+ if (alter_info->keys_onoff != LEAVE_AS_IS ||
+ table->file->indexes_are_disabled())
+ need_lock_for_indexes= true;
+ if (!table->s->tmp_table && need_lock_for_indexes &&
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto err_new_table_cleanup;
thd_proc_info(thd, "manage keys");
+ DEBUG_SYNC(thd, "alter_table_manage_keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
alter_info->keys_onoff);
error= trans_commit_stmt(thd);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 9b4543bf636..17b8056a165 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 68bb77d467f..ce1dcb4a33c 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2430,17 +2430,17 @@ static ulonglong read_timestamp(THD *thd)
static bool check_timestamp(sys_var *self, THD *thd, set_var *var)
{
- time_t val;
+ longlong val;
if (!var->value)
return FALSE;
- val= (time_t) var->save_result.ulonglong_value;
- if (val < (time_t) MY_TIME_T_MIN || val > (time_t) MY_TIME_T_MAX)
+ val= (longlong) var->save_result.ulonglong_value;
+ if (val != 0 && // this is how you set the default value
+ (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE))
{
- my_message(ER_UNKNOWN_ERROR,
- "This version of MySQL doesn't support dates later than 2038",
- MYF(0));
+ char buf[64];
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", llstr(val, buf));
return TRUE;
}
return FALSE;
diff --git a/sql/table.cc b/sql/table.cc
index 238e73f7193..24a37d934d2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/unireg.h b/sql/unireg.h
index b897c887c89..1bf956efb4f 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,7 +1,7 @@
#ifndef UNIREG_INCLUDED
#define UNIREG_INCLUDED
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -56,8 +56,6 @@ typedef struct st_ha_create_information HA_CREATE_INFO;
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
-#define ERRMAPP 1 /* Errormap f|r my_error */
-
#define ME_INFO (ME_HOLDTANG+ME_OLDWIN+ME_NOREFRESH)
#define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH)
#define MYF_RW MYF(MY_WME+MY_NABP) /* Vid my_read & my_write */
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index ff82372b52b..2e544c0552a 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -981,7 +981,7 @@ btr_page_reorganize_low(
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
#ifndef UNIV_HOTBACKUP
- temp_block = buf_block_alloc(buf_pool, 0);
+ temp_block = buf_block_alloc(buf_pool);
#else /* !UNIV_HOTBACKUP */
ut_ad(block == back_block1);
temp_block = back_block2;
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index a5ed1964b2e..8ba9fd721f5 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -111,6 +111,18 @@ can be released by page reorganize, then it is reorganized */
/*--------------------------------------*/
#define BTR_BLOB_HDR_SIZE 8 /*!< Size of a BLOB
part header, in bytes */
+
+/** Estimated table level stats from sampled value.
+@param value sampled stats
+@param index index being sampled
+@param sample number of sampled rows
+@param ext_size external stored data size
+@param not_empty table not empty
+@return estimated table wide stats from sampled value */
+#define BTR_TABLE_STATS_FROM_SAMPLE(value, index, sample, ext_size, not_empty)\
+ (((value) * (ib_int64_t) index->stat_n_leaf_pages \
+ + (sample) - 1 + (ext_size) + (not_empty)) / ((sample) + (ext_size)))
+
/* @} */
#endif /* !UNIV_HOTBACKUP */
@@ -185,7 +197,7 @@ static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- rec_t* rec, /*!< in: record */
+ const rec_t* rec, /*!< in: record */
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
#endif /* !UNIV_HOTBACKUP */
@@ -1874,8 +1886,8 @@ btr_cur_update_in_place(
NOT call it if index is secondary */
if (!dict_index_is_clust(index)
- || row_upd_changes_ord_field_binary(NULL, NULL,
- index, update)) {
+ || row_upd_changes_ord_field_binary(index, update, thr,
+ NULL, NULL)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
@@ -3479,9 +3491,54 @@ btr_estimate_n_rows_in_range(
}
/*******************************************************************//**
+Record the number of non_null key values in a given index for
+each n-column prefix of the index where n < dict_index_get_n_unique(index).
+The estimates are eventually stored in the array:
+index->stat_n_non_null_key_vals. */
+static
+void
+btr_record_not_null_field_in_rec(
+/*=============================*/
+ rec_t* rec, /*!< in: physical record */
+ ulint n_unique, /*!< in: dict_index_get_n_unique(index),
+ number of columns uniquely determine
+ an index entry */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
+ its size could be for all fields or
+ that of "n_unique" */
+ ib_int64_t* n_not_null) /*!< in/out: array to record number of
+ not null rows for n-column prefix */
+{
+ ulint i;
+
+ ut_ad(rec_offs_n_fields(offsets) >= n_unique);
+
+ if (n_not_null == NULL) {
+ return;
+ }
+
+ for (i = 0; i < n_unique; i++) {
+ ulint rec_len;
+ byte* field;
+
+ field = rec_get_nth_field(rec, offsets, i, &rec_len);
+
+ if (rec_len != UNIV_SQL_NULL) {
+ n_not_null[i]++;
+ } else {
+ /* Break if we hit the first NULL value */
+ break;
+ }
+ }
+}
+
+/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
-The estimates are stored in the array index->stat_n_diff_key_vals. */
+The estimates are stored in the array index->stat_n_diff_key_vals.
+If innodb_stats_method is "nulls_ignored", we also record the number of
+non-null values for each prefix and store the estimates in
+array index->stat_n_non_null_key_vals. */
UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
@@ -3495,6 +3552,8 @@ btr_estimate_number_of_different_key_vals(
ulint matched_fields;
ulint matched_bytes;
ib_int64_t* n_diff;
+ ib_int64_t* n_not_null;
+ ibool stats_null_not_equal;
ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0;
ulint total_external_size = 0;
@@ -3503,16 +3562,43 @@ btr_estimate_number_of_different_key_vals(
ullint add_on;
mtr_t mtr;
mem_heap_t* heap = NULL;
- ulint offsets_rec_[REC_OFFS_NORMAL_SIZE];
- ulint offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets_rec = offsets_rec_;
- ulint* offsets_next_rec= offsets_next_rec_;
- rec_offs_init(offsets_rec_);
- rec_offs_init(offsets_next_rec_);
+ ulint* offsets_rec = NULL;
+ ulint* offsets_next_rec = NULL;
n_cols = dict_index_get_n_unique(index);
- n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
+ heap = mem_heap_create((sizeof *n_diff + sizeof *n_not_null)
+ * (n_cols + 1)
+ + dict_index_get_n_fields(index)
+ * (sizeof *offsets_rec
+ + sizeof *offsets_next_rec));
+
+ n_diff = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
+
+ n_not_null = NULL;
+
+ /* Check srv_innodb_stats_method setting, and decide whether we
+ need to record non-null value and also decide if NULL is
+ considered equal (by setting stats_null_not_equal value) */
+ switch (srv_innodb_stats_method) {
+ case SRV_STATS_NULLS_IGNORED:
+ n_not_null = mem_heap_zalloc(heap, (n_cols + 1)
+ * sizeof *n_not_null);
+ /* fall through */
+
+ case SRV_STATS_NULLS_UNEQUAL:
+ /* for both SRV_STATS_NULLS_IGNORED and SRV_STATS_NULLS_UNEQUAL
+ case, we will treat NULLs as unequal value */
+ stats_null_not_equal = TRUE;
+ break;
+
+ case SRV_STATS_NULLS_EQUAL:
+ stats_null_not_equal = FALSE;
+ break;
+
+ default:
+ ut_error;
+ }
/* It makes no sense to test more pages than are contained
in the index, thus we lower the number if it is too high */
@@ -3529,7 +3615,6 @@ btr_estimate_number_of_different_key_vals(
/* We sample some pages in the index to get an estimate */
for (i = 0; i < n_sample_pages; i++) {
- rec_t* supremum;
mtr_start(&mtr);
btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
@@ -3542,18 +3627,25 @@ btr_estimate_number_of_different_key_vals(
page = btr_cur_get_page(&cursor);
- supremum = page_get_supremum_rec(page);
rec = page_rec_get_next(page_get_infimum_rec(page));
- if (rec != supremum) {
+ if (!page_rec_is_supremum(rec)) {
not_empty_flag = 1;
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
ULINT_UNDEFINED, &heap);
+
+ if (n_not_null) {
+ btr_record_not_null_field_in_rec(
+ rec, n_cols, offsets_rec, n_not_null);
+ }
}
- while (rec != supremum) {
+ while (!page_rec_is_supremum(rec)) {
rec_t* next_rec = page_rec_get_next(rec);
- if (next_rec == supremum) {
+ if (page_rec_is_supremum(next_rec)) {
+ total_external_size +=
+ btr_rec_get_externally_stored_len(
+ rec, offsets_rec);
break;
}
@@ -3561,11 +3653,13 @@ btr_estimate_number_of_different_key_vals(
matched_bytes = 0;
offsets_next_rec = rec_get_offsets(next_rec, index,
offsets_next_rec,
- n_cols, &heap);
+ ULINT_UNDEFINED,
+ &heap);
cmp_rec_rec_with_match(rec, next_rec,
offsets_rec, offsets_next_rec,
- index, &matched_fields,
+ index, stats_null_not_equal,
+ &matched_fields,
&matched_bytes);
for (j = matched_fields + 1; j <= n_cols; j++) {
@@ -3575,6 +3669,12 @@ btr_estimate_number_of_different_key_vals(
n_diff[j]++;
}
+ if (n_not_null) {
+ btr_record_not_null_field_in_rec(
+ next_rec, n_cols, offsets_next_rec,
+ n_not_null);
+ }
+
total_external_size
+= btr_rec_get_externally_stored_len(
rec, offsets_rec);
@@ -3609,10 +3709,6 @@ btr_estimate_number_of_different_key_vals(
}
}
- offsets_rec = rec_get_offsets(rec, index, offsets_rec,
- ULINT_UNDEFINED, &heap);
- total_external_size += btr_rec_get_externally_stored_len(
- rec, offsets_rec);
mtr_commit(&mtr);
}
@@ -3626,13 +3722,9 @@ btr_estimate_number_of_different_key_vals(
for (j = 0; j <= n_cols; j++) {
index->stat_n_diff_key_vals[j]
- = ((n_diff[j]
- * (ib_int64_t)index->stat_n_leaf_pages
- + n_sample_pages - 1
- + total_external_size
- + not_empty_flag)
- / (n_sample_pages
- + total_external_size));
+ = BTR_TABLE_STATS_FROM_SAMPLE(
+ n_diff[j], index, n_sample_pages,
+ total_external_size, not_empty_flag);
/* If the tree is small, smaller than
10 * n_sample_pages + total_external_size, then
@@ -3651,45 +3743,81 @@ btr_estimate_number_of_different_key_vals(
}
index->stat_n_diff_key_vals[j] += add_on;
- }
- mem_free(n_diff);
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
+ /* Update the stat_n_non_null_key_vals[] with our
+ sampled result. stat_n_non_null_key_vals[] is created
+ and initialized to zero in dict_index_add_to_cache(),
+ along with stat_n_diff_key_vals[] array */
+ if (n_not_null != NULL && (j < n_cols)) {
+ index->stat_n_non_null_key_vals[j] =
+ BTR_TABLE_STATS_FROM_SAMPLE(
+ n_not_null[j], index, n_sample_pages,
+ total_external_size, not_empty_flag);
+ }
}
+
+ mem_heap_free(heap);
}
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
/***********************************************************//**
+Gets the offset of the pointer to the externally stored part of a field.
+@return offset of the pointer to the externally stored part */
+static
+ulint
+btr_rec_get_field_ref_offs(
+/*=======================*/
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: index of the external field */
+{
+ ulint field_ref_offs;
+ ulint local_len;
+
+ ut_a(rec_offs_nth_extern(offsets, n));
+ field_ref_offs = rec_get_nth_field_offs(offsets, n, &local_len);
+ ut_a(local_len != UNIV_SQL_NULL);
+ ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
+
+ return(field_ref_offs + local_len - BTR_EXTERN_FIELD_REF_SIZE);
+}
+
+/** Gets a pointer to the externally stored part of a field.
+@param rec record
+@param offsets rec_get_offsets(rec)
+@param n index of the externally stored field
+@return pointer to the externally stored part */
+#define btr_rec_get_field_ref(rec, offsets, n) \
+ ((rec) + btr_rec_get_field_ref_offs(offsets, n))
+
+/***********************************************************//**
Gets the externally stored size of a record, in units of a database page.
@return externally stored part, in units of a database page */
static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- rec_t* rec, /*!< in: record */
+ const rec_t* rec, /*!< in: record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
- byte* data;
- ulint local_len;
- ulint extern_len;
ulint total_extern_len = 0;
ulint i;
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
+
+ if (!rec_offs_any_extern(offsets)) {
+ return(0);
+ }
+
n_fields = rec_offs_n_fields(offsets);
for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) {
- data = rec_get_nth_field(rec, offsets, i, &local_len);
-
- local_len -= BTR_EXTERN_FIELD_REF_SIZE;
-
- extern_len = mach_read_from_4(data + local_len
- + BTR_EXTERN_LEN + 4);
+ ulint extern_len = mach_read_from_4(
+ btr_rec_get_field_ref(rec, offsets, i)
+ + BTR_EXTERN_LEN + 4);
total_extern_len += ut_calc_align(extern_len,
UNIV_PAGE_SIZE);
@@ -3719,7 +3847,7 @@ btr_cur_set_ownership_of_extern_field(
ulint byte_val;
data = rec_get_nth_field(rec, offsets, i, &local_len);
-
+ ut_ad(rec_offs_nth_extern(offsets, i));
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
@@ -3729,6 +3857,9 @@ btr_cur_set_ownership_of_extern_field(
if (val) {
byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG);
} else {
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ ut_a(!(byte_val & BTR_EXTERN_OWNER_FLAG));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
byte_val = byte_val | BTR_EXTERN_OWNER_FLAG;
}
@@ -3946,13 +4077,12 @@ btr_blob_free(
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
- if (buf_LRU_free_block(&block->page, all, NULL)
- != BUF_LRU_FREED
+ if (buf_LRU_free_block(&block->page, all) != BUF_LRU_FREED
&& all && block->page.zip.data) {
/* Attempt to deallocate the uncompressed page
if the whole block cannot be deallocted. */
- buf_LRU_free_block(&block->page, FALSE, NULL);
+ buf_LRU_free_block(&block->page, FALSE);
}
}
@@ -3968,8 +4098,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
-btr_store_big_rec_extern_fields(
-/*============================*/
+btr_store_big_rec_extern_fields_func(
+/*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */
@@ -3978,11 +4108,17 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /*!< in: vector containing fields
+#ifdef UNIV_DEBUG
+ mtr_t* local_mtr, /*!< in: mtr containing the
+ latch to rec and to the tree */
+#endif /* UNIV_DEBUG */
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ ibool update_in_place,/*! in: TRUE if the record is updated
+ in place (not delete+insert) */
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+ const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
- containing the latch to rec and to the
- tree */
+
{
ulint rec_page_no;
byte* field_ref;
@@ -4000,6 +4136,7 @@ btr_store_big_rec_extern_fields(
z_stream c_stream;
ut_ad(rec_offs_validate(rec, index, offsets));
+ ut_ad(rec_offs_any_extern(offsets));
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
@@ -4031,21 +4168,37 @@ btr_store_big_rec_extern_fields(
ut_a(err == Z_OK);
}
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ /* All pointers to externally stored columns in the record
+ must either be zero or they must be pointers to inherited
+ columns, owned by this record or an earlier record version. */
+ for (i = 0; i < rec_offs_n_fields(offsets); i++) {
+ if (!rec_offs_nth_extern(offsets, i)) {
+ continue;
+ }
+ field_ref = btr_rec_get_field_ref(rec, offsets, i);
+
+ ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
+ /* Either this must be an update in place,
+ or the BLOB must be inherited, or the BLOB pointer
+ must be zero (will be written in this function). */
+ ut_a(update_in_place
+ || (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_INHERITED_FLAG)
+ || !memcmp(field_ref, field_ref_zero,
+ BTR_EXTERN_FIELD_REF_SIZE));
+ }
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
/* We have to create a file segment to the tablespace
for each field and put the pointer to the field in rec */
for (i = 0; i < big_rec_vec->n_fields; i++) {
- ut_ad(rec_offs_nth_extern(offsets,
- big_rec_vec->fields[i].field_no));
- {
- ulint local_len;
- field_ref = rec_get_nth_field(
- rec, offsets, big_rec_vec->fields[i].field_no,
- &local_len);
- ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
- local_len -= BTR_EXTERN_FIELD_REF_SIZE;
- field_ref += local_len;
- }
+ field_ref = btr_rec_get_field_ref(
+ rec, offsets, big_rec_vec->fields[i].field_no);
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ /* A zero BLOB pointer should have been initially inserted. */
+ ut_a(!memcmp(field_ref, field_ref_zero,
+ BTR_EXTERN_FIELD_REF_SIZE));
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
extern_len = big_rec_vec->fields[i].len;
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
extern_len);
@@ -4327,6 +4480,23 @@ next_zip_page:
mem_heap_free(heap);
}
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ /* All pointers to externally stored columns in the record
+ must be valid. */
+ for (i = 0; i < rec_offs_n_fields(offsets); i++) {
+ if (!rec_offs_nth_extern(offsets, i)) {
+ continue;
+ }
+
+ field_ref = btr_rec_get_field_ref(rec, offsets, i);
+
+ /* The pointer must not be zero. */
+ ut_a(0 != memcmp(field_ref, field_ref_zero,
+ BTR_EXTERN_FIELD_REF_SIZE));
+ /* The column must not be disowned by this record. */
+ ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
+ }
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
return(DB_SUCCESS);
}
@@ -4349,6 +4519,7 @@ btr_check_blob_fil_page_type(
if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) {
ulint flags = fil_space_get_flags(space_id);
+#ifndef UNIV_DEBUG /* Improve debug test coverage */
if (UNIV_LIKELY
((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) {
/* Old versions of InnoDB did not initialize
@@ -4357,6 +4528,7 @@ btr_check_blob_fil_page_type(
a BLOB page that is in Antelope format.*/
return;
}
+#endif /* !UNIV_DEBUG */
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -4406,23 +4578,13 @@ btr_free_externally_stored_field(
ulint page_no;
ulint next_page_no;
mtr_t mtr;
-#ifdef UNIV_DEBUG
+
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
MTR_MEMO_PAGE_X_FIX));
ut_ad(!rec || rec_offs_validate(rec, index, offsets));
-
- if (rec) {
- ulint local_len;
- const byte* f = rec_get_nth_field(rec, offsets,
- i, &local_len);
- ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
- local_len -= BTR_EXTERN_FIELD_REF_SIZE;
- f += local_len;
- ut_ad(f == field_ref);
- }
-#endif /* UNIV_DEBUG */
+ ut_ad(!rec || field_ref == btr_rec_get_field_ref(rec, offsets, i));
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE))) {
@@ -4585,13 +4747,8 @@ btr_rec_free_externally_stored_fields(
for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) {
- ulint len;
- byte* data
- = rec_get_nth_field(rec, offsets, i, &len);
- ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
-
btr_free_externally_stored_field(
- index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
+ index, btr_rec_get_field_ref(rec, offsets, i),
rec, offsets, page_zip, i, rb_ctx, mtr);
}
}
diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
index 8f5f9b839b5..d192ee7c132 100644
--- a/storage/innobase/btr/btr0sea.c
+++ b/storage/innobase/btr/btr0sea.c
@@ -151,7 +151,7 @@ btr_search_check_free_space_in_heap(void)
be enough free space in the hash table. */
if (heap->free_block == NULL) {
- buf_block_t* block = buf_block_alloc(NULL, 0);
+ buf_block_t* block = buf_block_alloc(NULL);
rw_lock_x_lock(&btr_search_latch);
diff --git a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c
index 787b4e652a0..75ba832c7e5 100644
--- a/storage/innobase/buf/buf0buddy.c
+++ b/storage/innobase/buf/buf0buddy.c
@@ -327,7 +327,7 @@ buf_buddy_alloc_low(
/* Try replacing an uncompressed page in the buffer pool. */
buf_pool_mutex_exit(buf_pool);
- block = buf_LRU_get_free_block(buf_pool, 0);
+ block = buf_LRU_get_free_block(buf_pool);
*lru = TRUE;
buf_pool_mutex_enter(buf_pool);
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index af4b747eb30..1ddf15ef8b9 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -416,9 +416,9 @@ UNIV_INTERN
buf_block_t*
buf_block_alloc(
/*============*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ulint zip_size) /*!< in: compressed page size in bytes,
- or 0 if uncompressed tablespace */
+ buf_pool_t* buf_pool) /*!< in/out: buffer pool instance,
+ or NULL for round-robin selection
+ of the buffer pool */
{
buf_block_t* block;
ulint index;
@@ -431,7 +431,7 @@ buf_block_alloc(
buf_pool = buf_pool_from_array(index);
}
- block = buf_LRU_get_free_block(buf_pool, zip_size);
+ block = buf_LRU_get_free_block(buf_pool);
buf_block_set_state(block, BUF_BLOCK_MEMORY);
@@ -865,9 +865,9 @@ buf_block_init(
block->modify_clock = 0;
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE;
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
block->check_index_page_at_flush = FALSE;
block->index = NULL;
@@ -1623,7 +1623,7 @@ shrink_again:
buf_LRU_make_block_old(&block->page);
dirty++;
- } else if (buf_LRU_free_block(&block->page, TRUE, NULL)
+ } else if (buf_LRU_free_block(&block->page, TRUE)
!= BUF_LRU_FREED) {
nonfree++;
}
@@ -2229,7 +2229,7 @@ buf_page_peek_if_search_hashed(
return(is_hashed);
}
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
@@ -2252,6 +2252,8 @@ buf_page_set_file_page_was_freed(
if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
+ /* bpage->file_page_was_freed can already hold
+ when this code is invoked from dict_drop_index_tree() */
bpage->file_page_was_freed = TRUE;
}
@@ -2289,7 +2291,7 @@ buf_page_reset_file_page_was_freed(
return(bpage);
}
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//**
Get read access to a compressed page (usually of type
@@ -2363,8 +2365,7 @@ err_exit:
mutex_enter(block_mutex);
/* Discard the uncompressed page frame if possible. */
- if (buf_LRU_free_block(bpage, FALSE, NULL)
- == BUF_LRU_FREED) {
+ if (buf_LRU_free_block(bpage, FALSE) == BUF_LRU_FREED) {
mutex_exit(block_mutex);
goto lookup;
@@ -2388,7 +2389,7 @@ got_block:
buf_page_set_accessed_make_young(bpage, access_time);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed);
#endif
@@ -2880,7 +2881,7 @@ wait_until_unfixed:
buf_pool_mutex_exit(buf_pool);
mutex_exit(&buf_pool->zip_mutex);
- block = buf_LRU_get_free_block(buf_pool, 0);
+ block = buf_LRU_get_free_block(buf_pool);
ut_a(block);
buf_pool_mutex_enter(buf_pool);
@@ -3010,8 +3011,7 @@ wait_until_unfixed:
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
- if (buf_LRU_free_block(&block->page, TRUE, NULL)
- == BUF_LRU_FREED) {
+ if (buf_LRU_free_block(&block->page, TRUE) == BUF_LRU_FREED) {
mutex_exit(&block->mutex);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
/* Set the watch, as it would have
@@ -3057,7 +3057,7 @@ wait_until_unfixed:
buf_page_set_accessed_make_young(&block->page, access_time);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!block->page.file_page_was_freed);
#endif
@@ -3216,7 +3216,7 @@ buf_page_optimistic_get(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
if (UNIV_UNLIKELY(!access_time)) {
@@ -3329,7 +3329,7 @@ buf_page_get_known_nowait(
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
@@ -3415,9 +3415,9 @@ buf_page_try_get_func(
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
buf_pool->stat.n_page_gets++;
@@ -3446,9 +3446,9 @@ buf_page_init_low(
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
bpage->file_page_was_freed = FALSE;
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/********************************************************************//**
@@ -3586,7 +3586,7 @@ buf_page_init_for_read(
&& UNIV_LIKELY(!recv_recovery_is_on())) {
block = NULL;
} else {
- block = buf_LRU_get_free_block(buf_pool, 0);
+ block = buf_LRU_get_free_block(buf_pool);
ut_ad(block);
ut_ad(buf_pool_from_block(block) == buf_pool);
}
@@ -3792,7 +3792,7 @@ buf_page_create(
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(space || !zip_size);
- free_block = buf_LRU_get_free_block(buf_pool, 0);
+ free_block = buf_LRU_get_free_block(buf_pool);
fold = buf_page_address_fold(space, offset);
@@ -3807,9 +3807,9 @@ buf_page_create(
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(space, offset) == 0);
#endif
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE;
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */
buf_pool_mutex_exit(buf_pool);
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index d819782ac9d..910e8386a71 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -603,7 +603,7 @@ buf_LRU_free_from_unzip_LRU_list(
ut_ad(block->page.in_LRU_list);
mutex_enter(&block->mutex);
- freed = buf_LRU_free_block(&block->page, FALSE, NULL);
+ freed = buf_LRU_free_block(&block->page, FALSE);
mutex_exit(&block->mutex);
switch (freed) {
@@ -666,7 +666,7 @@ buf_LRU_free_from_common_LRU_list(
mutex_enter(block_mutex);
accessed = buf_page_is_accessed(bpage);
- freed = buf_LRU_free_block(bpage, TRUE, NULL);
+ freed = buf_LRU_free_block(bpage, TRUE);
mutex_exit(block_mutex);
switch (freed) {
@@ -858,9 +858,7 @@ UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ulint zip_size) /*!< in: compressed page size in bytes,
- or 0 if uncompressed tablespace */
+ buf_pool_t* buf_pool) /*!< in/out: buffer pool instance */
{
buf_block_t* block = NULL;
ibool freed;
@@ -936,31 +934,11 @@ loop:
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
- if (block) {
+ buf_pool_mutex_exit(buf_pool);
+ if (block) {
ut_ad(buf_pool_from_block(block) == buf_pool);
-
-#ifdef UNIV_DEBUG
- block->page.zip.m_start =
-#endif /* UNIV_DEBUG */
- block->page.zip.m_end =
- block->page.zip.m_nonempty =
- block->page.zip.n_blobs = 0;
-
- if (UNIV_UNLIKELY(zip_size)) {
- ibool lru;
- page_zip_set_size(&block->page.zip, zip_size);
-
- block->page.zip.data = buf_buddy_alloc(
- buf_pool, zip_size, &lru);
-
- UNIV_MEM_DESC(block->page.zip.data, zip_size, block);
- } else {
- page_zip_set_size(&block->page.zip, 0);
- block->page.zip.data = NULL;
- }
-
- buf_pool_mutex_exit(buf_pool);
+ memset(&block->page.zip, 0, sizeof block->page.zip);
if (started_monitor) {
srv_print_innodb_monitor = mon_value_was;
@@ -972,8 +950,6 @@ loop:
/* If no block was in the free list, search from the end of the LRU
list and try to free a block there */
- buf_pool_mutex_exit(buf_pool);
-
freed = buf_LRU_search_and_free_block(buf_pool, n_iterations);
if (freed > 0) {
@@ -1456,12 +1432,8 @@ enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
- ibool zip, /*!< in: TRUE if should remove also the
+ ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
- ibool* buf_pool_mutex_released)
- /*!< in: pointer to a variable that will
- be assigned TRUE if buf_pool_mutex
- was temporarily released, or NULL */
{
buf_page_t* b = NULL;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
@@ -1638,10 +1610,6 @@ alloc:
b->io_fix = BUF_IO_READ;
}
- if (buf_pool_mutex_released) {
- *buf_pool_mutex_released = TRUE;
- }
-
buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index ee862d8c709..ebc7747640e 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -949,7 +949,7 @@ dict_table_rename_in_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint fold;
- char old_name[MAX_TABLE_NAME_LEN + 1];
+ char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -961,7 +961,7 @@ dict_table_rename_in_cache(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", table->name,
- MAX_TABLE_NAME_LEN);
+ MAX_FULL_NAME_LEN);
ut_error;
}
@@ -1011,11 +1011,11 @@ dict_table_rename_in_cache(
ut_fold_string(old_name), table);
if (strlen(new_name) > strlen(table->name)) {
- /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid
+ /* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid
memory fragmentation, we assume a repeated calls of
ut_realloc() with the same size do not cause fragmentation */
- ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN);
- table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1);
+ ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN);
+ table->name = ut_realloc(table->name, MAX_FULL_NAME_LEN + 1);
}
memcpy(table->name, new_name, strlen(new_name) + 1);
@@ -1689,6 +1689,12 @@ undo_size_ok:
new_index->heap,
(1 + dict_index_get_n_unique(new_index))
* sizeof(ib_int64_t));
+
+ new_index->stat_n_non_null_key_vals = mem_heap_zalloc(
+ new_index->heap,
+ (1 + dict_index_get_n_unique(new_index))
+ * sizeof(*new_index->stat_n_non_null_key_vals));
+
/* Give some sensible values to stat_n_... in case we do
not calculate statistics quickly enough */
@@ -4319,6 +4325,10 @@ dict_update_statistics(
for (i = dict_index_get_n_unique(index); i; ) {
index->stat_n_diff_key_vals[i--] = 1;
}
+
+ memset(index->stat_n_non_null_key_vals, 0,
+ (1 + dict_index_get_n_unique(index))
+ * sizeof(*index->stat_n_non_null_key_vals));
}
index = dict_table_get_next_index(index);
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index 3252e85b358..3561e7220ab 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -1552,7 +1552,7 @@ err_len:
"InnoDB: in InnoDB data dictionary"
" has unknown type %lx.\n",
(ulong) flags);
- return(NULL);
+ return("incorrect flags in SYS_TABLES");
}
} else {
flags = 0;
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
index 5bf5411bc6a..3f09732a676 100644
--- a/storage/innobase/fsp/fsp0fsp.c
+++ b/storage/innobase/fsp/fsp0fsp.c
@@ -3435,9 +3435,9 @@ fseg_free_page(
fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(space, page);
-#endif
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/**********************************************************************//**
@@ -3503,13 +3503,13 @@ fseg_free_extent(
fsp_free_extent(space, zip_size, page, mtr);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
for (i = 0; i < FSP_EXTENT_SIZE; i++) {
buf_page_set_file_page_was_freed(space,
first_page_in_extent + i);
}
-#endif
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
}
/**********************************************************************//**
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ae782426e61..31c7ac38c24 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -172,6 +172,25 @@ static char* internal_innobase_data_file_path = NULL;
static char* innodb_version_str = (char*) INNODB_VERSION_STR;
+/** Possible values for system variable "innodb_stats_method". The values
+are defined the same as its corresponding MyISAM system variable
+"myisam_stats_method"(see "myisam_stats_method_names"), for better usability */
+static const char* innodb_stats_method_names[] = {
+ "nulls_equal",
+ "nulls_unequal",
+ "nulls_ignored",
+ NullS
+};
+
+/** Used to define an enumerate type of the system variable innodb_stats_method.
+This is the same as "myisam_stats_method_typelib" */
+static TYPELIB innodb_stats_method_typelib = {
+ array_elements(innodb_stats_method_names) - 1,
+ "innodb_stats_method_typelib",
+ innodb_stats_method_names,
+ NULL
+};
+
/* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call
srv_active_wake_master_thread after each fetch or search, we only do
@@ -2574,11 +2593,12 @@ innobase_alter_table_flags(
/*=======================*/
uint flags)
{
- return(HA_ONLINE_ADD_INDEX_NO_WRITES
- | HA_ONLINE_DROP_INDEX_NO_WRITES
- | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES
- | HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES
- | HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
+ return(HA_INPLACE_ADD_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_INDEX_NO_WRITE
+ | HA_INPLACE_DROP_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE
+ | HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE
+ | HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
}
/*****************************************************************//**
@@ -6215,6 +6235,17 @@ create_table_def(
DBUG_RETURN(HA_ERR_GENERIC);
}
+ /* MySQL does the name length check. But we do additional check
+ on the name length here */
+ if (strlen(table_name) > MAX_FULL_NAME_LEN) {
+ push_warning_printf(
+ (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TABLE_NAME,
+ "InnoDB: Table Name or Database Name is too long");
+
+ DBUG_RETURN(ER_TABLE_NAME);
+ }
+
n_cols = form->s->fields;
/* We pass 0 as the space id, and determine at a lower level the space
@@ -7709,6 +7740,65 @@ innobase_get_mysql_key_number_for_index(
return(0);
}
+
+/*********************************************************************//**
+Calculate Record Per Key value. Need to exclude the NULL value if
+innodb_stats_method is set to "nulls_ignored"
+@return estimated record per key value */
+static
+ha_rows
+innodb_rec_per_key(
+/*===============*/
+ dict_index_t* index, /*!< in: dict_index_t structure */
+ ulint i, /*!< in: the column we are
+ calculating rec per key */
+ ha_rows records) /*!< in: estimated total records */
+{
+ ha_rows rec_per_key;
+
+ ut_ad(i < dict_index_get_n_unique(index));
+
+ /* Note the stat_n_diff_key_vals[] stores the diff value with
+ n-prefix indexing, so it is always stat_n_diff_key_vals[i + 1] */
+ if (index->stat_n_diff_key_vals[i + 1] == 0) {
+
+ rec_per_key = records;
+ } else if (srv_innodb_stats_method == SRV_STATS_NULLS_IGNORED) {
+ ib_int64_t num_null;
+
+ /* Number of rows with NULL value in this
+ field */
+ num_null = records - index->stat_n_non_null_key_vals[i];
+
+ /* In theory, index->stat_n_non_null_key_vals[i]
+ should always be less than the number of records.
+ Since this is statistics value, the value could
+ have slight discrepancy. But we will make sure
+ the number of null values is not a negative number. */
+ num_null = (num_null < 0) ? 0 : num_null;
+
+ /* If the number of NULL values is the same as or
+ large than that of the distinct values, we could
+ consider that the table consists mostly of NULL value.
+ Set rec_per_key to 1. */
+ if (index->stat_n_diff_key_vals[i + 1] <= num_null) {
+ rec_per_key = 1;
+ } else {
+ /* Need to exclude rows with NULL values from
+ rec_per_key calculation */
+ rec_per_key = (ha_rows)(
+ (records - num_null)
+ / (index->stat_n_diff_key_vals[i + 1]
+ - num_null));
+ }
+ } else {
+ rec_per_key = (ha_rows)
+ (records / index->stat_n_diff_key_vals[i + 1]);
+ }
+
+ return(rec_per_key);
+}
+
/*********************************************************************//**
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */
@@ -7942,13 +8032,8 @@ ha_innobase::info_low(
break;
}
- if (index->stat_n_diff_key_vals[j + 1] == 0) {
-
- rec_per_key = stats.records;
- } else {
- rec_per_key = (ha_rows)(stats.records /
- index->stat_n_diff_key_vals[j + 1]);
- }
+ rec_per_key = innodb_rec_per_key(
+ index, j, stats.records);
/* Since MySQL seems to favor table scans
too much over index searches, we pretend
@@ -11171,6 +11256,13 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
innodb_change_buffering_validate,
innodb_change_buffering_update, "all");
+static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method,
+ PLUGIN_VAR_RQCMDARG,
+ "Specifies how InnoDB index statistics collection code should "
+ "treat NULLs. Possible values are NULLS_EQUAL (default), "
+ "NULLS_UNEQUAL and NULLS_IGNORED",
+ NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib);
+
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
PLUGIN_VAR_RQCMDARG,
@@ -11227,6 +11319,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
+ MYSQL_SYSVAR(stats_method),
MYSQL_SYSVAR(replication_delay),
MYSQL_SYSVAR(status_file),
MYSQL_SYSVAR(strict_mode),
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 709274bab16..00aced180ce 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -767,16 +767,7 @@ fill_innodb_locks_from_cache(
for (i = 0; i < rows_num; i++) {
i_s_locks_row_t* row;
-
- /* note that the decoded database or table name is
- never expected to be longer than NAME_LEN;
- NAME_LEN for database name
- 2 for surrounding quotes around database name
- NAME_LEN for table name
- 2 for surrounding quotes around table name
- 1 for the separating dot (.)
- 9 for the #mysql50# prefix */
- char buf[2 * NAME_LEN + 14];
+ char buf[MAX_FULL_NAME_LEN + 1];
const char* bufend;
char lock_trx_id[TRX_ID_MAX_LEN + 1];
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 41eba7cb9f3..6b81e11b52e 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -2256,9 +2256,9 @@ ibuf_remove_free_page(void)
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_SPACE_ID, page_no, &mtr);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
-#endif
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
ibuf_enter(&mtr);
@@ -2302,9 +2302,9 @@ ibuf_remove_free_page(void)
ibuf_bitmap_page_set_bits(
bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
-#endif
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
mtr_commit(&mtr);
}
@@ -2560,23 +2560,6 @@ ibuf_contract_ext(
if (UNIV_UNLIKELY(ibuf->empty)
&& UNIV_LIKELY(!srv_shutdown_state)) {
-ibuf_is_empty:
-
-#if 0 /* TODO */
- if (srv_shutdown_state) {
- /* If the insert buffer becomes empty during
- shutdown, note it in the system tablespace. */
-
- trx_sys_set_ibuf_format(TRX_SYS_IBUF_EMPTY);
- }
-
- /* TO DO: call trx_sys_set_ibuf_format() at startup
- and whenever ibuf_use is changed to allow buffered
- delete-marking or deleting. Never downgrade the
- stamped format except when the insert buffer becomes
- empty. */
-#endif
-
return(0);
}
@@ -2604,7 +2587,7 @@ ibuf_is_empty:
mtr_commit(&mtr);
btr_pcur_close(&pcur);
- goto ibuf_is_empty;
+ return(0);
}
sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur),
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index cb65c6bfab7..be918439f59 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -466,7 +466,10 @@ btr_estimate_n_rows_in_range(
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
-The estimates are stored in the array index->stat_n_diff_key_vals. */
+The estimates are stored in the array index->stat_n_diff_key_vals.
+If innodb_stats_method is nulls_ignored, we also record the number of
+non-null values for each prefix and stored the estimates in
+array index->stat_n_non_null_key_vals. */
UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
@@ -497,8 +500,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
-btr_store_big_rec_extern_fields(
-/*============================*/
+btr_store_big_rec_extern_fields_func(
+/*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */
@@ -507,10 +510,42 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /*!< in: vector containing fields
+#ifdef UNIV_DEBUG
+ mtr_t* local_mtr, /*!< in: mtr containing the
+ latch to rec and to the tree */
+#endif /* UNIV_DEBUG */
+#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
+ ibool update_in_place,/*! in: TRUE if the record is updated
+ in place (not delete+insert) */
+#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
+ const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr); /*!< in: mtr containing the latch to
- rec and to the tree */
+ __attribute__((nonnull));
+
+/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
+them in rec. The extern flags in rec will have to be set beforehand.
+The fields are stored on pages allocated from leaf node
+file segment of the index tree.
+@param index in: clustered index; MUST be X-latched by mtr
+@param b in/out: block containing rec; MUST be X-latched by mtr
+@param rec in/out: clustered index record
+@param offsets in: rec_get_offsets(rec, index);
+ the "external storage" flags in offsets will not be adjusted
+@param mtr in: mini-transaction that holds x-latch on index and b
+@param upd in: TRUE if the record is updated in place (not delete+insert)
+@param big in: vector containing fields to be stored externally
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
+#ifdef UNIV_DEBUG
+# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
+ btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
+#elif defined UNIV_BLOB_LIGHT_DEBUG
+# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
+ btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
+#else
+# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
+ btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
+#endif
+
/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned the externally stored field,
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 46cae25f0f5..dbd5adee0cc 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -276,9 +276,9 @@ UNIV_INTERN
buf_block_t*
buf_block_alloc(
/*============*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint zip_size); /*!< in: compressed page size in bytes,
- or 0 if uncompressed tablespace */
+ buf_pool_t* buf_pool); /*!< in: buffer pool instance,
+ or NULL for round-robin selection
+ of the buffer pool */
/********************************************************************//**
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
@@ -480,7 +480,7 @@ buf_reset_check_index_page_at_flush(
/*================================*/
ulint space, /*!< in: space id */
ulint offset);/*!< in: page number */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
@@ -505,7 +505,7 @@ buf_page_reset_file_page_was_freed(
/*===============================*/
ulint space, /*!< in: space id */
ulint offset); /*!< in: page number */
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//**
Reads the freed_page_clock of a buffer block.
@return freed_page_clock */
@@ -1403,11 +1403,11 @@ struct buf_page_struct{
0 if the block was never accessed
in the buffer pool */
/* @} */
-# ifdef UNIV_DEBUG_FILE_ACCESSES
+# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
/*!< this is set to TRUE when fsp
frees a page in buffer pool */
-# endif /* UNIV_DEBUG_FILE_ACCESSES */
+# endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 7bcec633d9c..9b150188b03 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -111,12 +111,9 @@ enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
buf_page_t* bpage, /*!< in: block to be freed */
- ibool zip, /*!< in: TRUE if should remove also the
+ ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
- ibool* buf_pool_mutex_released);
- /*!< in: pointer to a variable that will
- be assigned TRUE if buf_pool->mutex
- was temporarily released, or NULL */
+ __attribute__((nonnull));
/******************************************************************//**
Try to free a replaceable block.
@return TRUE if found and freed */
@@ -153,9 +150,8 @@ UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- buf_pool_t* buf_pool, /*!< in: preferred buffer pool */
- ulint zip_size); /*!< in: compressed page size in bytes,
- or 0 if uncompressed tablespace */
+ buf_pool_t* buf_pool) /*!< in/out: buffer pool instance */
+ __attribute__((nonnull,warn_unused_result));
/******************************************************************//**
Puts a block back to the free list. */
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 7526e4dc8dc..5757b79d3ed 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -376,6 +376,12 @@ struct dict_index_struct{
dict_get_n_unique(index); we
periodically calculate new
estimates */
+ ib_int64_t* stat_n_non_null_key_vals;
+ /* approximate number of non-null key values
+ for this index, for each column where
+ n < dict_get_n_unique(index); This
+ is used when innodb_stats_method is
+ "nulls_ignored". */
ulint stat_index_size;
/*!< approximate index size in
database pages */
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index 0a9edfbfe70..687209575c9 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -33,11 +33,6 @@ typedef struct dict_index_struct dict_index_t;
typedef struct dict_table_struct dict_table_t;
typedef struct dict_foreign_struct dict_foreign_t;
-/* A cluster object is a table object with the type field set to
-DICT_CLUSTERED */
-
-typedef dict_table_t dict_cluster_t;
-
typedef struct ind_node_struct ind_node_t;
typedef struct tab_node_struct tab_node_t;
diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h
index 2f751a38864..a908521c9f7 100644
--- a/storage/innobase/include/rem0cmp.h
+++ b/storage/innobase/include/rem0cmp.h
@@ -165,6 +165,10 @@ cmp_rec_rec_with_match(
const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
dict_index_t* index, /*!< in: data dictionary index */
+ ibool nulls_unequal,
+ /* in: TRUE if this is for index statistics
+ cardinality estimation, and innodb_stats_method
+ is "nulls_unequal" or "nulls_ignored" */
ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
diff --git a/storage/innobase/include/rem0cmp.ic b/storage/innobase/include/rem0cmp.ic
index 39ef5f4fba3..63415fe7837 100644
--- a/storage/innobase/include/rem0cmp.ic
+++ b/storage/innobase/include/rem0cmp.ic
@@ -87,5 +87,5 @@ cmp_rec_rec(
ulint match_b = 0;
return(cmp_rec_rec_with_match(rec1, rec2, offsets1, offsets2, index,
- &match_f, &match_b));
+ FALSE, &match_f, &match_b));
}
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 9c2e003c609..c275c1da78e 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -280,19 +280,29 @@ NOTE: we compare the fields as binary strings!
@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
-row_upd_changes_ord_field_binary(
-/*=============================*/
+row_upd_changes_ord_field_binary_func(
+/*==================================*/
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update, /*!< in: update vector for the row; NOTE: the
+ field numbers in this MUST be clustered index
+ positions! */
+#ifdef UNIV_DEBUG
+ const que_thr_t*thr, /*!< in: query thread */
+#endif /* UNIV_DEBUG */
const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- const row_ext_t*ext, /*!< NULL, or prefixes of the externally
+ const row_ext_t*ext) /*!< NULL, or prefixes of the externally
stored columns in the old row */
- dict_index_t* index, /*!< in: index of the record */
- const upd_t* update) /*!< in: update vector for the row; NOTE: the
- field numbers in this MUST be clustered index
- positions! */
- __attribute__((nonnull(3,4), warn_unused_result));
+ __attribute__((nonnull(1,2), warn_unused_result));
+#ifdef UNIV_DEBUG
+# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
+ row_upd_changes_ord_field_binary_func(index,update,thr,row,ext)
+#else /* UNIV_DEBUG */
+# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
+ row_upd_changes_ord_field_binary_func(index,update,row,ext)
+#endif /* UNIV_DEBUG */
/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 612ff4c6e54..d600ad4a034 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -172,6 +172,11 @@ capacity. PCT_IO(5) -> returns the number of IO operations that
is 5% of the max where max is srv_io_capacity. */
#define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) p / 100.0)))
+/* The "innodb_stats_method" setting, decides how InnoDB is going
+to treat NULL value when collecting statistics. It is not defined
+as enum type because the configure option takes unsigned integer type. */
+extern ulong srv_innodb_stats_method;
+
#ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on;
extern ibool srv_archive_recovery;
@@ -418,6 +423,19 @@ enum {
in connection with recovery */
};
+/* Alternatives for srv_innodb_stats_method, which could be changed by
+setting innodb_stats_method */
+enum srv_stats_method_name_enum {
+ SRV_STATS_NULLS_EQUAL, /* All NULL values are treated as
+ equal. This is the default setting
+ for innodb_stats_method */
+ SRV_STATS_NULLS_UNEQUAL, /* All NULL values are treated as
+ NOT equal. */
+ SRV_STATS_NULLS_IGNORED /* NULL values are ignored */
+};
+
+typedef enum srv_stats_method_name_enum srv_stats_method_name_t;
+
#ifndef UNIV_HOTBACKUP
/** Types of threads existing in the system. */
enum srv_thread_type {
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index 5988fdfb382..9e5c96fa323 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -555,6 +555,7 @@ UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
+ FILE* f, /*!< in: output stream */
rw_lock_debug_t* info); /*!< in: debug struct */
#endif /* UNIV_SYNC_DEBUG */
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index 78a7a8c4bb0..a293d9b896e 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -141,9 +141,7 @@ struct trx_rseg_struct{
ulint id; /*!< rollback segment id == the index of
its slot in the trx system file copy */
mutex_t mutex; /*!< mutex protecting the fields in this
- struct except id; NOTE that the latching
- order must always be kernel mutex ->
- rseg mutex */
+ struct except id, which is constant */
ulint space; /*!< space where the rollback segment is
header is placed */
ulint zip_size;/* compressed page size of space
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index b4a4aa0ca44..83f6182c347 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -214,12 +214,12 @@ trx_recover_for_mysql(
/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
which is in the prepared state
-@return trx or NULL */
+@return trx or NULL; on match, the trx->xid will be invalidated */
UNIV_INTERN
trx_t *
trx_get_trx_by_xid(
/*===============*/
- XID* xid); /*!< in: X/Open XA transaction identification */
+ const XID* xid); /*!< in: X/Open XA transaction identifier */
/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
with trx->flush_log_later == TRUE.
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 4470d221da9..a99b8306eb8 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -184,14 +184,15 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_BUF_DEBUG /* Enable buffer pool
debugging without UNIV_DEBUG */
+#define UNIV_BLOB_LIGHT_DEBUG /* Enable off-page column
+ debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
ut_ad(lock_rec_validate_page())
assertions. */
-#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
- (field file_page_was_freed
- in buf_page_t) */
+#define UNIV_DEBUG_FILE_ACCESSES /* Enable freed block access
+ debugging without UNIV_DEBUG */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
@@ -308,6 +309,18 @@ number does not include a terminating '\0'. InnoDB probably can handle
longer names internally */
#define MAX_TABLE_NAME_LEN 192
+/* The maximum length of a database name. Like MAX_TABLE_NAME_LEN this is
+the MySQL's NAME_LEN, see check_and_convert_db_name(). */
+#define MAX_DATABASE_NAME_LEN MAX_TABLE_NAME_LEN
+
+/* MAX_FULL_NAME_LEN defines the full name path including the
+database name and table name. In addition, 14 bytes is added for:
+ 2 for surrounding quotes around table name
+ 1 for the separating dot (.)
+ 9 for the #mysql50# prefix */
+#define MAX_FULL_NAME_LEN \
+ (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14)
+
/*
UNIVERSAL TYPE DEFINITIONS
==========================
@@ -429,7 +442,7 @@ it is read or written. */
/* Use sun_prefetch when compile with Sun Studio */
# define UNIV_EXPECT(expr,value) (expr)
# define UNIV_LIKELY_NULL(expr) (expr)
-# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many(addr)
+# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many((void*) addr)
# define UNIV_PREFETCH_RW(addr) sun_prefetch_write_many(addr)
#else
/* Dummy versions of the macros */
diff --git a/storage/innobase/include/ut0vec.h b/storage/innobase/include/ut0vec.h
index a770f671cfc..0f8b955b098 100644
--- a/storage/innobase/include/ut0vec.h
+++ b/storage/innobase/include/ut0vec.h
@@ -94,6 +94,25 @@ ib_vector_get(
ulint n); /*!< in: element index to get */
/****************************************************************//**
+Get last element. The vector must not be empty.
+@return last element */
+UNIV_INLINE
+void*
+ib_vector_get_last(
+/*===============*/
+ ib_vector_t* vec); /*!< in: vector */
+
+/****************************************************************//**
+Set the n'th element. */
+UNIV_INLINE
+void
+ib_vector_set(
+/*==========*/
+ ib_vector_t* vec, /*!< in/out: vector */
+ ulint n, /*!< in: element index to set */
+ void* elem); /*!< in: data element */
+
+/****************************************************************//**
Remove the last element from the vector. */
UNIV_INLINE
void*
diff --git a/storage/innobase/include/ut0vec.ic b/storage/innobase/include/ut0vec.ic
index 02e881f9bca..34c858868ce 100644
--- a/storage/innobase/include/ut0vec.ic
+++ b/storage/innobase/include/ut0vec.ic
@@ -51,6 +51,35 @@ ib_vector_get(
}
/****************************************************************//**
+Get last element. The vector must not be empty.
+@return last element */
+UNIV_INLINE
+void*
+ib_vector_get_last(
+/*===============*/
+ ib_vector_t* vec) /*!< in: vector */
+{
+ ut_a(vec->used > 0);
+
+ return(vec->data[vec->used - 1]);
+}
+
+/****************************************************************//**
+Set the n'th element. */
+UNIV_INLINE
+void
+ib_vector_set(
+/*==========*/
+ ib_vector_t* vec, /*!< in/out: vector */
+ ulint n, /*!< in: element index to set */
+ void* elem) /*!< in: data element */
+{
+ ut_a(n < vec->used);
+
+ vec->data[n] = elem;
+}
+
+/****************************************************************//**
Remove the last element from the vector.
@return last vector element */
UNIV_INLINE
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index f38ef48df4e..ceb4e89c08a 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -3622,6 +3622,80 @@ lock_table_create(
}
/*************************************************************//**
+Pops autoinc lock requests from the transaction's autoinc_locks. We
+handle the case where there are gaps in the array and they need to
+be popped off the stack. */
+UNIV_INLINE
+void
+lock_table_pop_autoinc_locks(
+/*=========================*/
+ trx_t* trx) /*!< in/out: transaction that owns the AUTOINC locks */
+{
+ ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
+
+ /* Skip any gaps, gaps are NULL lock entries in the
+ trx->autoinc_locks vector. */
+
+ do {
+ ib_vector_pop(trx->autoinc_locks);
+
+ if (ib_vector_is_empty(trx->autoinc_locks)) {
+ return;
+ }
+
+ } while (ib_vector_get_last(trx->autoinc_locks) == NULL);
+}
+
+/*************************************************************//**
+Removes an autoinc lock request from the transaction's autoinc_locks. */
+UNIV_INLINE
+void
+lock_table_remove_autoinc_lock(
+/*===========================*/
+ lock_t* lock, /*!< in: table lock */
+ trx_t* trx) /*!< in/out: transaction that owns the lock */
+{
+ lock_t* autoinc_lock;
+ lint i = ib_vector_size(trx->autoinc_locks) - 1;
+
+ ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(lock_get_mode(lock) == LOCK_AUTO_INC);
+ ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
+ ut_ad(!ib_vector_is_empty(trx->autoinc_locks));
+
+ /* With stored functions and procedures the user may drop
+ a table within the same "statement". This special case has
+ to be handled by deleting only those AUTOINC locks that were
+ held by the table being dropped. */
+
+ autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
+
+ /* This is the default fast case. */
+
+ if (autoinc_lock == lock) {
+ lock_table_pop_autoinc_locks(trx);
+ } else {
+ /* The last element should never be NULL */
+ ut_a(autoinc_lock != NULL);
+
+ /* Handle freeing the locks from within the stack. */
+
+ while (--i >= 0) {
+ autoinc_lock = ib_vector_get(trx->autoinc_locks, i);
+
+ if (UNIV_LIKELY(autoinc_lock == lock)) {
+ ib_vector_set(trx->autoinc_locks, i, NULL);
+ return;
+ }
+ }
+
+ /* Must find the autoinc lock. */
+ ut_error;
+ }
+}
+
+/*************************************************************//**
Removes a table lock request from the queue and the trx list of locks;
this is a low-level function which does NOT check if waiting requests
can now be granted. */
@@ -3660,10 +3734,8 @@ lock_table_remove_low(
if (!lock_get_wait(lock)
&& !ib_vector_is_empty(trx->autoinc_locks)) {
- lock_t* autoinc_lock;
- autoinc_lock = ib_vector_pop(trx->autoinc_locks);
- ut_a(autoinc_lock == lock);
+ lock_table_remove_autoinc_lock(lock, trx);
}
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index b5a7ddbd7b2..7727760f1cd 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -347,7 +347,7 @@ mem_heap_create_block(
return(NULL);
}
} else {
- buf_block = buf_block_alloc(NULL, 0);
+ buf_block = buf_block_alloc(NULL);
}
block = (mem_block_t*) buf_block->frame;
diff --git a/storage/innobase/mtr/mtr0log.c b/storage/innobase/mtr/mtr0log.c
index 04eeb4391cd..864970cef40 100644
--- a/storage/innobase/mtr/mtr0log.c
+++ b/storage/innobase/mtr/mtr0log.c
@@ -408,7 +408,7 @@ mlog_parse_string(
ptr += 2;
if (UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
- || UNIV_UNLIKELY(len + offset) > UNIV_PAGE_SIZE) {
+ || UNIV_UNLIKELY(len + offset > UNIV_PAGE_SIZE)) {
recv_sys->found_corrupt_log = TRUE;
return(NULL);
diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
index 98640a8e6fb..4c5371370da 100644
--- a/storage/innobase/page/page0zip.c
+++ b/storage/innobase/page/page0zip.c
@@ -4440,7 +4440,7 @@ page_zip_reorganize(
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
#ifndef UNIV_HOTBACKUP
- temp_block = buf_block_alloc(buf_pool, 0);
+ temp_block = buf_block_alloc(buf_pool);
btr_search_drop_page_hash_index(block);
block->check_index_page_at_flush = TRUE;
#else /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/rem/rem0cmp.c b/storage/innobase/rem/rem0cmp.c
index 35b67992558..04d2c15437b 100644
--- a/storage/innobase/rem/rem0cmp.c
+++ b/storage/innobase/rem/rem0cmp.c
@@ -862,6 +862,10 @@ cmp_rec_rec_with_match(
const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
dict_index_t* index, /*!< in: data dictionary index */
+ ibool nulls_unequal,
+ /* in: TRUE if this is for index statistics
+ cardinality estimation, and innodb_stats_method
+ is "nulls_unequal" or "nulls_ignored" */
ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
@@ -961,9 +965,13 @@ cmp_rec_rec_with_match(
|| rec2_f_len == UNIV_SQL_NULL) {
if (rec1_f_len == rec2_f_len) {
-
- goto next_field;
-
+ /* This is limited to stats collection,
+ cannot use it for regular search */
+ if (nulls_unequal) {
+ ret = -1;
+ } else {
+ goto next_field;
+ }
} else if (rec2_f_len == UNIV_SQL_NULL) {
/* We define the SQL null to be the
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index dbfba358f9f..e0414cde80d 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -2122,7 +2122,7 @@ function_exit:
err = btr_store_big_rec_extern_fields(
index, btr_cur_get_block(&cursor),
- rec, offsets, big_rec, &mtr);
+ rec, offsets, &mtr, FALSE, big_rec);
if (modify) {
dtuple_big_rec_free(big_rec);
diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
index 209df02e445..5be437add5a 100644
--- a/storage/innobase/row/row0merge.c
+++ b/storage/innobase/row/row0merge.c
@@ -2157,13 +2157,15 @@ row_merge_drop_temp_indexes(void)
}
/*********************************************************************//**
-Create a merge file. */
-static
-void
-row_merge_file_create(
-/*==================*/
- merge_file_t* merge_file) /*!< out: merge file structure */
+Creates temperary merge files, and if UNIV_PFS_IO defined, register
+the file descriptor with Performance Schema.
+@return File descriptor */
+UNIV_INLINE
+int
+row_merge_file_create_low(void)
+/*===========================*/
{
+ int fd;
#ifdef UNIV_PFS_IO
/* This temp file open does not go through normal
file APIs, add instrumentation to register with
@@ -2175,37 +2177,59 @@ row_merge_file_create(
"Innodb Merge Temp File",
__FILE__, __LINE__);
#endif
- merge_file->fd = innobase_mysql_tmpfile();
- merge_file->offset = 0;
- merge_file->n_rec = 0;
+ fd = innobase_mysql_tmpfile();
#ifdef UNIV_PFS_IO
- register_pfs_file_open_end(locker, merge_file->fd);
+ register_pfs_file_open_end(locker, fd);
#endif
+ return(fd);
}
-
/*********************************************************************//**
-Destroy a merge file. */
+Create a merge file. */
static
void
-row_merge_file_destroy(
-/*===================*/
+row_merge_file_create(
+/*==================*/
merge_file_t* merge_file) /*!< out: merge file structure */
{
+ merge_file->fd = row_merge_file_create_low();
+ merge_file->offset = 0;
+ merge_file->n_rec = 0;
+}
+
+/*********************************************************************//**
+Destroy a merge file. And de-register the file from Performance Schema
+if UNIV_PFS_IO is defined. */
+UNIV_INLINE
+void
+row_merge_file_destroy_low(
+/*=======================*/
+ int fd) /*!< in: merge file descriptor */
+{
#ifdef UNIV_PFS_IO
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
- register_pfs_file_io_begin(&state, locker, merge_file->fd, 0, PSI_FILE_CLOSE,
+ register_pfs_file_io_begin(&state, locker,
+ fd, 0, PSI_FILE_CLOSE,
__FILE__, __LINE__);
#endif
- if (merge_file->fd != -1) {
- close(merge_file->fd);
- merge_file->fd = -1;
- }
-
+ close(fd);
#ifdef UNIV_PFS_IO
register_pfs_file_io_end(locker, 0);
#endif
}
+/*********************************************************************//**
+Destroy a merge file. */
+static
+void
+row_merge_file_destroy(
+/*===================*/
+ merge_file_t* merge_file) /*!< out: merge file structure */
+{
+ if (merge_file->fd != -1) {
+ row_merge_file_destroy_low(merge_file->fd);
+ merge_file->fd = -1;
+ }
+}
/*********************************************************************//**
Determine the precise type of a column that is added to a tem
@@ -2363,7 +2387,7 @@ row_merge_rename_tables(
{
ulint err = DB_ERROR;
pars_info_t* info;
- char old_name[MAX_TABLE_NAME_LEN + 1];
+ char old_name[MAX_FULL_NAME_LEN + 1];
ut_ad(old_table != new_table);
ut_ad(mutex_own(&dict_sys->mutex));
@@ -2377,7 +2401,7 @@ row_merge_rename_tables(
ut_print_timestamp(stderr);
fprintf(stderr, "InnoDB: too long table name: '%s', "
"max length is %d\n", old_table->name,
- MAX_TABLE_NAME_LEN);
+ MAX_FULL_NAME_LEN);
ut_error;
}
@@ -2598,7 +2622,7 @@ row_merge_build_indexes(
row_merge_file_create(&merge_files[i]);
}
- tmpfd = innobase_mysql_tmpfile();
+ tmpfd = row_merge_file_create_low();
/* Reset the MySQL row buffer that is used when reporting
duplicate keys. */
@@ -2640,7 +2664,7 @@ row_merge_build_indexes(
}
func_exit:
- close(tmpfd);
+ row_merge_file_destroy_low(tmpfd);
for (i = 0; i < n_indexes; i++) {
row_merge_file_destroy(&merge_files[i]);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 23d248481c9..31aa49d4267 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1933,15 +1933,13 @@ err_exit:
err = trx->error_state;
- if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
+ switch (err) {
+ case DB_SUCCESS:
+ break;
+ case DB_OUT_OF_FILE_SPACE:
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
- /* TO DO: free table? The code below will dereference
- table->name, though. */
- }
- switch (err) {
- case DB_OUT_OF_FILE_SPACE:
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: cannot create table ",
stderr);
@@ -1956,9 +1954,13 @@ err_exit:
break;
case DB_DUPLICATE_KEY:
+ default:
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
+ trx->error_state = DB_SUCCESS;
+ trx_general_rollback_for_mysql(trx, NULL);
+ dict_mem_table_free(table);
break;
}
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index 08abc8a3e59..83e7c9e4857 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -489,8 +489,11 @@ Purges an update of an existing record. Also purges an update of a delete
marked record if that record contained an externally stored field. */
static
void
-row_purge_upd_exist_or_extern(
-/*==========================*/
+row_purge_upd_exist_or_extern_func(
+/*===============================*/
+#ifdef UNIV_DEBUG
+ const que_thr_t*thr, /*!< in: query thread */
+#endif /* UNIV_DEBUG */
purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
@@ -515,8 +518,8 @@ row_purge_upd_exist_or_extern(
while (node->index != NULL) {
index = node->index;
- if (row_upd_changes_ord_field_binary(NULL, NULL, node->index,
- node->update)) {
+ if (row_upd_changes_ord_field_binary(node->index, node->update,
+ thr, NULL, NULL)) {
/* Build the older version of the index entry */
entry = row_build_index_entry(node->row, NULL,
index, heap);
@@ -598,6 +601,14 @@ skip_secondaries:
}
}
+#ifdef UNIV_DEBUG
+# define row_purge_upd_exist_or_extern(thr,node) \
+ row_purge_upd_exist_or_extern_func(thr,node)
+#else /* UNIV_DEBUG */
+# define row_purge_upd_exist_or_extern(thr,node) \
+ row_purge_upd_exist_or_extern_func(node)
+#endif /* UNIV_DEBUG */
+
/***********************************************************//**
Parses the row reference and other info in a modify undo log record.
@return TRUE if purge operation required: NOTE that then the CALLER
@@ -704,47 +715,32 @@ err_exit:
/***********************************************************//**
Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the
-parent node, which is always a query thread node.
-@return DB_SUCCESS if operation successfully completed, else error code */
-static
-ulint
+parent node, which is always a query thread node. */
+static __attribute__((nonnull))
+void
row_purge(
/*======*/
purge_node_t* node, /*!< in: row purge node */
que_thr_t* thr) /*!< in: query thread */
{
- roll_ptr_t roll_ptr;
- ibool purge_needed;
ibool updated_extern;
- trx_t* trx;
- ut_ad(node && thr);
-
- trx = thr_get_trx(thr);
+ ut_ad(node);
+ ut_ad(thr);
- node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
- &(node->reservation),
+ node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr,
+ &node->reservation,
node->heap);
if (!node->undo_rec) {
/* Purge completed for this query thread */
thr->run_node = que_node_get_parent(node);
- return(DB_SUCCESS);
- }
-
- node->roll_ptr = roll_ptr;
-
- if (node->undo_rec == &trx_purge_dummy_rec) {
- purge_needed = FALSE;
- } else {
- purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
- thr);
- /* If purge_needed == TRUE, we must also remember to unfreeze
- data dictionary! */
+ return;
}
- if (purge_needed) {
+ if (node->undo_rec != &trx_purge_dummy_rec
+ && row_purge_parse_undo_rec(node, &updated_extern, thr)) {
node->found_clust = FALSE;
node->index = dict_table_get_next_index(
@@ -756,14 +752,14 @@ row_purge(
} else if (updated_extern
|| node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
- row_purge_upd_exist_or_extern(node);
+ row_purge_upd_exist_or_extern(thr, node);
}
if (node->found_clust) {
btr_pcur_close(&(node->pcur));
}
- row_mysql_unfreeze_data_dictionary(trx);
+ row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
}
/* Do some cleanup */
@@ -771,8 +767,6 @@ row_purge(
mem_heap_empty(node->heap);
thr->run_node = node;
-
- return(DB_SUCCESS);
}
/***********************************************************//**
@@ -786,9 +780,6 @@ row_purge_step(
que_thr_t* thr) /*!< in: query thread */
{
purge_node_t* node;
-#ifdef UNIV_DEBUG
- ulint err;
-#endif /* UNIV_DEBUG */
ut_ad(thr);
@@ -796,12 +787,7 @@ row_purge_step(
ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
-#ifdef UNIV_DEBUG
- err =
-#endif /* UNIV_DEBUG */
row_purge(node, thr);
- ut_ad(err == DB_SUCCESS);
-
return(thr);
}
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index 0d4c42b958c..2188fdeff49 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low(
mtr_t* mtr, /*!< in: mtr */
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
- btr_pcur_t* pcur;
btr_cur_t* btr_cur;
ulint err;
- ibool success;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
- pcur = &(node->pcur);
- btr_cur = btr_pcur_get_btr_cur(pcur);
- success = btr_pcur_restore_position(mode, pcur, mtr);
+ /* Find out if the record has been purged already
+ or if we can remove it. */
- if (!success) {
+ if (!btr_pcur_restore_position(mode, &node->pcur, mtr)
+ || row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
return(DB_SUCCESS);
}
- /* Find out if we can remove the whole clustered index record */
-
- if (node->rec_type == TRX_UNDO_UPD_DEL_REC
- && !row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
-
- /* Ok, we can remove */
- } else {
- return(DB_SUCCESS);
- }
+ btr_cur = btr_pcur_get_btr_cur(&node->pcur);
if (mode == BTR_MODIFY_LEAF) {
- success = btr_cur_optimistic_delete(btr_cur, mtr);
-
- if (success) {
- err = DB_SUCCESS;
- } else {
- err = DB_FAIL;
- }
+ err = btr_cur_optimistic_delete(btr_cur, mtr)
+ ? DB_SUCCESS
+ : DB_FAIL;
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@@ -693,8 +679,9 @@ row_undo_mod_upd_exist_sec(
while (node->index != NULL) {
index = node->index;
- if (row_upd_changes_ord_field_binary(
- node->row, node->ext, node->index, node->update)) {
+ if (row_upd_changes_ord_field_binary(node->index, node->update,
+ thr,
+ node->row, node->ext)) {
/* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, node->ext,
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 03ed40c6647..c6bff0fccd6 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -1192,25 +1192,31 @@ NOTE: we compare the fields as binary strings!
@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
-row_upd_changes_ord_field_binary(
-/*=============================*/
+row_upd_changes_ord_field_binary_func(
+/*==================================*/
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update, /*!< in: update vector for the row; NOTE: the
+ field numbers in this MUST be clustered index
+ positions! */
+#ifdef UNIV_DEBUG
+ const que_thr_t*thr, /*!< in: query thread */
+#endif /* UNIV_DEBUG */
const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- const row_ext_t*ext, /*!< NULL, or prefixes of the externally
+ const row_ext_t*ext) /*!< NULL, or prefixes of the externally
stored columns in the old row */
- dict_index_t* index, /*!< in: index of the record */
- const upd_t* update) /*!< in: update vector for the row; NOTE: the
- field numbers in this MUST be clustered index
- positions! */
{
ulint n_unique;
ulint i;
const dict_index_t* clust_index;
- ut_ad(update);
ut_ad(index);
+ ut_ad(update);
+ ut_ad(thr);
+ ut_ad(thr->graph);
+ ut_ad(thr->graph->trx);
n_unique = dict_index_get_n_unique(index);
@@ -1252,6 +1258,10 @@ row_upd_changes_ord_field_binary(
|| dfield_is_null(dfield)) {
/* do nothing special */
} else if (UNIV_LIKELY_NULL(ext)) {
+ /* Silence a compiler warning without
+ silencing a Valgrind error. */
+ dfield_len = 0;
+ UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len);
/* See if the column is stored externally. */
buf = row_ext_lookup(ext, col_no, &dfield_len);
@@ -1259,9 +1269,14 @@ row_upd_changes_ord_field_binary(
if (UNIV_LIKELY_NULL(buf)) {
if (UNIV_UNLIKELY(buf == field_ref_zero)) {
- /* This should never happen, but
- we try to fail safe here. */
- ut_ad(0);
+ /* The externally stored field
+ was not written yet. This
+ record should only be seen by
+ recv_recovery_rollback_active(),
+ when the server had crashed before
+ storing the field. */
+ ut_ad(thr->graph->trx->is_recovered);
+ ut_ad(trx_is_recv(thr->graph->trx));
return(TRUE);
}
@@ -1636,8 +1651,8 @@ row_upd_sec_step(
ut_ad(!dict_index_is_clust(node->index));
if (node->state == UPD_NODE_UPDATE_ALL_SEC
- || row_upd_changes_ord_field_binary(node->row, node->ext,
- node->index, node->update)) {
+ || row_upd_changes_ord_field_binary(node->index, node->update,
+ thr, node->row, node->ext)) {
return(row_upd_sec_index_entry(node, thr));
}
@@ -1967,7 +1982,7 @@ row_upd_clust_rec(
index, btr_cur_get_block(btr_cur), rec,
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
- big_rec, mtr);
+ mtr, TRUE, big_rec);
mtr_commit(mtr);
}
@@ -2165,8 +2180,8 @@ exit_func:
row_upd_store_row(node);
- if (row_upd_changes_ord_field_binary(node->row, node->ext, index,
- node->update)) {
+ if (row_upd_changes_ord_field_binary(index, node->update, thr,
+ node->row, node->ext)) {
/* Update causes an ordering field (ordering fields within
the B-tree) of the clustered index record to change: perform
diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c
index 2e12361312c..91c230db135 100644
--- a/storage/innobase/row/row0vers.c
+++ b/storage/innobase/row/row0vers.c
@@ -669,11 +669,15 @@ row_vers_build_for_semi_consistent_read(
mutex_enter(&kernel_mutex);
version_trx = trx_get_on_id(version_trx_id);
+ if (version_trx
+ && (version_trx->conc_state == TRX_COMMITTED_IN_MEMORY
+ || version_trx->conc_state == TRX_NOT_STARTED)) {
+
+ version_trx = NULL;
+ }
mutex_exit(&kernel_mutex);
- if (!version_trx
- || version_trx->conc_state == TRX_NOT_STARTED
- || version_trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
+ if (!version_trx) {
/* We found a version that belongs to a
committed transaction: return it. */
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index e19e75f27a5..dcfd5463fbc 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -275,6 +275,11 @@ UNIV_INTERN ulong srv_purge_batch_size = 20;
/* variable counts amount of data read in total (in bytes) */
UNIV_INTERN ulint srv_data_read = 0;
+/* Internal setting for "innodb_stats_method". Decides how InnoDB treats
+NULL value when collecting statistics. By default, it is set to
+SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
+ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
+
/* here we count the amount of data written in total (in bytes) */
UNIV_INTERN ulint srv_data_written = 0;
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index acb448a1a67..2a9ad0e7541 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -1327,13 +1327,16 @@ innobase_start_or_create_for_mysql(void)
ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
- /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
- still applies to windows. */
- if (!srv_use_native_aio) {
- io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
- } else {
+ io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
+
+ /* On Windows when using native aio the number of aio requests
+ that a thread can handle at a given time is limited to 32
+ i.e.: SRV_N_PENDING_IOS_PER_THREAD */
+# ifdef __WIN__
+ if (srv_use_native_aio) {
io_limit = SRV_N_PENDING_IOS_PER_THREAD;
}
+# endif /* __WIN__ */
os_aio_init(io_limit,
srv_n_read_io_threads,
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index ce9d42c4921..3ecbce72ebd 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/sync/sync0arr.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -714,7 +714,7 @@ print:
fprintf(stderr, "rw-lock %p ",
(void*) lock);
sync_array_cell_print(stderr, cell);
- rw_lock_debug_print(debug);
+ rw_lock_debug_print(stderr, debug);
return(TRUE);
}
}
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 783cff3bf82..295a010f9d7 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -936,7 +936,7 @@ rw_lock_list_print_info(
info = UT_LIST_GET_FIRST(lock->debug_list);
while (info != NULL) {
- rw_lock_debug_print(info);
+ rw_lock_debug_print(file, info);
info = UT_LIST_GET_NEXT(list, info);
}
}
@@ -984,7 +984,7 @@ rw_lock_print(
info = UT_LIST_GET_FIRST(lock->debug_list);
while (info != NULL) {
- rw_lock_debug_print(info);
+ rw_lock_debug_print(stderr, info);
info = UT_LIST_GET_NEXT(list, info);
}
}
@@ -996,28 +996,29 @@ UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
+ FILE* f, /*!< in: output stream */
rw_lock_debug_t* info) /*!< in: debug struct */
{
ulint rwt;
rwt = info->lock_type;
- fprintf(stderr, "Locked: thread %lu file %s line %lu ",
+ fprintf(f, "Locked: thread %lu file %s line %lu ",
(ulong) os_thread_pf(info->thread_id), info->file_name,
(ulong) info->line);
if (rwt == RW_LOCK_SHARED) {
- fputs("S-LOCK", stderr);
+ fputs("S-LOCK", f);
} else if (rwt == RW_LOCK_EX) {
- fputs("X-LOCK", stderr);
+ fputs("X-LOCK", f);
} else if (rwt == RW_LOCK_WAIT_EX) {
- fputs("WAIT X-LOCK", stderr);
+ fputs("WAIT X-LOCK", f);
} else {
ut_error;
}
if (info->pass != 0) {
- fprintf(stderr, " pass value %lu", (ulong) info->pass);
+ fprintf(f, " pass value %lu", (ulong) info->pass);
}
- putc('\n', stderr);
+ putc('\n', f);
}
/***************************************************************//**
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index 761cc4c805e..453314f465d 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -222,21 +222,40 @@ UNIV_INTERN mysql_pfs_key_t mutex_list_mutex_key;
UNIV_INTERN ibool sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+/** Number of slots reserved for each OS thread in the sync level array */
+static const ulint SYNC_THREAD_N_LEVELS = 10000;
+
+typedef struct sync_arr_struct sync_arr_t;
+
+/** Array for tracking sync levels per thread. */
+struct sync_arr_struct {
+ ulint in_use; /*!< Number of active cells */
+ ulint n_elems; /*!< Number of elements in the array */
+ ulint max_elems; /*!< Maximum elements */
+ ulint next_free; /*!< ULINT_UNDEFINED or index of next
+ free slot */
+ sync_level_t* elems; /*!< Array elements */
+};
+
/** Mutexes or rw-locks held by a thread */
struct sync_thread_struct{
- os_thread_id_t id; /*!< OS thread id */
- sync_level_t* levels; /*!< level array for this thread; if
- this is NULL this slot is unused */
+ os_thread_id_t id; /*!< OS thread id */
+ sync_arr_t* levels; /*!< level array for this thread; if
+ this is NULL this slot is unused */
};
-/** Number of slots reserved for each OS thread in the sync level array */
-#define SYNC_THREAD_N_LEVELS 10000
-
/** An acquired mutex or rw-lock and its level in the latching order */
struct sync_level_struct{
- void* latch; /*!< pointer to a mutex or an rw-lock; NULL means that
- the slot is empty */
- ulint level; /*!< level of the latch in the latching order */
+ void* latch; /*!< pointer to a mutex or an
+ rw-lock; NULL means that
+ the slot is empty */
+ ulint level; /*!< level of the latch in the
+ latching order. This field is
+ overloaded to serve as a node in a
+ linked list of free nodes too. When
+ latch == NULL then this will contain
+ the ordinal value of the next free
+ element */
};
/******************************************************************//**
@@ -745,27 +764,28 @@ mutex_n_reserved(void)
/*==================*/
{
mutex_t* mutex;
- ulint count = 0;
+ ulint count = 0;
mutex_enter(&mutex_list_mutex);
- mutex = UT_LIST_GET_FIRST(mutex_list);
+ for (mutex = UT_LIST_GET_FIRST(mutex_list);
+ mutex != NULL;
+ mutex = UT_LIST_GET_NEXT(list, mutex)) {
- while (mutex != NULL) {
if (mutex_get_lock_word(mutex) != 0) {
count++;
}
-
- mutex = UT_LIST_GET_NEXT(list, mutex);
}
mutex_exit(&mutex_list_mutex);
ut_a(count >= 1);
- return(count - 1); /* Subtract one, because this function itself
- was holding one mutex (mutex_list_mutex) */
+ /* Subtract one, because this function itself was holding
+ one mutex (mutex_list_mutex) */
+
+ return(count - 1);
}
/******************************************************************//**
@@ -781,20 +801,6 @@ sync_all_freed(void)
}
/******************************************************************//**
-Gets the value in the nth slot in the thread level arrays.
-@return pointer to thread slot */
-static
-sync_thread_t*
-sync_thread_level_arrays_get_nth(
-/*=============================*/
- ulint n) /*!< in: slot number */
-{
- ut_ad(n < OS_THREAD_MAX_N);
-
- return(sync_thread_level_arrays + n);
-}
-
-/******************************************************************//**
Looks for the thread slot for the calling thread.
@return pointer to thread slot, NULL if not found */
static
@@ -803,15 +809,15 @@ sync_thread_level_arrays_find_slot(void)
/*====================================*/
{
- sync_thread_t* slot;
- os_thread_id_t id;
ulint i;
+ os_thread_id_t id;
id = os_thread_get_curr_id();
for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ sync_thread_t* slot;
- slot = sync_thread_level_arrays_get_nth(i);
+ slot = &sync_thread_level_arrays[i];
if (slot->levels && os_thread_eq(slot->id, id)) {
@@ -831,12 +837,12 @@ sync_thread_level_arrays_find_free(void)
/*====================================*/
{
- sync_thread_t* slot;
ulint i;
for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ sync_thread_t* slot;
- slot = sync_thread_level_arrays_get_nth(i);
+ slot = &sync_thread_level_arrays[i];
if (slot->levels == NULL) {
@@ -848,19 +854,44 @@ sync_thread_level_arrays_find_free(void)
}
/******************************************************************//**
-Gets the value in the nth slot in the thread level array.
-@return pointer to level slot */
+Print warning. */
static
-sync_level_t*
-sync_thread_levels_get_nth(
-/*=======================*/
- sync_level_t* arr, /*!< in: pointer to level array for an OS
- thread */
- ulint n) /*!< in: slot number */
+void
+sync_print_warning(
+/*===============*/
+ const sync_level_t* slot) /*!< in: slot for which to
+ print warning */
{
- ut_ad(n < SYNC_THREAD_N_LEVELS);
+ mutex_t* mutex;
+
+ mutex = slot->latch;
+
+ if (mutex->magic_n == MUTEX_MAGIC_N) {
+ fprintf(stderr,
+ "Mutex created at %s %lu\n",
+ mutex->cfile_name, (ulong) mutex->cline);
+
+ if (mutex_get_lock_word(mutex) != 0) {
+ ulint line;
+ const char* file_name;
+ os_thread_id_t thread_id;
+
+ mutex_get_debug_info(
+ mutex, &file_name, &line, &thread_id);
+
+ fprintf(stderr,
+ "InnoDB: Locked mutex:"
+ " addr %p thread %ld file %s line %ld\n",
+ (void*) mutex, os_thread_pf(thread_id),
+ file_name, (ulong) line);
+ } else {
+ fputs("Not locked\n", stderr);
+ }
+ } else {
+ rw_lock_t* lock = slot->latch;
- return(arr + n);
+ rw_lock_print(lock);
+ }
}
/******************************************************************//**
@@ -871,69 +902,29 @@ static
ibool
sync_thread_levels_g(
/*=================*/
- sync_level_t* arr, /*!< in: pointer to level array for an OS
+ sync_arr_t* arr, /*!< in: pointer to level array for an OS
thread */
ulint limit, /*!< in: level limit */
ulint warn) /*!< in: TRUE=display a diagnostic message */
{
- sync_level_t* slot;
- rw_lock_t* lock;
- mutex_t* mutex;
ulint i;
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
-
- slot = sync_thread_levels_get_nth(arr, i);
-
- if (slot->latch != NULL) {
- if (slot->level <= limit) {
-
- if (!warn) {
-
- return(FALSE);
- }
+ for (i = 0; i < arr->n_elems; i++) {
+ const sync_level_t* slot;
- lock = slot->latch;
- mutex = slot->latch;
+ slot = &arr->elems[i];
+ if (slot->latch != NULL && slot->level <= limit) {
+ if (warn) {
fprintf(stderr,
"InnoDB: sync levels should be"
" > %lu but a level is %lu\n",
(ulong) limit, (ulong) slot->level);
- if (mutex->magic_n == MUTEX_MAGIC_N) {
- fprintf(stderr,
- "Mutex created at %s %lu\n",
- mutex->cfile_name,
- (ulong) mutex->cline);
-
- if (mutex_get_lock_word(mutex) != 0) {
- const char* file_name;
- ulint line;
- os_thread_id_t thread_id;
-
- mutex_get_debug_info(
- mutex, &file_name,
- &line, &thread_id);
-
- fprintf(stderr,
- "InnoDB: Locked mutex:"
- " addr %p thread %ld"
- " file %s line %ld\n",
- (void*) mutex,
- os_thread_pf(
- thread_id),
- file_name,
- (ulong) line);
- } else {
- fputs("Not locked\n", stderr);
- }
- } else {
- rw_lock_print(lock);
- }
-
- return(FALSE);
+ sync_print_warning(slot);
}
+
+ return(FALSE);
}
}
@@ -942,31 +933,29 @@ sync_thread_levels_g(
/******************************************************************//**
Checks if the level value is stored in the level array.
-@return TRUE if stored */
+@return slot if found or NULL */
static
-ibool
+const sync_level_t*
sync_thread_levels_contain(
/*=======================*/
- sync_level_t* arr, /*!< in: pointer to level array for an OS
+ sync_arr_t* arr, /*!< in: pointer to level array for an OS
thread */
ulint level) /*!< in: level */
{
- sync_level_t* slot;
ulint i;
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ for (i = 0; i < arr->n_elems; i++) {
+ const sync_level_t* slot;
- slot = sync_thread_levels_get_nth(arr, i);
+ slot = &arr->elems[i];
- if (slot->latch != NULL) {
- if (slot->level == level) {
+ if (slot->latch != NULL && slot->level == level) {
- return(TRUE);
- }
+ return(slot);
}
}
- return(FALSE);
+ return(NULL);
}
/******************************************************************//**
@@ -980,10 +969,9 @@ sync_thread_levels_contains(
ulint level) /*!< in: latching order level
(SYNC_DICT, ...)*/
{
- sync_level_t* arr;
- sync_thread_t* thread_slot;
- sync_level_t* slot;
ulint i;
+ sync_arr_t* arr;
+ sync_thread_t* thread_slot;
if (!sync_order_checks_on) {
@@ -1003,9 +991,10 @@ sync_thread_levels_contains(
arr = thread_slot->levels;
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ for (i = 0; i < arr->n_elems; i++) {
+ sync_level_t* slot;
- slot = sync_thread_levels_get_nth(arr, i);
+ slot = &arr->elems[i];
if (slot->latch != NULL && slot->level == level) {
@@ -1031,10 +1020,9 @@ sync_thread_levels_nonempty_gen(
also purge_is_running mutex is
allowed */
{
- sync_level_t* arr;
- sync_thread_t* thread_slot;
- sync_level_t* slot;
ulint i;
+ sync_arr_t* arr;
+ sync_thread_t* thread_slot;
if (!sync_order_checks_on) {
@@ -1054,9 +1042,10 @@ sync_thread_levels_nonempty_gen(
arr = thread_slot->levels;
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ for (i = 0; i < arr->n_elems; ++i) {
+ const sync_level_t* slot;
- slot = sync_thread_levels_get_nth(arr, i);
+ slot = &arr->elems[i];
if (slot->latch != NULL
&& (!dict_mutex_allowed
@@ -1098,10 +1087,10 @@ sync_thread_add_level(
ulint level) /*!< in: level in the latching order; if
SYNC_LEVEL_VARYING, nothing is done */
{
- sync_level_t* array;
+ ulint i;
sync_level_t* slot;
+ sync_arr_t* array;
sync_thread_t* thread_slot;
- ulint i;
if (!sync_order_checks_on) {
@@ -1126,20 +1115,23 @@ sync_thread_add_level(
thread_slot = sync_thread_level_arrays_find_slot();
if (thread_slot == NULL) {
- /* We have to allocate the level array for a new thread */
- array = ut_malloc(sizeof(sync_level_t) * SYNC_THREAD_N_LEVELS);
+ ulint sz;
- thread_slot = sync_thread_level_arrays_find_free();
+ sz = sizeof(*array)
+ + (sizeof(*array->elems) * SYNC_THREAD_N_LEVELS);
- thread_slot->id = os_thread_get_curr_id();
- thread_slot->levels = array;
+ /* We have to allocate the level array for a new thread */
+ array = calloc(sz, sizeof(char));
+ ut_a(array != NULL);
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ array->next_free = ULINT_UNDEFINED;
+ array->max_elems = SYNC_THREAD_N_LEVELS;
+ array->elems = (sync_level_t*) &array[1];
- slot = sync_thread_levels_get_nth(array, i);
+ thread_slot = sync_thread_level_arrays_find_free();
- slot->latch = NULL;
- }
+ thread_slot->levels = array;
+ thread_slot->id = os_thread_get_curr_id();
}
array = thread_slot->levels;
@@ -1303,19 +1295,26 @@ sync_thread_add_level(
ut_error;
}
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ if (array->next_free == ULINT_UNDEFINED) {
+ ut_a(array->n_elems < array->max_elems);
- slot = sync_thread_levels_get_nth(array, i);
+ i = array->n_elems++;
+ } else {
+ i = array->next_free;
+ array->next_free = array->elems[i].level;
+ }
- if (slot->latch == NULL) {
- slot->latch = latch;
- slot->level = level;
+ ut_a(i < array->n_elems);
+ ut_a(i != ULINT_UNDEFINED);
- break;
- }
- }
+ ++array->in_use;
+
+ slot = &array->elems[i];
- ut_a(i < SYNC_THREAD_N_LEVELS);
+ ut_a(slot->latch == NULL);
+
+ slot->latch = latch;
+ slot->level = level;
mutex_exit(&sync_thread_mutex);
}
@@ -1331,8 +1330,7 @@ sync_thread_reset_level(
/*====================*/
void* latch) /*!< in: pointer to a mutex or an rw-lock */
{
- sync_level_t* array;
- sync_level_t* slot;
+ sync_arr_t* array;
sync_thread_t* thread_slot;
ulint i;
@@ -1363,17 +1361,37 @@ sync_thread_reset_level(
array = thread_slot->levels;
- for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
+ for (i = 0; i < array->n_elems; i++) {
+ sync_level_t* slot;
- slot = sync_thread_levels_get_nth(array, i);
+ slot = &array->elems[i];
- if (slot->latch == latch) {
- slot->latch = NULL;
+ if (slot->latch != latch) {
+ continue;
+ }
- mutex_exit(&sync_thread_mutex);
+ slot->latch = NULL;
- return(TRUE);
+ /* Update the free slot list. See comment in sync_level_t
+ for the level field. */
+ slot->level = array->next_free;
+ array->next_free = i;
+
+ ut_a(array->in_use >= 1);
+ --array->in_use;
+
+ /* If all cells are idle then reset the free
+ list. The assumption is that this will save
+ time when we need to scan up to n_elems. */
+
+ if (array->in_use == 0) {
+ array->n_elems = 0;
+ array->next_free = ULINT_UNDEFINED;
}
+
+ mutex_exit(&sync_thread_mutex);
+
+ return(TRUE);
}
if (((mutex_t*) latch)->magic_n != MUTEX_MAGIC_N) {
@@ -1403,11 +1421,6 @@ void
sync_init(void)
/*===========*/
{
-#ifdef UNIV_SYNC_DEBUG
- sync_thread_t* thread_slot;
- ulint i;
-#endif /* UNIV_SYNC_DEBUG */
-
ut_a(sync_initialized == FALSE);
sync_initialized = TRUE;
@@ -1421,13 +1434,10 @@ sync_init(void)
/* Create the thread latch level array where the latch levels
are stored for each OS thread */
- sync_thread_level_arrays = ut_malloc(OS_THREAD_MAX_N
- * sizeof(sync_thread_t));
- for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ sync_thread_level_arrays = calloc(
+ sizeof(sync_thread_t), OS_THREAD_MAX_N);
+ ut_a(sync_thread_level_arrays != NULL);
- thread_slot = sync_thread_level_arrays_get_nth(i);
- thread_slot->levels = NULL;
- }
#endif /* UNIV_SYNC_DEBUG */
/* Init the mutex list and create the mutex to protect it. */
@@ -1454,6 +1464,34 @@ sync_init(void)
#endif /* UNIV_SYNC_DEBUG */
}
+#ifdef UNIV_SYNC_DEBUG
+/******************************************************************//**
+Frees all debug memory. */
+static
+void
+sync_thread_level_arrays_free(void)
+/*===============================*/
+
+{
+ ulint i;
+
+ for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ sync_thread_t* slot;
+
+ slot = &sync_thread_level_arrays[i];
+
+ /* If this slot was allocated then free the slot memory too. */
+ if (slot->levels != NULL) {
+ free(slot->levels);
+ slot->levels = NULL;
+ }
+ }
+
+ free(sync_thread_level_arrays);
+ sync_thread_level_arrays = NULL;
+}
+#endif /* UNIV_SYNC_DEBUG */
+
/******************************************************************//**
Frees the resources in InnoDB's own synchronization data structures. Use
os_sync_free() after calling this. */
@@ -1466,17 +1504,20 @@ sync_close(void)
sync_array_free(sync_primary_wait_array);
- mutex = UT_LIST_GET_FIRST(mutex_list);
+ for (mutex = UT_LIST_GET_FIRST(mutex_list);
+ mutex != NULL;
+ /* No op */) {
- while (mutex) {
#ifdef UNIV_MEM_DEBUG
if (mutex == &mem_hash_mutex) {
mutex = UT_LIST_GET_NEXT(list, mutex);
continue;
}
#endif /* UNIV_MEM_DEBUG */
+
mutex_free(mutex);
- mutex = UT_LIST_GET_FIRST(mutex_list);
+
+ mutex = UT_LIST_GET_FIRST(mutex_list);
}
mutex_free(&mutex_list_mutex);
@@ -1485,6 +1526,8 @@ sync_close(void)
/* Switch latching order checks on in sync0sync.c */
sync_order_checks_on = FALSE;
+
+ sync_thread_level_arrays_free();
#endif /* UNIV_SYNC_DEBUG */
sync_initialized = FALSE;
diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c
index 876a00fb935..f9d421e3705 100644
--- a/storage/innobase/trx/trx0roll.c
+++ b/storage/innobase/trx/trx0roll.c
@@ -47,8 +47,8 @@ Created 3/26/1996 Heikki Tuuri
rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
-/** In crash recovery, the current trx to be rolled back */
-static trx_t* trx_roll_crash_recv_trx = NULL;
+/** In crash recovery, the current trx to be rolled back; NULL otherwise */
+static const trx_t* trx_roll_crash_recv_trx = NULL;
/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 7f2ca1f1471..4bbcee210b0 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -2004,18 +2004,18 @@ trx_recover_for_mysql(
/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
which is in the prepared state
-@return trx or NULL */
+@return trx or NULL; on match, the trx->xid will be invalidated */
UNIV_INTERN
trx_t*
trx_get_trx_by_xid(
/*===============*/
- XID* xid) /*!< in: X/Open XA transaction identification */
+ const XID* xid) /*!< in: X/Open XA transaction identifier */
{
trx_t* trx;
if (xid == NULL) {
- return (NULL);
+ return(NULL);
}
mutex_enter(&kernel_mutex);
@@ -2028,10 +2028,16 @@ trx_get_trx_by_xid(
of gtrid_length+bqual_length bytes should be
the same */
- if (xid->gtrid_length == trx->xid.gtrid_length
+ if (trx->conc_state == TRX_PREPARED
+ && xid->gtrid_length == trx->xid.gtrid_length
&& xid->bqual_length == trx->xid.bqual_length
&& memcmp(xid->data, trx->xid.data,
xid->gtrid_length + xid->bqual_length) == 0) {
+
+ /* Invalidate the XID, so that subsequent calls
+ will not find it. */
+ memset(&trx->xid, 0, sizeof(trx->xid));
+ trx->xid.formatID = -1;
break;
}
@@ -2040,14 +2046,5 @@ trx_get_trx_by_xid(
mutex_exit(&kernel_mutex);
- if (trx) {
- if (trx->conc_state != TRX_PREPARED) {
-
- return(NULL);
- }
-
- return(trx);
- } else {
- return(NULL);
- }
+ return(trx);
}
diff --git a/strings/bchange.c b/strings/bchange.c
index 0b2c62019b5..45eabacb767 100644
--- a/strings/bchange.c
+++ b/strings/bchange.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/bmove_upp.c b/strings/bmove_upp.c
index 05e786837f4..d466b69face 100644
--- a/strings/bmove_upp.c
+++ b/strings/bmove_upp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c
index 73ade93f6e1..fce7f01d9ed 100644
--- a/strings/conf_to_src.c
+++ b/strings/conf_to_src.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -252,7 +252,7 @@ static void
fprint_copyright(FILE *file)
{
fprintf(file,
-"/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n"
+"/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.\n"
"\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 3007d76a5a4..ddc32099b71 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 3b6a977e47c..ed674da6438 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index df4083c9f8d..157faf888c0 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index 0095fe7f995..5af431c8188 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index 7329f9ec09a..e36e7cf7a26 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c
index 6180e0e1a7a..ad4ac84eacd 100644
--- a/strings/ctype-eucjpms.c
+++ b/strings/ctype-eucjpms.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c
index f89a45d6ed8..f88cdd421d3 100644
--- a/strings/ctype-extra.c
+++ b/strings/ctype-extra.c
@@ -6,7 +6,7 @@
./conf_to_src ../sql/share/charsets/ > FILE
*/
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index b1acd643df3..9314e43b7ea 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index 547c8821229..a18c4b41721 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c
index dbd91c09637..dc64859fa32 100644
--- a/strings/ctype-latin1.c
+++ b/strings/ctype-latin1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 8b985b7405b..53529679c11 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 2e5f78a30bf..bea56143807 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 91adf4ebddf..0c26d9df316 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index 14b661ab0fc..92d6258a902 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 2f7bf030d90..4228d9dfd2e 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index 67be793c3dc..bc0e08da1ff 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 9f4d032ffe0..9f24607c88a 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index 324f6b9aafb..f3921d22f4b 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c
index d9d092beb8f..50eda71a82c 100644
--- a/strings/ctype-win1250ch.c
+++ b/strings/ctype-win1250ch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 MySQL AB
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype.c b/strings/ctype.c
index 4891e657b6e..d624c758148 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/do_ctype.c b/strings/do_ctype.c
index f87d55b6251..9bdbd3d27eb 100644
--- a/strings/do_ctype.c
+++ b/strings/do_ctype.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/dtoa.c b/strings/dtoa.c
index d64c420b499..59aa056df9c 100644
--- a/strings/dtoa.c
+++ b/strings/dtoa.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007 MySQL AB
+/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/dump_map.c b/strings/dump_map.c
index e2b8b7db077..60bd91541c4 100644
--- a/strings/dump_map.c
+++ b/strings/dump_map.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003-2004 MySQL AB
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/int2str.c b/strings/int2str.c
index ecc214d58d5..553de0f3b45 100644
--- a/strings/int2str.c
+++ b/strings/int2str.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/is_prefix.c b/strings/is_prefix.c
index 451cd468b7e..370927a24cd 100644
--- a/strings/is_prefix.c
+++ b/strings/is_prefix.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/llstr.c b/strings/llstr.c
index 643cf36a311..283af4795dc 100644
--- a/strings/llstr.c
+++ b/strings/llstr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/longlong2str.c b/strings/longlong2str.c
index 641ae0955d3..21027a0ee9a 100644
--- a/strings/longlong2str.c
+++ b/strings/longlong2str.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/my_strchr.c b/strings/my_strchr.c
index 08fa51ba17a..35f39d563c5 100644
--- a/strings/my_strchr.c
+++ b/strings/my_strchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c
index b9fc4b4be8e..5263abb335c 100644
--- a/strings/my_strtoll10.c
+++ b/strings/my_strtoll10.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 MySQL AB
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index e9786dacfdc..9f425a1db4d 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/str2int.c b/strings/str2int.c
index c4a4c07eeff..7cf49982d76 100644
--- a/strings/str2int.c
+++ b/strings/str2int.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/str_alloc.c b/strings/str_alloc.c
index 615ad1ba1e2..fdf32b8ee15 100644
--- a/strings/str_alloc.c
+++ b/strings/str_alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strappend.c b/strings/strappend.c
index bb926f74665..e81a4d4301e 100644
--- a/strings/strappend.c
+++ b/strings/strappend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strcend.c b/strings/strcend.c
index e08ad2b1e75..c48f695cfd6 100644
--- a/strings/strcend.c
+++ b/strings/strcend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strcont.c b/strings/strcont.c
index 5a518a3550f..ddf8f2c838f 100644
--- a/strings/strcont.c
+++ b/strings/strcont.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strend.c b/strings/strend.c
index d70a5d648d5..c38502bd55c 100644
--- a/strings/strend.c
+++ b/strings/strend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/strfill.c b/strings/strfill.c
index 4b1fe67b206..12d227f5805 100644
--- a/strings/strfill.c
+++ b/strings/strfill.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strmake.c b/strings/strmake.c
index 2d5fa5e36aa..296199b90be 100644
--- a/strings/strmake.c
+++ b/strings/strmake.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strmov.c b/strings/strmov.c
index 4d4915d27a0..6444f080430 100644
--- a/strings/strmov.c
+++ b/strings/strmov.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strnlen.c b/strings/strnlen.c
index 826cd5ae5dd..7c8f3c4a54e 100644
--- a/strings/strnlen.c
+++ b/strings/strnlen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strnmov.c b/strings/strnmov.c
index 7e26877637b..a826233bb17 100644
--- a/strings/strnmov.c
+++ b/strings/strnmov.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/strxmov.c b/strings/strxmov.c
index 9dd2c936620..c0b2449e66a 100644
--- a/strings/strxmov.c
+++ b/strings/strxmov.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/strxnmov.c b/strings/strxnmov.c
index 16469be6e45..dac6eab5d63 100644
--- a/strings/strxnmov.c
+++ b/strings/strxnmov.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 MySQL AB
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/uca-dump.c b/strings/uca-dump.c
index 774e940c7da..3ba78163c2f 100644
--- a/strings/uca-dump.c
+++ b/strings/uca-dump.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/uctypedump.c b/strings/uctypedump.c
index 2e484604fd3..5b902843ee1 100644
--- a/strings/uctypedump.c
+++ b/strings/uctypedump.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 MySQL AB
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/utr11-dump.c b/strings/utr11-dump.c
index a15f63025f4..adbbdda1169 100644
--- a/strings/utr11-dump.c
+++ b/strings/utr11-dump.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 MySQL AB
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/xml.c b/strings/xml.c
index dee9da2864c..29ce74e36a0 100644
--- a/strings/xml.c
+++ b/strings/xml.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index aa861609a5f..1ee9a234f8b 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -1,4 +1,4 @@
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -523,10 +523,27 @@ rm -f $RBR%{_mandir}/man1/make_win_bin_dist.1*
##############################################################################
%pre -n MySQL-server%{product_suffix}
+# This is the code running at the beginning of a RPM upgrade action,
+# before replacing the old files with the new ones.
# ATTENTION: Parts of this are duplicated in the "triggerpostun" !
-mysql_datadir=%{mysqldatadir}
+# There are users who deviate from the default file system layout.
+# Check local settings to support them.
+if [ -x %{_bindir}/my_print_defaults ]
+then
+ mysql_datadir=`%{_bindir}/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p'`
+ PID_FILE_PATT=`%{_bindir}/my_print_defaults server mysqld | grep '^--pid-file=' | sed -n 's/--pid-file=//p'`
+fi
+if [ -z "$mysql_datadir" ]
+then
+ mysql_datadir=%{mysqldatadir}
+fi
+if [ -z "$PID_FILE_PATT" ]
+then
+ PID_FILE_PATT="$mysql_datadir/*.pid"
+fi
+
# Check if we can safely upgrade. An upgrade is only safe if it's from one
# of our RPMs in the same version family.
@@ -601,7 +618,7 @@ fi
# We assume that if there is exactly one ".pid" file,
# it contains the valid PID of a running MySQL server.
-NR_PID_FILES=`ls $mysql_datadir/*.pid 2>/dev/null | wc -l`
+NR_PID_FILES=`ls $PID_FILE_PATT 2>/dev/null | wc -l`
case $NR_PID_FILES in
0 ) SERVER_TO_START='' ;; # No "*.pid" file == no running server
1 ) SERVER_TO_START='true' ;;
@@ -623,8 +640,8 @@ if [ -f $STATUS_FILE ]; then
echo "before repeating the MySQL upgrade."
exit 1
elif [ -n "$SEVERAL_PID_FILES" ] ; then
- echo "Your MySQL directory '$mysql_datadir' has more than one PID file:"
- ls -ld $mysql_datadir/*.pid
+ echo "You have more than one PID file:"
+ ls -ld $PID_FILE_PATT
echo "Please check which one (if any) corresponds to a running server"
echo "and delete all others before repeating the MySQL upgrade."
exit 1
@@ -649,17 +666,17 @@ if [ -d $mysql_datadir ] ; then
if [ -n "$SERVER_TO_START" ] ; then
# There is only one PID file, race possibility ignored
echo "PID file:" >> $STATUS_FILE
- ls -l $mysql_datadir/*.pid >> $STATUS_FILE
- cat $mysql_datadir/*.pid >> $STATUS_FILE
+ ls -l $PID_FILE_PATT >> $STATUS_FILE
+ cat $PID_FILE_PATT >> $STATUS_FILE
echo >> $STATUS_FILE
echo "Server process:" >> $STATUS_FILE
- ps -fp `cat $mysql_datadir/*.pid` >> $STATUS_FILE
+ ps -fp `cat $PID_FILE_PATT` >> $STATUS_FILE
echo >> $STATUS_FILE
echo "SERVER_TO_START=$SERVER_TO_START" >> $STATUS_FILE
else
# Take a note we checked it ...
echo "PID file:" >> $STATUS_FILE
- ls -l $mysql_datadir/*.pid >> $STATUS_FILE 2>&1
+ ls -l $PID_FILE_PATT >> $STATUS_FILE 2>&1
fi
fi
@@ -674,10 +691,22 @@ if [ -x %{_sysconfdir}/init.d/mysql ] ; then
fi
%post -n MySQL-server%{product_suffix}
+# This is the code running at the end of a RPM install or upgrade action,
+# after the (new) files have been written.
# ATTENTION: Parts of this are duplicated in the "triggerpostun" !
-mysql_datadir=%{mysqldatadir}
+# There are users who deviate from the default file system layout.
+# Check local settings to support them.
+if [ -x %{_bindir}/my_print_defaults ]
+then
+ mysql_datadir=`%{_bindir}/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p'`
+fi
+if [ -z "$mysql_datadir" ]
+then
+ mysql_datadir=%{mysqldatadir}
+fi
+
NEW_VERSION=%{mysql_version}-%{release}
STATUS_FILE=$mysql_datadir/RPM_UPGRADE_MARKER
@@ -855,7 +884,17 @@ fi
# http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s02.html
# For all details of this code, see the "pre" and "post" sections.
-mysql_datadir=%{mysqldatadir}
+# There are users who deviate from the default file system layout.
+# Check local settings to support them.
+if [ -x %{_bindir}/my_print_defaults ]
+then
+ mysql_datadir=`%{_bindir}/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p'`
+fi
+if [ -z "$mysql_datadir" ]
+then
+ mysql_datadir=%{mysqldatadir}
+fi
+
NEW_VERSION=%{mysql_version}-%{release}
STATUS_FILE=$mysql_datadir/RPM_UPGRADE_MARKER-LAST # Note the difference!
STATUS_HISTORY=$mysql_datadir/RPM_UPGRADE_HISTORY
@@ -1085,6 +1124,14 @@ echo "=====" >> $STATUS_HISTORY
# merging BK trees)
##############################################################################
%changelog
+
+* Thu Feb 09 2011 Joerg Bruehe <joerg.bruehe@oracle.com>
+
+- Fix bug#56581: If an installation deviates from the default file locations
+ ("datadir" and "pid-file"), the mechanism to detect a running server (on upgrade)
+ should still work, and use these locations.
+ The problem was that the fix for bug#27072 did not check for local settings.
+
* Tue Nov 23 2010 Jonathan Perkin <jonathan.perkin@oracle.com>
- EXCEPTIONS-CLIENT has been deleted, remove it from here too