summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--BUILD/Makefile.am18
-rw-r--r--client/mysql.cc2
-rw-r--r--client/mysqltest.c8
-rw-r--r--configure.in15
-rw-r--r--extra/comp_err.c4
-rw-r--r--heap/hp_create.c1
-rw-r--r--include/config-netware.h3
-rw-r--r--include/hash.h14
-rw-r--r--include/heap.h1
-rw-r--r--include/sha1.h6
-rw-r--r--innobase/btr/btr0sea.c41
-rw-r--r--innobase/dict/dict0dict.c3
-rw-r--r--innobase/fil/fil0fil.c103
-rw-r--r--innobase/include/btr0sea.ic2
-rw-r--r--innobase/include/os0file.h5
-rw-r--r--innobase/os/os0file.c8
-rw-r--r--innobase/os/os0thread.c9
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--libmysql/libmysql.c8
-rw-r--r--libmysql/libmysql.ver.in1
-rwxr-xr-xlibmysqld/ha_blackhole.cc0
-rw-r--r--myisam/ft_update.c4
-rw-r--r--myisam/mi_delete.c2
-rw-r--r--mysql-test/include/have_euckr.inc4
-rw-r--r--mysql-test/include/have_gb2312.inc4
-rw-r--r--mysql-test/r/create.result20
-rw-r--r--mysql-test/r/ctype_euckr.result167
-rw-r--r--mysql-test/r/ctype_gb2312.result167
-rw-r--r--mysql-test/r/ctype_ucs.result26
-rw-r--r--mysql-test/r/ctype_utf8.result8
-rw-r--r--mysql-test/r/date_formats.result9
-rw-r--r--mysql-test/r/fulltext.result11
-rw-r--r--mysql-test/r/fulltext2.result26
-rw-r--r--mysql-test/r/func_gconcat.result6
-rw-r--r--mysql-test/r/grant.result9
-rw-r--r--mysql-test/r/grant2.result12
-rw-r--r--mysql-test/r/have_euckr.require2
-rw-r--r--mysql-test/r/have_gb2312.require2
-rw-r--r--mysql-test/r/having.result13
-rw-r--r--mysql-test/r/heap.result12
-rw-r--r--mysql-test/r/heap_hash.result20
-rw-r--r--mysql-test/r/innodb.result53
-rw-r--r--mysql-test/r/kill.result14
-rw-r--r--mysql-test/r/merge.result49
-rw-r--r--mysql-test/r/myisam.result2
-rw-r--r--mysql-test/r/ndb_blob.result7
-rw-r--r--mysql-test/r/ndb_load.result80
-rw-r--r--mysql-test/r/ndb_multi.result1
-rw-r--r--mysql-test/r/ps.result53
-rw-r--r--mysql-test/r/rpl_ignore_table.result16
-rw-r--r--mysql-test/r/rpl_multi_update4.result25
-rw-r--r--mysql-test/r/subselect.result6
-rw-r--r--mysql-test/r/type_float.result22
-rw-r--r--mysql-test/r/update.result19
-rw-r--r--mysql-test/t/create.test14
-rw-r--r--mysql-test/t/ctype_euckr.test33
-rw-r--r--mysql-test/t/ctype_gb2312.test33
-rw-r--r--mysql-test/t/ctype_ucs.test24
-rw-r--r--mysql-test/t/ctype_utf8.test10
-rw-r--r--mysql-test/t/date_formats.test7
-rw-r--r--mysql-test/t/disabled.def1
-rw-r--r--mysql-test/t/fulltext.test12
-rw-r--r--mysql-test/t/fulltext2.test38
-rw-r--r--mysql-test/t/func_math.test2
-rw-r--r--mysql-test/t/grant.test12
-rw-r--r--mysql-test/t/grant2.test33
-rw-r--r--mysql-test/t/having.test12
-rw-r--r--mysql-test/t/heap.test11
-rw-r--r--mysql-test/t/innodb.test49
-rw-r--r--mysql-test/t/kill.test49
-rw-r--r--mysql-test/t/merge.test26
-rw-r--r--mysql-test/t/ndb_blob.test6
-rw-r--r--mysql-test/t/ndb_load.test24
-rw-r--r--mysql-test/t/ndb_multi.test1
-rw-r--r--mysql-test/t/ps.test43
-rw-r--r--mysql-test/t/rpl_ignore_table-slave.opt1
-rw-r--r--mysql-test/t/rpl_ignore_table.test28
-rw-r--r--mysql-test/t/rpl_multi_update4-slave.opt1
-rw-r--r--mysql-test/t/rpl_multi_update4.test44
-rw-r--r--mysql-test/t/symlink.test2
-rw-r--r--mysql-test/t/type_float.test17
-rw-r--r--mysql-test/t/type_time.test18
-rw-r--r--mysql-test/t/update.test19
-rw-r--r--mysys/hash.c60
-rw-r--r--mysys/sha1.c16
-rw-r--r--mysys/testhash.c9
-rw-r--r--ndb/include/logger/LogHandler.hpp13
-rw-r--r--ndb/include/logger/Logger.hpp5
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters.h5
-rw-r--r--ndb/src/common/logger/FileLogHandler.cpp17
-rw-r--r--ndb/src/common/logger/LogHandler.cpp29
-rw-r--r--ndb/src/common/logger/Logger.cpp11
-rw-r--r--ndb/src/common/logger/SysLogHandler.cpp1
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp2
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp14
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp30
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp2
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp14
-rw-r--r--ndb/src/ndbapi/NdbBlob.cpp2
-rw-r--r--ndb/test/ndbapi/testBlobs.cpp100
-rw-r--r--ndb/tools/delete_all.cpp30
-rwxr-xr-xndb/tools/ndb_error_reporter88
-rw-r--r--ndb/tools/ndb_size.pl6
-rw-r--r--netware/mysqld_safe.c12
-rw-r--r--scripts/make_win_src_distribution.sh4
-rw-r--r--scripts/mysqld_multi.sh3
-rw-r--r--sql-common/my_time.c28
-rw-r--r--sql/field.cc6
-rw-r--r--sql/ha_heap.cc62
-rw-r--r--sql/ha_heap.h4
-rw-r--r--sql/ha_innodb.cc131
-rw-r--r--sql/ha_ndbcluster.cc25
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/item_cmpfunc.h1
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/item_strfunc.cc8
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/lock.cc94
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/mysqld.cc12
-rw-r--r--sql/password.c46
-rw-r--r--sql/protocol.cc18
-rw-r--r--sql/spatial.h2
-rw-r--r--sql/sql_acl.cc30
-rw-r--r--sql/sql_base.cc44
-rw-r--r--sql/sql_cache.cc10
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_db.cc13
-rw-r--r--sql/sql_handler.cc46
-rw-r--r--sql/sql_load.cc7
-rw-r--r--sql/sql_parse.cc26
-rw-r--r--sql/sql_select.cc37
-rw-r--r--sql/sql_select.h11
-rw-r--r--sql/sql_table.cc1
-rw-r--r--sql/sql_update.cc16
-rw-r--r--strings/ctype-euc_kr.c37
-rw-r--r--strings/ctype-gb2312.c37
-rw-r--r--strings/ctype-ucs2.c41
-rw-r--r--tests/mysql_client_test.c117
-rw-r--r--zlib/Makefile.am2
142 files changed, 2700 insertions, 409 deletions
diff --git a/.bzrignore b/.bzrignore
index d8be10eacdb..414a40ef1eb 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1057,3 +1057,4 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
+libmysql/libmysql.ver
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
index 4e27ffd5e7f..b43be5c3bdc 100644
--- a/BUILD/Makefile.am
+++ b/BUILD/Makefile.am
@@ -20,14 +20,22 @@
EXTRA_DIST = FINISH.sh \
SETUP.sh \
check-cpu \
+ cleanup \
compile-alpha \
compile-alpha-ccc \
compile-alpha-cxx \
compile-alpha-debug \
+ compile-amd64-debug-max \
+ compile-amd64-max \
+ compile-darwin-mwcc \
+ compile-dist \
+ compile-hpux11-parisc2-aCC \
compile-ia64-debug-max \
+ compile-irix-mips64-mipspro \
compile-pentium \
compile-pentium-debug \
compile-pentium-debug-max \
+ compile-pentium-debug-max-no-embedded \
compile-pentium-debug-no-bdb \
compile-pentium-debug-openssl \
compile-pentium-gcov \
@@ -36,10 +44,16 @@ EXTRA_DIST = FINISH.sh \
compile-pentium-myodbc \
compile-pentium-mysqlfs-debug \
compile-pentium-pgcc \
+ compile-pentium-valgrind-max \
+ compile-pentium64-debug \
+ compile-pentium64-debug-max \
+ compile-pentium64-valgrind-max \
+ compile-ppc \
+ compile-ppc-debug \
+ compile-ppc-debug-max \
+ compile-ppc-max \
compile-solaris-sparc \
compile-solaris-sparc-debug \
- compile-irix-mips64-mipspro \
- compile-hpux11-parisc2-aCC \
compile-solaris-sparc-forte \
compile-solaris-sparc-purify
diff --git a/client/mysql.cc b/client/mysql.cc
index 14a27413687..d76195535a3 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -254,7 +254,7 @@ static COMMANDS commands[] = {
{ "quit", 'q', com_quit, 0, "Quit mysql." },
{ "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
{ "source", '.', com_source, 1,
- "Execute a SQL script file. Takes a file name as an argument."},
+ "Execute an SQL script file. Takes a file name as an argument."},
{ "status", 's', com_status, 0, "Get status information from the server."},
#ifdef USE_POPEN
{ "system", '!', com_shell, 1, "Execute a system shell command."},
diff --git a/client/mysqltest.c b/client/mysqltest.c
index d10ad054798..613c4e12763 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -2966,8 +2966,8 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
warn_res= mysql_store_result(mysql);
}
if (!warn_res)
- verbose_msg("Warning count is %u but didn't get any warnings\n",
- count);
+ die("Warning count is %u but didn't get any warnings\n",
+ count);
else
{
dynstr_append_mem(ds, "Warnings:\n", 10);
@@ -3446,8 +3446,8 @@ static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds)
{
MYSQL_RES *warn_res= mysql_store_result(mysql);
if (!warn_res)
- verbose_msg("Warning count is %u but didn't get any warnings\n",
- count);
+ die("Warning count is %u but didn't get any warnings\n",
+ count);
else
{
dynstr_append_mem(ds, "Warnings:\n", 10);
diff --git a/configure.in b/configure.in
index 9afd2034796..b230b7f042e 100644
--- a/configure.in
+++ b/configure.in
@@ -5,18 +5,19 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 4.1.17)
+AM_INIT_AUTOMAKE(mysql, 4.1.19)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
-SHARED_LIB_VERSION=14:0:0
+SHARED_LIB_MAJOR_VERSION=14
+SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=4
NDB_VERSION_MINOR=1
-NDB_VERSION_BUILD=17
+NDB_VERSION_BUILD=19
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -68,6 +69,7 @@ AC_DEFINE_UNQUOTED([PROTOCOL_VERSION], [$PROTOCOL_VERSION],
AC_SUBST(DOT_FRM_VERSION)
AC_DEFINE_UNQUOTED([DOT_FRM_VERSION], [$DOT_FRM_VERSION],
[Version of .frm files])
+AC_SUBST(SHARED_LIB_MAJOR_VERSION)
AC_SUBST(SHARED_LIB_VERSION)
AC_SUBST(AVAILABLE_LANGUAGES)
AC_SUBST(AVAILABLE_LANGUAGES_ERRORS)
@@ -431,6 +433,13 @@ then
fi
fi
+# libmysqlclient versioning when linked with GNU ld.
+if $LD --version 2>/dev/null|grep -q GNU; then
+ LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_builddir)/libmysql/libmysql.ver"
+ AC_CONFIG_FILES(libmysql/libmysql.ver)
+fi
+AC_SUBST(LD_VERSION_SCRIPT)
+
# Avoid bug in fcntl on some versions of linux
AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
# Any wariation of Linux
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 6c7fad6a270..f47c8a1beca 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -159,7 +159,9 @@ static void get_options(register int *argc,register char **argv[])
case 'I':
case '?':
printf(" %s (Compile errormessage) Ver 1.3\n",progname);
- puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. "
+ "This is free software,\n"
+ "and you are welcome to modify and redistribute it under the GPL license.\n");
printf("Usage: %s [-?] [-I] [-V] fromfile[s] tofile\n",progname);
puts("Options: -Info -Version\n");
help=1;
diff --git a/heap/hp_create.c b/heap/hp_create.c
index 2b811dac89b..acd4447fe5c 100644
--- a/heap/hp_create.c
+++ b/heap/hp_create.c
@@ -104,6 +104,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
DBUG_RETURN(1);
}
share->keydef= (HP_KEYDEF*) (share + 1);
+ share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys);
init_block(&share->block, reclength + 1, min_records, max_records);
/* Fix keys */
diff --git a/include/config-netware.h b/include/config-netware.h
index 74b3c3720e9..503c8bbef67 100644
--- a/include/config-netware.h
+++ b/include/config-netware.h
@@ -92,6 +92,9 @@ extern "C" {
/* On NetWare, stack grows towards lower address*/
#define STACK_DIRECTION -1
+/* On NetWare, we need to set stack size for threads, otherwise default 16K is used */
+#define NW_THD_STACKSIZE 65536
+
/* On NetWare, to fix the problem with the deletion of open files */
#define CANT_DELETE_OPEN_FILES 1
diff --git a/include/hash.h b/include/hash.h
index 9a6d91036e1..8f5ff21ae5e 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *);
typedef struct st_hash {
uint key_offset,key_length; /* Length of key if const length */
- uint records,blength,current_record;
+ uint records, blength;
uint flags;
DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key;
@@ -41,6 +41,9 @@ typedef struct st_hash {
CHARSET_INFO *charset;
} HASH;
+/* A search iterator state */
+typedef uint HASH_SEARCH_STATE;
+
#define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)
my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint default_array_elements, uint key_offset,
@@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
void hash_free(HASH *tree);
void my_hash_reset(HASH *hash);
byte *hash_element(HASH *hash,uint idx);
-gptr hash_search(HASH *info,const byte *key,uint length);
-gptr hash_next(HASH *info,const byte *key,uint length);
+gptr hash_search(const HASH *info, const byte *key, uint length);
+gptr hash_first(const HASH *info, const byte *key, uint length,
+ HASH_SEARCH_STATE *state);
+gptr hash_next(const HASH *info, const byte *key, uint length,
+ HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info,const byte *data);
my_bool hash_delete(HASH *hash,byte *record);
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
-void hash_replace(HASH *hash, uint idx, byte *new_row);
+void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
diff --git a/include/heap.h b/include/heap.h
index badec9ce2ef..cfbb6113f86 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -136,6 +136,7 @@ typedef struct st_heap_share
HP_KEYDEF *keydef;
ulong min_records,max_records; /* Params to open */
ulong data_length,index_length,max_table_size;
+ uint key_stat_version; /* version to indicate insert/delete */
uint records; /* records */
uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */
diff --git a/include/sha1.h b/include/sha1.h
index 1c345469d3c..e67acbf96b8 100644
--- a/include/sha1.h
+++ b/include/sha1.h
@@ -60,8 +60,8 @@ typedef struct SHA1_CONTEXT
C_MODE_START
-int sha1_reset( SHA1_CONTEXT* );
-int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int );
-int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] );
+int mysql_sha1_reset(SHA1_CONTEXT*);
+int mysql_sha1_input(SHA1_CONTEXT*, const uint8 *, unsigned int);
+int mysql_sha1_result(SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE]);
C_MODE_END
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 9384168df88..c7da695859b 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -191,7 +191,7 @@ static
void
btr_search_info_update_hash(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
{
dict_index_t* index;
@@ -443,7 +443,7 @@ Updates the search info. */
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor) /* in: cursor which was just positioned */
{
buf_block_t* block;
@@ -931,7 +931,7 @@ btr_search_drop_page_hash_index(
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
-
+retry:
rw_lock_s_lock(&btr_search_latch);
block = buf_block_align(page);
@@ -1007,6 +1007,24 @@ next_rec:
rw_lock_x_lock(&btr_search_latch);
+ if (!block->is_hashed) {
+ /* Someone else has meanwhile dropped the hash index */
+
+ goto cleanup;
+ }
+
+ if (block->curr_n_fields != n_fields
+ || block->curr_n_bytes != n_bytes) {
+
+ /* Someone else has meanwhile built a new hash index on the
+ page, with different parameters */
+
+ rw_lock_x_unlock(&btr_search_latch);
+
+ mem_free(folds);
+ goto retry;
+ }
+
for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page);
@@ -1014,7 +1032,22 @@ next_rec:
block->is_hashed = FALSE;
- rw_lock_x_unlock(&btr_search_latch);
+cleanup:
+ if (block->n_pointers) {
+ /* Corruption */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Corruption of adaptive hash index. After dropping\n"
+"InnoDB: the hash index to a page of %lu %lu, still %lu hash nodes remain.\n",
+ (ulong) ut_dulint_get_high(tree_id),
+ (ulong) ut_dulint_get_low(tree_id),
+ (ulong) block->n_pointers);
+ rw_lock_x_unlock(&btr_search_latch);
+
+ btr_search_validate();
+ } else {
+ rw_lock_x_unlock(&btr_search_latch);
+ }
mem_free(folds);
}
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 0cdd593b678..093df5118af 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -2755,7 +2755,8 @@ dict_table_get_highest_foreign_id(
if (ut_strlen(foreign->id) > ((sizeof dict_ibfk) - 1) + len
&& 0 == ut_memcmp(foreign->id, table->name, len)
&& 0 == ut_memcmp(foreign->id + len,
- dict_ibfk, (sizeof dict_ibfk) - 1)) {
+ dict_ibfk, (sizeof dict_ibfk) - 1)
+ && foreign->id[len + ((sizeof dict_ibfk) - 1)] != '0') {
/* It is of the >= 4.0.18 format */
id = strtoul(foreign->id + len + ((sizeof dict_ibfk) - 1),
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index e83d2fcde32..c696c940790 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -179,6 +179,11 @@ struct fil_space_struct {
hash_node_t name_hash;/* hash chain the name_hash table */
rw_lock_t latch; /* latch protecting the file space storage
allocation */
+ UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
+ /* list of spaces with at least one unflushed
+ file we have written to */
+ ibool is_in_unflushed_spaces; /* TRUE if this space is
+ currently in the list above */
UT_LIST_NODE_T(fil_space_t) space_list;
/* list of all spaces */
ibuf_data_t* ibuf_data;
@@ -211,6 +216,12 @@ struct fil_system_struct {
not put to this list: they are opened
after the startup, and kept open until
shutdown */
+ UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
+ /* base node for the list of those
+ tablespaces whose files contain
+ unflushed writes; those spaces have
+ at least one file node where
+ modification_counter > flush_counter */
ulint n_open; /* number of files currently open */
ulint max_n_open; /* n_open is not allowed to exceed
this */
@@ -387,6 +398,36 @@ fil_space_get_ibuf_data(
return(space->ibuf_data);
}
+/**************************************************************************
+Checks if all the file nodes in a space are flushed. The caller must hold
+the fil_system mutex. */
+static
+ibool
+fil_space_is_flushed(
+/*=================*/
+ /* out: TRUE if all are flushed */
+ fil_space_t* space) /* in: space */
+{
+ fil_node_t* node;
+
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&(fil_system->mutex)));
+#endif /* UNIV_SYNC_DEBUG */
+
+ node = UT_LIST_GET_FIRST(space->chain);
+
+ while (node) {
+ if (node->modification_counter > node->flush_counter) {
+
+ return(FALSE);
+ }
+
+ node = UT_LIST_GET_NEXT(chain, node);
+ }
+
+ return(TRUE);
+}
+
/***********************************************************************
Appends a new file to the chain of files of a space. File must be closed. */
@@ -517,7 +558,7 @@ fil_node_open_file(
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace file %s\n"
-"InnoDB: is only %lu %lu, should be at least %lu!", node->name,
+"InnoDB: is only %lu %lu, should be at least %lu!\n", node->name,
(ulong) size_high,
(ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE));
@@ -687,8 +728,8 @@ fil_try_to_close_file_in_LRU(
ut_print_filename(stderr, node->name);
fprintf(stderr,
", because mod_count %ld != fl_count %ld\n",
- (ulong) node->modification_counter,
- (ulong) node->flush_counter);
+ (long) node->modification_counter,
+ (long) node->flush_counter);
}
node = UT_LIST_GET_PREV(LRU, node);
@@ -839,6 +880,16 @@ fil_node_free(
node->modification_counter = node->flush_counter;
+ if (space->is_in_unflushed_spaces
+ && fil_space_is_flushed(space)) {
+
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces,
+ system->unflushed_spaces,
+ space);
+ }
+
fil_node_close_file(node, system);
}
@@ -1002,6 +1053,8 @@ try_again:
HASH_INSERT(fil_space_t, name_hash, system->name_hash,
ut_fold_string(name), space);
+ space->is_in_unflushed_spaces = FALSE;
+
UT_LIST_ADD_LAST(space_list, system->space_list, space);
mutex_exit(&(system->mutex));
@@ -1097,6 +1150,13 @@ fil_space_free(
HASH_DELETE(fil_space_t, name_hash, system->name_hash,
ut_fold_string(space->name), space);
+ if (space->is_in_unflushed_spaces) {
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
+ space);
+ }
+
UT_LIST_REMOVE(space_list, system->space_list, space);
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
@@ -1248,6 +1308,7 @@ fil_system_create(
system->tablespace_version = 0;
+ UT_LIST_INIT(system->unflushed_spaces);
UT_LIST_INIT(system->space_list);
return(system);
@@ -2612,12 +2673,12 @@ fil_open_single_table_tablespace(
fputs("!\n"
"InnoDB: Have you moved InnoDB .ibd files around without using the\n"
"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n"
-"InnoDB: It is also possible that this is a table created with\n"
-"InnoDB: CREATE TEMPORARY TABLE, and MySQL removed the .ibd file for this.\n"
+"InnoDB: It is also possible that this is a temporary table #sql...,\n"
+"InnoDB: and MySQL removed the .ibd file for this.\n"
"InnoDB: Please refer to\n"
"InnoDB:"
" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
-"InnoDB: how to resolve the issue.\n", stderr);
+"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(filepath);
@@ -2657,7 +2718,7 @@ fil_open_single_table_tablespace(
"InnoDB: Please refer to\n"
"InnoDB:"
" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
-"InnoDB: how to resolve the issue.\n", (ulong) space_id, (ulong) id);
+"InnoDB: for how to resolve the issue.\n", (ulong) space_id, (ulong) id);
ret = FALSE;
@@ -3292,7 +3353,7 @@ fil_space_for_table_exists_in_mem(
ut_print_filename(stderr, name);
fprintf(stderr, "\n"
"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n"
-"InnoDB: but tablespace with that id does not exist. There is\n"
+"InnoDB: but a tablespace with that id does not exist. There is\n"
"InnoDB: a tablespace of name %s and id %lu, though. Have\n"
"InnoDB: you deleted or moved .ibd files?\n",
(ulong) id, namespace->name,
@@ -3303,7 +3364,7 @@ fil_space_for_table_exists_in_mem(
"InnoDB: Please refer to\n"
"InnoDB:"
" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
-"InnoDB: how to resolve the issue.\n", stderr);
+"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(path);
mutex_exit(&(system->mutex));
@@ -3317,7 +3378,7 @@ fil_space_for_table_exists_in_mem(
ut_print_filename(stderr, name);
fprintf(stderr, "\n"
"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n"
-"InnoDB: but tablespace with that id has name %s.\n"
+"InnoDB: but the tablespace with that id has name %s.\n"
"InnoDB: Have you deleted or moved .ibd files?\n", (ulong) id, space->name);
if (namespace != NULL) {
@@ -3732,6 +3793,14 @@ fil_node_complete_io(
if (type == OS_FILE_WRITE) {
system->modification_counter++;
node->modification_counter = system->modification_counter;
+
+ if (!node->space->is_in_unflushed_spaces) {
+
+ node->space->is_in_unflushed_spaces = TRUE;
+ UT_LIST_ADD_FIRST(unflushed_spaces,
+ system->unflushed_spaces,
+ node->space);
+ }
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
@@ -4145,6 +4214,16 @@ retry:
skip_flush:
if (node->flush_counter < old_mod_counter) {
node->flush_counter = old_mod_counter;
+
+ if (space->is_in_unflushed_spaces
+ && fil_space_is_flushed(space)) {
+
+ space->is_in_unflushed_spaces = FALSE;
+
+ UT_LIST_REMOVE(unflushed_spaces,
+ system->unflushed_spaces,
+ space);
+ }
}
if (space->purpose == FIL_TABLESPACE) {
@@ -4176,7 +4255,7 @@ fil_flush_file_spaces(
mutex_enter(&(system->mutex));
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(system->unflushed_spaces);
while (space) {
if (space->purpose == purpose && !space->is_being_deleted) {
@@ -4192,7 +4271,7 @@ fil_flush_file_spaces(
space->n_pending_flushes--;
}
- space = UT_LIST_GET_NEXT(space_list, space);
+ space = UT_LIST_GET_NEXT(unflushed_spaces, space);
}
mutex_exit(&(system->mutex));
diff --git a/innobase/include/btr0sea.ic b/innobase/include/btr0sea.ic
index 8a41042f713..f4e33027c25 100644
--- a/innobase/include/btr0sea.ic
+++ b/innobase/include/btr0sea.ic
@@ -16,7 +16,7 @@ Updates the search info. */
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in: search info */
+ btr_search_t* info, /* in/out: search info */
btr_cur_t* cursor);/* in: cursor which was just positioned */
/************************************************************************
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index cd07eb49cd6..0091e942d2c 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -86,9 +86,10 @@ log. */
#define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73
-#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources
+#define OS_FILE_PATH_ERROR 74
+#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources
to become available again */
-#define OS_FILE_ERROR_NOT_SPECIFIED 75
+#define OS_FILE_ERROR_NOT_SPECIFIED 76
/* Types for aio operations */
#define OS_FILE_READ 10
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 49f88c0d62a..6ef6f7cd545 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -303,6 +303,8 @@ os_file_get_last_error(
return(OS_FILE_NOT_FOUND);
} else if (err == EEXIST) {
return(OS_FILE_ALREADY_EXISTS);
+ } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) {
+ return(OS_FILE_PATH_ERROR);
} else {
return(100 + err);
}
@@ -352,7 +354,8 @@ os_file_handle_error(
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS) {
+ } else if (err == OS_FILE_ALREADY_EXISTS
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
@@ -456,7 +459,8 @@ os_file_handle_error_no_exit(
return(TRUE);
- } else if (err == OS_FILE_ALREADY_EXISTS) {
+ } else if (err == OS_FILE_ALREADY_EXISTS
+ || err == OS_FILE_PATH_ERROR) {
return(FALSE);
} else {
diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c
index 0278e3b2b66..e1a1119cfd4 100644
--- a/innobase/os/os0thread.c
+++ b/innobase/os/os0thread.c
@@ -148,6 +148,15 @@ os_thread_create(
exit(1);
}
#endif
+#ifdef __NETWARE__
+ ret = pthread_attr_setstacksize(&attr,
+ (size_t) NW_THD_STACKSIZE);
+ if (ret) {
+ fprintf(stderr,
+ "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret);
+ exit(1);
+ }
+#endif
os_mutex_enter(os_sync_mutex);
os_thread_count++;
os_mutex_exit(os_sync_mutex);
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index bb4d252f385..3f72049bf43 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -75,7 +75,7 @@ mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(sql_cmn_objects) $(vio_objects) $(sqlobjects)
-target_ldflags = -version-info @SHARED_LIB_VERSION@
+target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target)
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 7c6d140d2ef..498881aa947 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2733,7 +2733,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
{
switch (attr_type) {
case STMT_ATTR_UPDATE_MAX_LENGTH:
- *(unsigned long *) value= stmt->update_max_length;
+ *(my_bool*) value= stmt->update_max_length;
break;
default:
return TRUE;
@@ -4628,6 +4628,12 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
/* If statement hasnt been prepared there is nothing to reset */
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
DBUG_RETURN(0);
+ if (!stmt->mysql)
+ {
+ /* mysql can be reset in mysql_close called from mysql_reconnect */
+ set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
+ DBUG_RETURN(1);
+ }
mysql= stmt->mysql->last_used_con;
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
diff --git a/libmysql/libmysql.ver.in b/libmysql/libmysql.ver.in
new file mode 100644
index 00000000000..20eb0fd41bb
--- /dev/null
+++ b/libmysql/libmysql.ver.in
@@ -0,0 +1 @@
+libmysqlclient_@SHARED_LIB_MAJOR_VERSION@ { global: *; };
diff --git a/libmysqld/ha_blackhole.cc b/libmysqld/ha_blackhole.cc
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libmysqld/ha_blackhole.cc
diff --git a/myisam/ft_update.c b/myisam/ft_update.c
index beccc062270..8f2b2bce101 100644
--- a/myisam/ft_update.c
+++ b/myisam/ft_update.c
@@ -170,6 +170,10 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
FT_SEG_ITERATOR ftsi1, ftsi2;
CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
DBUG_ENTER("_mi_ft_cmp");
+#ifndef MYSQL_HAS_TRUE_CTYPE_IMPLEMENTATION
+ if (cs->mbmaxlen > 1)
+ DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT);
+#endif
_mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
_mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index 833223221ec..6c302aecea1 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -157,7 +157,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
goto err;
}
if ((error=d_search(info,keyinfo,
- (keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND
+ (keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND | SEARCH_UPDATE
: SEARCH_SAME),
key,key_length,old_root,root_buff)) >0)
{
diff --git a/mysql-test/include/have_euckr.inc b/mysql-test/include/have_euckr.inc
new file mode 100644
index 00000000000..af794aafc04
--- /dev/null
+++ b/mysql-test/include/have_euckr.inc
@@ -0,0 +1,4 @@
+-- require r/have_euckr.require
+disable_query_log;
+show collation like "euckr_korean_ci";
+enable_query_log;
diff --git a/mysql-test/include/have_gb2312.inc b/mysql-test/include/have_gb2312.inc
new file mode 100644
index 00000000000..4328bc67639
--- /dev/null
+++ b/mysql-test/include/have_gb2312.inc
@@ -0,0 +1,4 @@
+-- require r/have_gb2312.require
+disable_query_log;
+show collation like "gb2312_chinese_ci";
+enable_query_log;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index a933027cdb1..6fe148adce5 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -247,21 +247,6 @@ select * from t1;
0 1 2
0 0 1
drop table t1;
-create table t1 select 1,2,3;
-create table if not exists t1 select 1,2;
-Warnings:
-Note 1050 Table 't1' already exists
-create table if not exists t1 select 1,2,3,4;
-ERROR 21S01: Column count doesn't match value count at row 1
-create table if not exists t1 select 1;
-Warnings:
-Note 1050 Table 't1' already exists
-select * from t1;
-1 2 3
-1 2 3
-0 1 2
-0 0 1
-drop table t1;
create table t1 (a int not null, b int, primary key (a));
insert into t1 values (1,1);
create table if not exists t1 select 2;
@@ -601,6 +586,11 @@ DESC t2;
Field Type Null Key Default Extra
f2 varchar(86) YES NULL
DROP TABLE t1,t2;
+CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1;
+SELECT * FROM t12913;
+f1
+a
+DROP TABLE t12913;
create database mysqltest;
use mysqltest;
drop database mysqltest;
diff --git a/mysql-test/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result
new file mode 100644
index 00000000000..6017bc07763
--- /dev/null
+++ b/mysql-test/r/ctype_euckr.result
@@ -0,0 +1,167 @@
+drop table if exists t1;
+SET @test_character_set= 'euckr';
+SET @test_collation= 'euckr_korean_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) euckr_korean_ci YES MUL NULL
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
+aaa
+aaaa
+aaaaa
+DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) euckr_korean_ci YES MUL NULL
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
+SET NAMES euckr;
+SET collation_connection='euckr_korean_ci';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+euckr_korean_ci 6109
+euckr_korean_ci 61
+euckr_korean_ci 6120
+drop table t1;
+create table t1 engine=innodb select repeat('a',50) as c1;
+alter table t1 add index(c1(5));
+insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111');
+select collation(c1) from t1 limit 1;
+collation(c1)
+euckr_korean_ci
+select c1 from t1 where c1 like 'abcdef%' order by c1;
+c1
+abcdefg
+select c1 from t1 where c1 like 'abcde1%' order by c1;
+c1
+abcde100
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde11%' order by c1;
+c1
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde111%' order by c1;
+c1
+abcde111
+drop table t1;
+select @@collation_connection;
+@@collation_connection
+euckr_korean_ci
+create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ;
+insert into t1 values('abcdef');
+insert into t1 values('_bcdef');
+insert into t1 values('a_cdef');
+insert into t1 values('ab_def');
+insert into t1 values('abc_ef');
+insert into t1 values('abcd_f');
+insert into t1 values('abcde_');
+select c1 as c1u from t1 where c1 like 'ab\_def';
+c1u
+ab_def
+select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
+c2h
+ab_def
+drop table t1;
+SET collation_connection='euckr_bin';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+euckr_bin 6109
+euckr_bin 61
+euckr_bin 6120
+drop table t1;
+create table t1 engine=innodb select repeat('a',50) as c1;
+alter table t1 add index(c1(5));
+insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111');
+select collation(c1) from t1 limit 1;
+collation(c1)
+euckr_bin
+select c1 from t1 where c1 like 'abcdef%' order by c1;
+c1
+abcdefg
+select c1 from t1 where c1 like 'abcde1%' order by c1;
+c1
+abcde100
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde11%' order by c1;
+c1
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde111%' order by c1;
+c1
+abcde111
+drop table t1;
+select @@collation_connection;
+@@collation_connection
+euckr_bin
+create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ;
+insert into t1 values('abcdef');
+insert into t1 values('_bcdef');
+insert into t1 values('a_cdef');
+insert into t1 values('ab_def');
+insert into t1 values('abc_ef');
+insert into t1 values('abcd_f');
+insert into t1 values('abcde_');
+select c1 as c1u from t1 where c1 like 'ab\_def';
+c1u
+ab_def
+select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
+c2h
+ab_def
+drop table t1;
+SET NAMES euckr;
+CREATE TABLE t1 (a text) character set euckr;
+INSERT INTO t1 VALUES (0xA2E6),(0xFEF7);
+SELECT hex(a) FROM t1 ORDER BY a;
+hex(a)
+A2E6
+FEF7
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_gb2312.result b/mysql-test/r/ctype_gb2312.result
new file mode 100644
index 00000000000..314c336bab9
--- /dev/null
+++ b/mysql-test/r/ctype_gb2312.result
@@ -0,0 +1,167 @@
+drop table if exists t1;
+SET @test_character_set= 'gb2312';
+SET @test_collation= 'gb2312_chinese_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) gb2312_chinese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
+aaa
+aaaa
+aaaaa
+DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) gb2312_chinese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
+SET NAMES gb2312;
+SET collation_connection='gb2312_chinese_ci';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+gb2312_chinese_ci 6109
+gb2312_chinese_ci 61
+gb2312_chinese_ci 6120
+drop table t1;
+create table t1 engine=innodb select repeat('a',50) as c1;
+alter table t1 add index(c1(5));
+insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111');
+select collation(c1) from t1 limit 1;
+collation(c1)
+gb2312_chinese_ci
+select c1 from t1 where c1 like 'abcdef%' order by c1;
+c1
+abcdefg
+select c1 from t1 where c1 like 'abcde1%' order by c1;
+c1
+abcde100
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde11%' order by c1;
+c1
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde111%' order by c1;
+c1
+abcde111
+drop table t1;
+select @@collation_connection;
+@@collation_connection
+gb2312_chinese_ci
+create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ;
+insert into t1 values('abcdef');
+insert into t1 values('_bcdef');
+insert into t1 values('a_cdef');
+insert into t1 values('ab_def');
+insert into t1 values('abc_ef');
+insert into t1 values('abcd_f');
+insert into t1 values('abcde_');
+select c1 as c1u from t1 where c1 like 'ab\_def';
+c1u
+ab_def
+select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
+c2h
+ab_def
+drop table t1;
+SET collation_connection='gb2312_bin';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+gb2312_bin 6109
+gb2312_bin 61
+gb2312_bin 6120
+drop table t1;
+create table t1 engine=innodb select repeat('a',50) as c1;
+alter table t1 add index(c1(5));
+insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111');
+select collation(c1) from t1 limit 1;
+collation(c1)
+gb2312_bin
+select c1 from t1 where c1 like 'abcdef%' order by c1;
+c1
+abcdefg
+select c1 from t1 where c1 like 'abcde1%' order by c1;
+c1
+abcde100
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde11%' order by c1;
+c1
+abcde110
+abcde111
+select c1 from t1 where c1 like 'abcde111%' order by c1;
+c1
+abcde111
+drop table t1;
+select @@collation_connection;
+@@collation_connection
+gb2312_bin
+create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ;
+insert into t1 values('abcdef');
+insert into t1 values('_bcdef');
+insert into t1 values('a_cdef');
+insert into t1 values('ab_def');
+insert into t1 values('abc_ef');
+insert into t1 values('abcd_f');
+insert into t1 values('abcde_');
+select c1 as c1u from t1 where c1 like 'ab\_def';
+c1u
+ab_def
+select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
+c2h
+ab_def
+drop table t1;
+SET NAMES gb2312;
+CREATE TABLE t1 (a text) character set gb2312;
+INSERT INTO t1 VALUES (0xA2A1),(0xD7FE);
+SELECT hex(a) FROM t1 ORDER BY a;
+hex(a)
+A2A1
+D7FE
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 619ad750ff3..0e12ec88662 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -677,3 +677,29 @@ hex(a)
005B
803D
drop table t1;
+create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB;
+insert into t1 values('a');
+create index t1f1 on t1(f1);
+select f1 from t1 where f1 like 'a%';
+f1
+a
+drop table t1;
+create table t1 (utext varchar(20) character set ucs2);
+insert into t1 values ("lily");
+insert into t1 values ("river");
+prepare stmt from 'select utext from t1 where utext like ?';
+set @param1='%%';
+execute stmt using @param1;
+utext
+lily
+river
+execute stmt using @param1;
+utext
+lily
+river
+select utext from t1 where utext like '%%';
+utext
+lily
+river
+drop table t1;
+deallocate prepare stmt;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 03d3ab9f22e..cf9426e6b21 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1070,3 +1070,11 @@ char(a)
1
2
drop table t1;
+CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8);
+INSERT INTO t1 VALUES(REPEAT('a', 100));
+CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1;
+SELECT LENGTH(bug) FROM t2;
+LENGTH(bug)
+100
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index 34a2dedd976..014eeed27e7 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -464,3 +464,12 @@ d1 d2
02 February
01 January
drop table t1;
+select str_to_date( 1, NULL );
+str_to_date( 1, NULL )
+NULL
+select str_to_date( NULL, 1 );
+str_to_date( NULL, 1 )
+NULL
+select str_to_date( 1, IF(1=1,NULL,NULL) );
+str_to_date( 1, IF(1=1,NULL,NULL) )
+NULL
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index ebd6880a10e..c1dd5f80d5c 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -436,3 +436,14 @@ SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE);
a
testword''
DROP TABLE t1;
+CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a));
+INSERT INTO t1 VALUES('test'),('test1'),('test');
+PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a) AGAINST('test1 test')";
+EXECUTE stmt;
+a MATCH(a) AGAINST('test1 test')
+test1 0.68526661396027
+EXECUTE stmt;
+a MATCH(a) AGAINST('test1 test')
+test1 0.68526661396027
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
diff --git a/mysql-test/r/fulltext2.result b/mysql-test/r/fulltext2.result
index 0b1d8eb9a15..f6a4b20bc22 100644
--- a/mysql-test/r/fulltext2.result
+++ b/mysql-test/r/fulltext2.result
@@ -215,3 +215,29 @@ select count(*) from t1 where match a against ('aaazzz' in boolean mode);
count(*)
262
drop table t1;
+set names utf8;
+create table t1(a text,fulltext(a)) collate=utf8_swedish_ci;
+insert into t1 values('test test '),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test');
+delete from t1 limit 1;
+truncate table t1;
+insert into t1 values('ab c d');
+update t1 set a='ab c d';
+select * from t1 where match a against('ab c' in boolean mode);
+a
+drop table t1;
+set names latin1;
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index d7a741827d5..200b4a4d53b 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -131,9 +131,9 @@ grp group_concat(a separator "")+0
3 456789
select grp, group_concat(a separator "")+0.0 from t1 group by grp;
grp group_concat(a separator "")+0.0
-1 1.0
-2 23.0
-3 456789.0
+1 1
+2 23
+3 456789
select grp, ROUND(group_concat(a separator "")) from t1 group by grp;
grp ROUND(group_concat(a separator ""))
1 1
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 0a406c1ffc2..13593ec2a88 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -464,3 +464,12 @@ show grants for root@localhost;
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
set names latin1;
+insert into mysql.user (host, user) values ('', 'mysqltest_7');
+flush privileges;
+set password for mysqltest_7@ = password('systpass');
+show grants for mysqltest_7@;
+Grants for mysqltest_7@
+GRANT USAGE ON *.* TO 'mysqltest_7'@'' IDENTIFIED BY PASSWORD '*2FB071A056F9BB745219D9C876814231DAF46517'
+drop user mysqltest_7@;
+show grants for mysqltest_7@;
+ERROR 42000: There is no such grant defined for user 'mysqltest_7' on host ''
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 6b6bb697306..85963705718 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -131,3 +131,15 @@ lock table mysql.user write;
revoke all on *.* from 'mysqltest_1'@'localhost';
unlock tables;
drop user 'mysqltest_1'@'localhost';
+insert into mysql.user (user, host) values
+('mysqltest_1', 'host1'),
+('mysqltest_2', 'host2'),
+('mysqltest_3', 'host3'),
+('mysqltest_4', 'host4'),
+('mysqltest_5', 'host5'),
+('mysqltest_6', 'host6'),
+('mysqltest_7', 'host7');
+flush privileges;
+drop user mysqltest_3@host3;
+drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4,
+mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7;
diff --git a/mysql-test/r/have_euckr.require b/mysql-test/r/have_euckr.require
new file mode 100644
index 00000000000..0771ceec570
--- /dev/null
+++ b/mysql-test/r/have_euckr.require
@@ -0,0 +1,2 @@
+Collation Charset Id Default Compiled Sortlen
+euckr_korean_ci euckr 19 Yes Yes 1
diff --git a/mysql-test/r/have_gb2312.require b/mysql-test/r/have_gb2312.require
new file mode 100644
index 00000000000..9bcb7c94a14
--- /dev/null
+++ b/mysql-test/r/have_gb2312.require
@@ -0,0 +1,2 @@
+Collation Charset Id Default Compiled Sortlen
+gb2312_chinese_ci gb2312 24 Yes Yes 1
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 218276406b1..9730f9f81bf 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -128,3 +128,16 @@ id description c
1 test 0
2 test2 0
drop table t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (4), (1), (3), (1);
+SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a)>0;
+SUM(a)
+2
+6
+4
+SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a);
+SUM(a)
+2
+6
+4
+DROP TABLE t1;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 53dec294ef8..6bb9d0c87ee 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL;
a b
explain SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 1 Using where
+1 SIMPLE t1 ref a a 5 const 2 Using where
SELECT * FROM t1 WHERE a<=>NULL;
a b
NULL 99
@@ -296,3 +296,13 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1
drop table t1;
+CREATE TABLE t1 (a int, key(a)) engine=heap;
+insert into t1 values (0);
+delete from t1;
+select * from t1;
+a
+insert into t1 values (0), (1);
+select * from t1 where a = 0;
+a
+0
+drop table t1;
diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result
index e5098ab8c87..11b280997e5 100644
--- a/mysql-test/r/heap_hash.result
+++ b/mysql-test/r/heap_hash.result
@@ -182,7 +182,7 @@ SELECT * FROM t1 WHERE a=NULL;
a b
explain SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 5 const 1 Using where
+1 SIMPLE t1 ref a a 5 const 2 Using where
SELECT * FROM t1 WHERE a<=>NULL;
a b
NULL 99
@@ -220,16 +220,16 @@ insert into t1 values ('aaag', 'prefill-hash=3',0);
insert into t1 values ('aaah', 'prefill-hash=6',0);
explain select * from t1 where a='aaaa';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 8 const 1 Using where
+1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaab';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 8 const 1 Using where
+1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaac';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 8 const 1 Using where
+1 SIMPLE t1 ref a a 8 const 2 Using where
explain select * from t1 where a='aaad';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 8 const 1 Using where
+1 SIMPLE t1 ref a a 8 const 2 Using where
insert into t1 select * from t1;
flush tables;
explain select * from t1 where a='aaaa';
@@ -291,25 +291,25 @@ insert into t1 (name) values ('Matt'), ('Lilu'), ('Corbin'), ('Carly'),
insert into t2 select * from t1;
explain select * from t1 where name='matt';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
+1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where
explain select * from t2 where name='matt';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
+1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where
explain select * from t2 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Phil';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
+1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where
explain select * from t2 where name='Phil';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
explain select * from t1 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref heap_idx,btree_idx heap_idx 20 const 1 Using where
+1 SIMPLE t1 ref heap_idx,btree_idx btree_idx 20 const 1 Using where
explain select * from t2 where name='Lilu';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref btree_idx,heap_idx btree_idx 20 const 1 Using where
@@ -364,5 +364,5 @@ a
3
explain select a from t1 where a in (1,3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using where
+1 SIMPLE t1 range a a 5 NULL 4 Using where
drop table t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index b43d00bda1c..c4fae109bd4 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1754,3 +1754,56 @@ rename table t3 to t1;
ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
set foreign_key_checks=1;
drop table t2,t3;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2))
+) character set utf8 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2))
+) character set ucs2 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a hex(b)
+1 61626364656667
+2 6465666768696A6B
+6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a hex(b)
+1 61626364656667
+2 6465666768696A6B
+6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) default NULL,
+ KEY `t2_ibfk_0` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2,t1;
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index ba9ba2833f6..239f9d24e9e 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1, t2, t3;
create table t1 (kill_id int);
insert into t1 values(connection_id());
select ((@id := kill_id) - kill_id) from t1;
@@ -17,3 +17,15 @@ select 4;
4
4
drop table t1;
+create table t1 (id int primary key);
+create table t2 (id int unsigned not null);
+insert into t2 select id from t1;
+create table t3 (kill_id int);
+insert into t3 values(connection_id());
+ select id from t1 where id in (select distinct id from t2);
+select ((@id := kill_id) - kill_id) from t3;
+((@id := kill_id) - kill_id)
+0
+kill @id;
+Got one of the listed errors
+drop table t1, t2, t3;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 3035908688a..038ea43cabc 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -717,3 +717,52 @@ SELECT b FROM t2;
b
3
DROP TABLE t1, t2;
+create table t1(a int);
+create table t2(a int);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int) engine=merge union=(t1, t2) insert_method=first;
+select * from t3;
+a
+1
+2
+insert t2 select * from t2;
+select * from t2;
+a
+2
+2
+insert t3 select * from t1;
+select * from t3;
+a
+1
+1
+2
+2
+insert t1 select * from t3;
+select * from t1;
+a
+1
+1
+1
+1
+2
+2
+select * from t2;
+a
+2
+2
+select * from t3;
+a
+1
+1
+1
+1
+2
+2
+2
+2
+check table t1, t2;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+drop table t1, t2, t3;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index d2d0417f6e6..c269cbadca3 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -554,7 +554,7 @@ Warnings:
Note 1031 Table storage engine for 't1' doesn't have this option
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
-t1 1 a 1 a NULL 1000 NULL NULL YES HASH
+t1 1 a 1 a NULL 500 NULL NULL YES HASH
drop table t1,t2;
create table t1 ( a tinytext, b char(1), index idx (a(1),b) );
insert into t1 values (null,''), (null,'');
diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result
index 6f25ec95c80..bcf867a4edd 100644
--- a/mysql-test/r/ndb_blob.result
+++ b/mysql-test/r/ndb_blob.result
@@ -428,6 +428,13 @@ delete from t1;
select * from t1;
a b
commit;
+replace t1 set a=2, b='y';
+select * from t1;
+a b
+2 y
+delete from t1;
+select * from t1;
+a b
drop table t1;
set autocommit=0;
create table t1 (
diff --git a/mysql-test/r/ndb_load.result b/mysql-test/r/ndb_load.result
new file mode 100644
index 00000000000..76da5b2a215
--- /dev/null
+++ b/mysql-test/r/ndb_load.result
@@ -0,0 +1,80 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ;
+ERROR 23000: Can't write; duplicate key in table 't1'
+DROP TABLE t1;
+CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ;
+SELECT * FROM t1 ORDER BY word;
+word
+Aarhus
+Aarhus
+Aaron
+Aaron
+Ababa
+Ababa
+aback
+aback
+abaft
+abaft
+abandon
+abandon
+abandoned
+abandoned
+abandoning
+abandoning
+abandonment
+abandonment
+abandons
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+DROP TABLE t1;
diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result
index 2080be241e8..bd3af223a65 100644
--- a/mysql-test/r/ndb_multi.result
+++ b/mysql-test/r/ndb_multi.result
@@ -30,6 +30,7 @@ create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster
+flush table t1;
select * from t1;
a
2
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index d46c2d5b3d5..ba9336c20bb 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -639,25 +639,6 @@ execute stmt using @a, @b;
?=?
1
deallocate prepare stmt;
-create table t1 (utext varchar(20) character set ucs2);
-insert into t1 values ("lily");
-insert into t1 values ("river");
-prepare stmt from 'select utext from t1 where utext like ?';
-set @param1='%%';
-execute stmt using @param1;
-utext
-lily
-river
-execute stmt using @param1;
-utext
-lily
-river
-select utext from t1 where utext like '%%';
-utext
-lily
-river
-drop table t1;
-deallocate prepare stmt;
create table t1 (a int);
prepare stmt from "select ??";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
@@ -718,3 +699,37 @@ execute stmt;
drop table t1;
set names default;
deallocate prepare stmt;
+create table t1 (
+word_id mediumint(8) unsigned not null default '0',
+formatted varchar(20) not null default ''
+);
+insert into t1 values
+(80,'pendant'), (475,'pretendants'), (989,'tendances'),
+(1019,'cependant'),(1022,'abondance'),(1205,'independants'),
+(13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'),
+(82,'decrocher');
+select count(*) from t1 where formatted like '%NDAN%';
+count(*)
+6
+select count(*) from t1 where formatted like '%ER';
+count(*)
+5
+prepare stmt from "select count(*) from t1 where formatted like ?";
+set @like="%NDAN%";
+execute stmt using @like;
+count(*)
+6
+set @like="%ER";
+execute stmt using @like;
+count(*)
+5
+set @like="%NDAN%";
+execute stmt using @like;
+count(*)
+6
+set @like="%ER";
+execute stmt using @like;
+count(*)
+5
+deallocate prepare stmt;
+drop table t1;
diff --git a/mysql-test/r/rpl_ignore_table.result b/mysql-test/r/rpl_ignore_table.result
new file mode 100644
index 00000000000..356a9dcb2f8
--- /dev/null
+++ b/mysql-test/r/rpl_ignore_table.result
@@ -0,0 +1,16 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+**** Test case for BUG#16487 ****
+**** Master ****
+CREATE TABLE test.t4 (a int);
+CREATE TABLE test.t1 (a int);
+UPDATE test.t4 NATURAL JOIN test.t1 SET t1.a=5;
+**** Slave ****
+SELECT * FROM t4;
+a
+DROP TABLE t1;
+DROP TABLE t4;
diff --git a/mysql-test/r/rpl_multi_update4.result b/mysql-test/r/rpl_multi_update4.result
new file mode 100644
index 00000000000..f6dde65a35d
--- /dev/null
+++ b/mysql-test/r/rpl_multi_update4.result
@@ -0,0 +1,25 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists d1;
+drop database if exists d2;
+drop database if exists d2;
+create database d1;
+create table d1.t0 (id int);
+create database d2;
+use d2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (1), (2), (3), (4), (5);
+insert into t2 select id + 3 from t1;
+update t1 join t2 using (id) set t1.id = 0;
+insert into d1.t0 values (0);
+use d1;
+select * from t0 where id=0;
+id
+0
+drop database d1;
+drop database d2;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 4c795abe986..500aa4b1728 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -213,9 +213,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
a
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
-8 7.5000
-8 4.5000
-9 7.5000
+8 7.5
+8 4.5
+9 7.5
explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 6e381192270..e8daeb08526 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -250,3 +250,25 @@ t3 CREATE TABLE `t3` (
`d` double(22,9) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
+create table t1 select 105213674794682365.00 + 0.0 x;
+show warnings;
+Level Code Message
+desc t1;
+Field Type Null Key Default Extra
+x double 0
+drop table t1;
+create table t1 select 0.0 x;
+desc t1;
+Field Type Null Key Default Extra
+x double(3,1) 0.0
+create table t2 select 105213674794682365.00 y;
+desc t2;
+Field Type Null Key Default Extra
+y double(21,2) 0.00
+create table t3 select x+y a from t1,t2;
+show warnings;
+Level Code Message
+desc t3;
+Field Type Null Key Default Extra
+a double 0
+drop table t1,t2,t3;
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 7854fd773a1..0f86a959250 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -358,3 +358,22 @@ update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1;
affected rows: 3
info: Rows matched: 3 Changed: 3 Warnings: 0
drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, filler1 char(200), filler2 char(200), key(a));
+insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B;
+flush status;
+update t2 set a=3 where a=2;
+show status like 'handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 1
+Handler_read_next 1
+Handler_read_prev 0
+Handler_read_rnd 1
+Handler_read_rnd_next 0
+drop table t1, t2;
+create table t1(f1 int, `*f2` int);
+insert into t1 values (1,1);
+update t1 set `*f2`=1;
+drop table t1;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index c9d16916f8a..7799200eaa0 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -207,13 +207,6 @@ create table if not exists t1 select 1,2,3,4;
create table if not exists t1 select 1;
select * from t1;
drop table t1;
-create table t1 select 1,2,3;
-create table if not exists t1 select 1,2;
---error 1136
-create table if not exists t1 select 1,2,3,4;
-create table if not exists t1 select 1;
-select * from t1;
-drop table t1;
#
# Test create table if not exists with duplicate key error
@@ -502,6 +495,13 @@ DESC t2;
DROP TABLE t1,t2;
#
+# Bug#12913 Simple SQL can crash server or connection
+#
+CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1;
+SELECT * FROM t12913;
+DROP TABLE t12913;
+
+#
# Bug#11028: Crash on create table like
#
create database mysqltest;
diff --git a/mysql-test/t/ctype_euckr.test b/mysql-test/t/ctype_euckr.test
new file mode 100644
index 00000000000..56939817b2f
--- /dev/null
+++ b/mysql-test/t/ctype_euckr.test
@@ -0,0 +1,33 @@
+-- source include/have_euckr.inc
+
+#
+# Tests with the euckr character set
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET @test_character_set= 'euckr';
+SET @test_collation= 'euckr_korean_ci';
+-- source include/ctype_common.inc
+
+SET NAMES euckr;
+SET collation_connection='euckr_korean_ci';
+-- source include/ctype_filesort.inc
+-- source include/ctype_innodb_like.inc
+-- source include/ctype_like_escape.inc
+SET collation_connection='euckr_bin';
+-- source include/ctype_filesort.inc
+-- source include/ctype_innodb_like.inc
+-- source include/ctype_like_escape.inc
+
+#
+# Bug#15377 Valid multibyte sequences are truncated on INSERT
+#
+SET NAMES euckr;
+CREATE TABLE t1 (a text) character set euckr;
+INSERT INTO t1 VALUES (0xA2E6),(0xFEF7);
+SELECT hex(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/ctype_gb2312.test b/mysql-test/t/ctype_gb2312.test
new file mode 100644
index 00000000000..835818d441c
--- /dev/null
+++ b/mysql-test/t/ctype_gb2312.test
@@ -0,0 +1,33 @@
+-- source include/have_gb2312.inc
+
+#
+# Tests with the gb2312 character set
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+SET @test_character_set= 'gb2312';
+SET @test_collation= 'gb2312_chinese_ci';
+-- source include/ctype_common.inc
+
+SET NAMES gb2312;
+SET collation_connection='gb2312_chinese_ci';
+-- source include/ctype_filesort.inc
+-- source include/ctype_innodb_like.inc
+-- source include/ctype_like_escape.inc
+SET collation_connection='gb2312_bin';
+-- source include/ctype_filesort.inc
+-- source include/ctype_innodb_like.inc
+-- source include/ctype_like_escape.inc
+
+#
+# Bug#15377 Valid multibyte sequences are truncated on INSERT
+#
+SET NAMES gb2312;
+CREATE TABLE t1 (a text) character set gb2312;
+INSERT INTO t1 VALUES (0xA2A1),(0xD7FE);
+SELECT hex(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 2c9e71ddff5..bd37d008173 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -419,4 +419,28 @@ insert into t1 values (0x005b);
select hex(a) from t1;
drop table t1;
+#
+# Bug #14583 Bug on query using a LIKE on indexed field with ucs2_bin collation
+#
+--disable_warnings
+create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB;
+--enable_warnings
+insert into t1 values('a');
+create index t1f1 on t1(f1);
+select f1 from t1 where f1 like 'a%';
+drop table t1;
+
+#
+# Bug#9442 Set parameter make query fail if column character set is UCS2
+#
+create table t1 (utext varchar(20) character set ucs2);
+insert into t1 values ("lily");
+insert into t1 values ("river");
+prepare stmt from 'select utext from t1 where utext like ?';
+set @param1='%%';
+execute stmt using @param1;
+execute stmt using @param1;
+select utext from t1 where utext like '%%';
+drop table t1;
+deallocate prepare stmt;
# End of 4.1 tests
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 8c0e03c0cd3..01bffe9492e 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -882,4 +882,14 @@ set names utf8;
select distinct char(a) from t1;
drop table t1;
+#
+# Bug#15581: COALESCE function truncates mutli-byte TINYTEXT values
+#
+CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8);
+INSERT INTO t1 VALUES(REPEAT('a', 100));
+CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1;
+SELECT LENGTH(bug) FROM t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test
index 6d501865d2c..78b4482a94a 100644
--- a/mysql-test/t/date_formats.test
+++ b/mysql-test/t/date_formats.test
@@ -268,4 +268,11 @@ insert into t1 (f1) values ("2005-01-01");
insert into t1 (f1) values ("2005-02-01");
select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M");
drop table t1;
+
+#
+# Bug #15828
+#
+select str_to_date( 1, NULL );
+select str_to_date( NULL, 1 );
+select str_to_date( 1, IF(1=1,NULL,NULL) );
# End of 4.1 tests
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index ddb79205357..3eae8d230d8 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -13,4 +13,3 @@
rpl_relayrotate : Unstable test case, bug#12429
rpl_until : Unstable test case, bug#12429
rpl_deadlock : Unstable test case, bug#12429
-kill : Unstable test case, bug#9712
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 1399b9bfdff..d5ce6241490 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -357,4 +357,16 @@ SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE);
SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE);
DROP TABLE t1;
+#
+# BUG#14496: Crash or strange results with prepared statement,
+# MATCH and FULLTEXT
+#
+CREATE TABLE t1 (a TEXT, FULLTEXT KEY(a));
+INSERT INTO t1 VALUES('test'),('test1'),('test');
+PREPARE stmt from "SELECT a, MATCH(a) AGAINST('test1 test') FROM t1 WHERE MATCH(a) AGAINST('test1 test')";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/fulltext2.test b/mysql-test/t/fulltext2.test
index bcd39b9ea04..fd97f795534 100644
--- a/mysql-test/t/fulltext2.test
+++ b/mysql-test/t/fulltext2.test
@@ -179,7 +179,45 @@ update t1 set a='aaaxxx' where a = 'aaayyy';
select count(*) from t1 where match a against ('aaaxxx' in boolean mode);
select count(*) from t1 where match a against ('aaayyy' in boolean mode);
select count(*) from t1 where match a against ('aaazzz' in boolean mode);
+drop table t1;
+#
+# BUG#11336
+#
+# for uca collation isalnum and strnncollsp don't agree on whether
+# 0xC2A0 is a space (strnncollsp is right, isalnum is wrong).
+#
+# they still don't, the bug was fixed by avoiding strnncollsp
+#
+
+set names utf8;
+create table t1(a text,fulltext(a)) collate=utf8_swedish_ci;
+insert into t1 values('test test '),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
+('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test');
+delete from t1 limit 1;
+
+#
+# BUG#16489: utf8 + fulltext leads to corrupt index file.
+#
+truncate table t1;
+insert into t1 values('ab c d');
+update t1 set a='ab c d';
+select * from t1 where match a against('ab c' in boolean mode);
drop table t1;
+set names latin1;
# End of 4.1 tests
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index a8f62e38e86..c22c09ab62b 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -91,7 +91,9 @@ drop table t1;
#
# InnoDB is required to reproduce the fault, but it is okay if we default to
# MyISAM when testing.
+--disable_warnings
create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8;
+--enable_warnings
insert into t1 values ('http://www.foo.com/', now());
select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0));
drop table t1;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 039e41dcf34..805fa881399 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -421,4 +421,16 @@ revoke all privileges on ÂÄ.* from root@localhost;
show grants for root@localhost;
set names latin1;
+#
+# Bug #15598 Server crashes in specific case during setting new password
+# - Caused by a user with host ''
+#
+insert into mysql.user (host, user) values ('', 'mysqltest_7');
+flush privileges;
+set password for mysqltest_7@ = password('systpass');
+show grants for mysqltest_7@;
+drop user mysqltest_7@;
+--error 1141
+show grants for mysqltest_7@;
+
# End of 4.1 tests
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index cb00c41a0ca..79ea7f70712 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -206,4 +206,37 @@ drop user 'mysqltest_1'@'localhost';
disconnect con2root;
disconnect con3root;
+#
+# Bug #15775: "drop user" command does not refresh acl_check_hosts
+#
+
+# Create some test users
+insert into mysql.user (user, host) values
+ ('mysqltest_1', 'host1'),
+ ('mysqltest_2', 'host2'),
+ ('mysqltest_3', 'host3'),
+ ('mysqltest_4', 'host4'),
+ ('mysqltest_5', 'host5'),
+ ('mysqltest_6', 'host6'),
+ ('mysqltest_7', 'host7');
+flush privileges;
+
+# Drop one user
+drop user mysqltest_3@host3;
+
+# This connect failed before fix since the acl_check_hosts list was corrupted by the "drop user"
+connect (con8,127.0.0.1,root,,test,$MASTER_MYPORT,);
+disconnect con8;
+connection default;
+
+# Clean up - Drop all of the remaining users at once
+drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4,
+ mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7;
+
+# Check that it's still possible to connect
+connect (con9,127.0.0.1,root,,test,$MASTER_MYPORT,);
+disconnect con9;
+connection default;
+
+
# End of 4.1 tests
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index 920a3b752ab..3dd9ace6a1b 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -123,4 +123,16 @@ group by a.id, a.description
having (a.description is not null) and (c=0);
drop table t1,t2,t3;
+#
+# Bug #14274: HAVING clause containing only set function
+#
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (4), (1), (3), (1);
+
+SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a)>0;
+SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a);
+
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test
index 270b8a1df6f..50147b4182d 100644
--- a/mysql-test/t/heap.test
+++ b/mysql-test/t/heap.test
@@ -234,4 +234,15 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
drop table t1;
+#
+# Bug 12796: Record doesn't show when selecting through index
+#
+CREATE TABLE t1 (a int, key(a)) engine=heap;
+insert into t1 values (0);
+delete from t1;
+select * from t1;
+insert into t1 values (0), (1);
+select * from t1 where a = 0;
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 03aa113c662..ee411a1bb37 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1329,4 +1329,53 @@ create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
rename table t3 to t1;
set foreign_key_checks=1;
drop table t2,t3;
+
+# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..'
+
+create table t2 (
+ a int, b char(10), filler char(10), primary key(a, b(2))
+) character set utf8 engine = innodb;
+
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+ a int, b char(10), filler char(10), primary key(a, b(2))
+) character set ucs2 engine = innodb;
+
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;
+
+# Ensure that <tablename>_ibfk_0 is not mistreated as a
+# generated foreign key identifier. (Bug #16387)
+
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+DROP TABLE t2,t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index aada8dd2ef3..9ef5e272d46 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -12,7 +12,7 @@ connect (con2, localhost, root,,);
#remember id of con1
connection con1;
--disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2, t3;
--enable_warnings
create table t1 (kill_id int);
@@ -40,4 +40,51 @@ connection con2;
select 4;
drop table t1;
+disconnect con2;
+connection default;
+#
+# BUG#14851: killing long running subquery processed via a temporary table.
+#
+create table t1 (id int primary key);
+create table t2 (id int unsigned not null);
+
+connect (conn1, localhost, root,,);
+connection conn1;
+
+-- disable_result_log
+-- disable_query_log
+let $1 = 4096;
+while ($1)
+{
+ eval insert into t1 values ($1);
+ dec $1;
+}
+-- enable_query_log
+-- enable_result_log
+
+insert into t2 select id from t1;
+
+create table t3 (kill_id int);
+insert into t3 values(connection_id());
+
+-- disable_result_log
+send select id from t1 where id in (select distinct id from t2);
+-- enable_result_log
+
+connect (conn2, localhost, root,,);
+connection conn2;
+select ((@id := kill_id) - kill_id) from t3;
+-- sleep 1
+kill @id;
+
+connection conn1;
+-- error 1053,2013
+reap;
+
+disconnect conn1;
+disconnect conn2;
+connection default;
+
+drop table t1, t2, t3;
+
# End of 4.1 tests
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index d384c017611..a723443b395 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -350,4 +350,30 @@ INSERT INTO t2 (b) VALUES (1) ON DUPLICATE KEY UPDATE b=3;
SELECT b FROM t2;
DROP TABLE t1, t2;
+
+#
+# BUG#5390 - problems with merge tables
+# Problem #1: INSERT...SELECT
+#
+#drop table if exists t1, t2, t3;
+create table t1(a int);
+create table t2(a int);
+insert into t1 values (1);
+insert into t2 values (2);
+create table t3 (a int) engine=merge union=(t1, t2) insert_method=first;
+select * from t3;
+#
+insert t2 select * from t2;
+select * from t2;
+#
+insert t3 select * from t1;
+select * from t3;
+#
+insert t1 select * from t3;
+select * from t1;
+select * from t2;
+select * from t3;
+check table t1, t2;
+drop table t1, t2, t3;
+
# End of 4.1 tests
diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test
index a12ebee2f0d..f80b7f71281 100644
--- a/mysql-test/t/ndb_blob.test
+++ b/mysql-test/t/ndb_blob.test
@@ -338,7 +338,7 @@ select * from t1 order by a;
drop table t1;
drop database test2;
-# -- bug-5252 tinytext crashes plus no-commit result --
+# -- bug-5252 tinytext crashes + no-commit result + replace --
set autocommit=0;
create table t1 (
@@ -352,6 +352,10 @@ select * from t1;
delete from t1;
select * from t1;
commit;
+replace t1 set a=2, b='y';
+select * from t1;
+delete from t1;
+select * from t1;
drop table t1;
# -- bug-5013 insert empty string to text --
diff --git a/mysql-test/t/ndb_load.test b/mysql-test/t/ndb_load.test
new file mode 100644
index 00000000000..72a5b53eaad
--- /dev/null
+++ b/mysql-test/t/ndb_load.test
@@ -0,0 +1,24 @@
+-- source include/have_ndb.inc
+-- source include/not_embedded.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+#
+# Basic test for different types of loading data
+#
+
+# should give duplicate key
+CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB;
+--error 1022
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ;
+DROP TABLE t1;
+
+# now without a primary key we should be ok
+CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB;
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ;
+SELECT * FROM t1 ORDER BY word;
+DROP TABLE t1;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test
index 760150c6f6a..1183f2b283f 100644
--- a/mysql-test/t/ndb_multi.test
+++ b/mysql-test/t/ndb_multi.test
@@ -40,6 +40,7 @@ connection server1;
# Currently a retry is required remotely
--error 1296
select * from t1;
+flush table t1;
select * from t1;
# Connect to server2 and use the tables from there
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 82dfc643801..b0755d06414 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -665,19 +665,6 @@ set @b='CHRISTINE';
execute stmt using @a, @b;
deallocate prepare stmt;
#
-# Bug#9442 Set parameter make query fail if column character set is UCS2
-#
-create table t1 (utext varchar(20) character set ucs2);
-insert into t1 values ("lily");
-insert into t1 values ("river");
-prepare stmt from 'select utext from t1 where utext like ?';
-set @param1='%%';
-execute stmt using @param1;
-execute stmt using @param1;
-select utext from t1 where utext like '%%';
-drop table t1;
-deallocate prepare stmt;
-#
# Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
# replication": check that errouneous queries with placeholders are not
# allowed
@@ -746,5 +733,35 @@ drop table t1;
set names default;
deallocate prepare stmt;
+#
+# A test case for Bug#12734 "prepared statement may return incorrect result
+# set for a select SQL request": test that canDoTurboBM is reset for each
+# execute of a prepared statement.
+#
+create table t1 (
+ word_id mediumint(8) unsigned not null default '0',
+ formatted varchar(20) not null default ''
+);
+
+insert into t1 values
+ (80,'pendant'), (475,'pretendants'), (989,'tendances'),
+ (1019,'cependant'),(1022,'abondance'),(1205,'independants'),
+ (13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'),
+ (82,'decrocher');
+
+select count(*) from t1 where formatted like '%NDAN%';
+select count(*) from t1 where formatted like '%ER';
+prepare stmt from "select count(*) from t1 where formatted like ?";
+set @like="%NDAN%";
+execute stmt using @like;
+set @like="%ER";
+execute stmt using @like;
+set @like="%NDAN%";
+execute stmt using @like;
+set @like="%ER";
+execute stmt using @like;
+deallocate prepare stmt;
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_ignore_table-slave.opt b/mysql-test/t/rpl_ignore_table-slave.opt
new file mode 100644
index 00000000000..cb49119bfcb
--- /dev/null
+++ b/mysql-test/t/rpl_ignore_table-slave.opt
@@ -0,0 +1 @@
+--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3
diff --git a/mysql-test/t/rpl_ignore_table.test b/mysql-test/t/rpl_ignore_table.test
new file mode 100644
index 00000000000..bc651779208
--- /dev/null
+++ b/mysql-test/t/rpl_ignore_table.test
@@ -0,0 +1,28 @@
+source include/master-slave.inc;
+
+#
+# BUG#16487
+#
+# Requirement:
+# Multi-updates on ignored tables should not fail even if the slave does
+# not have the ignored tables.
+#
+# Note table t1, t2, and t3 are ignored in the option file to this test.
+#
+
+--echo **** Test case for BUG#16487 ****
+--echo **** Master ****
+connection master;
+CREATE TABLE test.t4 (a int);
+CREATE TABLE test.t1 (a int);
+
+# Expect: The row must *not* by updated on slave, since t1 is ignored
+UPDATE test.t4 NATURAL JOIN test.t1 SET t1.a=5;
+
+--echo **** Slave ****
+sync_slave_with_master;
+SELECT * FROM t4;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t4;
diff --git a/mysql-test/t/rpl_multi_update4-slave.opt b/mysql-test/t/rpl_multi_update4-slave.opt
new file mode 100644
index 00000000000..fea27db43ee
--- /dev/null
+++ b/mysql-test/t/rpl_multi_update4-slave.opt
@@ -0,0 +1 @@
+--replicate-wild-do-table=d1.%
diff --git a/mysql-test/t/rpl_multi_update4.test b/mysql-test/t/rpl_multi_update4.test
new file mode 100644
index 00000000000..3d909b8e5cd
--- /dev/null
+++ b/mysql-test/t/rpl_multi_update4.test
@@ -0,0 +1,44 @@
+# Let's verify that multi-update is not always skipped by slave if
+# some replicate-* rules exist.
+# (BUG#15699)
+
+source include/master-slave.inc;
+
+### Clean-up
+
+connection master;
+--disable_warnings
+drop database if exists d1;
+drop database if exists d2;
+
+connection slave;
+drop database if exists d2;
+--enable_warnings
+
+### Test
+
+connection master;
+create database d1; # accepted by slave
+create table d1.t0 (id int);
+create database d2; # ignored by slave
+use d2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (1), (2), (3), (4), (5);
+insert into t2 select id + 3 from t1;
+# a problematic query which must be filter out by slave
+update t1 join t2 using (id) set t1.id = 0;
+insert into d1.t0 values (0); # replication works
+
+sync_slave_with_master;
+use d1;
+#connection slave;
+select * from t0 where id=0; # must find
+
+### Clean-up
+connection master;
+drop database d1;
+drop database d2;
+
+
+# End of test
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index 85ad04aa556..c0c1db3d553 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -3,6 +3,8 @@ disable_query_log;
show variables like "have_symlink";
enable_query_log;
+--source include/not_windows.inc
+
--disable_warnings
drop table if exists t1,t2,t7,t8,t9;
drop database if exists mysqltest;
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index abaf72ea2ed..75723d2a0ff 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -162,4 +162,21 @@ show create table t3;
drop table t1, t2, t3;
+#
+# Bug #9855 (inconsistent column type for create select
+#
+create table t1 select 105213674794682365.00 + 0.0 x;
+show warnings;
+desc t1;
+drop table t1;
+
+create table t1 select 0.0 x;
+desc t1;
+create table t2 select 105213674794682365.00 y;
+desc t2;
+create table t3 select x+y a from t1,t2;
+show warnings;
+desc t3;
+drop table t1,t2,t3;
+
# End of 4.1 tests
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 7ae3f65f7cc..cb7e4f85ad1 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -21,4 +21,22 @@ select t, time_to_sec(t),sec_to_time(time_to_sec(t)) from t1;
select sec_to_time(time_to_sec(t)) from t1;
drop table t1;
+#
+# BUG #12440: Incorrect processing of time values containing
+# long fraction part and/or large exponent part.
+#
+# These must return normal result:
+# ##########################################################
+# To be uncommented after fix BUG #15805
+# ##########################################################
+# SELECT CAST(235959.123456 AS TIME);
+# SELECT CAST(0.235959123456e+6 AS TIME);
+# SELECT CAST(235959123456e-6 AS TIME);
+# These must cut fraction part and produce warning:
+# SELECT CAST(235959.1234567 AS TIME);
+# SELECT CAST(0.2359591234567e6 AS TIME);
+# This must return NULL and produce warning:
+# SELECT CAST(0.2359591234567e+30 AS TIME);
+# ##########################################################
+
# End of 4.1 tests
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 95adb40962c..c69c56f0331 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -287,4 +287,23 @@ update t1 set f1=1 where f1=3;
update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1;
--disable_info
drop table t1,t2;
+
+
+# BUG#15935
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, filler1 char(200), filler2 char(200), key(a));
+insert into t2 select A.a + 10*B.a, 'filler','filler' from t1 A, t1 B;
+flush status;
+update t2 set a=3 where a=2;
+show status like 'handler_read%';
+drop table t1, t2;
+
+#
+# Bug #16510 Updating field named like '*name' caused server crash
+#
+create table t1(f1 int, `*f2` int);
+insert into t1 values (1,1);
+update t1 set `*f2`=1;
+drop table t1;
# End of 4.1 tests
diff --git a/mysys/hash.c b/mysys/hash.c
index ffebdf76144..75135a470c9 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -36,9 +36,10 @@ typedef struct st_hash_info {
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
-static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length);
+static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key,
+ uint length);
-static uint calc_hash(HASH *hash,const byte *key,uint length)
+static uint calc_hash(const HASH *hash, const byte *key, uint length)
{
ulong nr1=1, nr2=4;
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
@@ -63,7 +64,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
hash->key_offset=key_offset;
hash->key_length=key_length;
hash->blength=1;
- hash->current_record= NO_RECORD; /* For the future */
hash->get_key=get_key;
hash->free=free_element;
hash->flags=flags;
@@ -135,7 +135,6 @@ void my_hash_reset(HASH *hash)
reset_dynamic(&hash->array);
/* Set row pointers so that the hash can be reused at once */
hash->blength= 1;
- hash->current_record= NO_RECORD;
DBUG_VOID_RETURN;
}
@@ -147,7 +146,8 @@ void my_hash_reset(HASH *hash)
*/
static inline char*
-hash_key(HASH *hash,const byte *record,uint *length,my_bool first)
+hash_key(const HASH *hash, const byte *record, uint *length,
+ my_bool first)
{
if (hash->get_key)
return (*hash->get_key)(record,length,first);
@@ -163,8 +163,8 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
return (hashnr & ((buffmax >> 1) -1));
}
-static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax,
- uint maxlength)
+static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos,
+ uint buffmax, uint maxlength)
{
uint length;
byte *key= (byte*) hash_key(hash,pos->data,&length,0);
@@ -186,14 +186,25 @@ unsigned int rec_hashnr(HASH *hash,const byte *record)
}
- /* Search after a record based on a key */
- /* Sets info->current_ptr to found record */
+gptr hash_search(const HASH *hash, const byte *key, uint length)
+{
+ HASH_SEARCH_STATE state;
+ return hash_first(hash, key, length, &state);
+}
+
+/*
+ Search after a record based on a key
+
+ NOTE
+ Assigns the number of the found record to HASH_SEARCH_STATE state
+*/
-gptr hash_search(HASH *hash,const byte *key,uint length)
+gptr hash_first(const HASH *hash, const byte *key, uint length,
+ HASH_SEARCH_STATE *current_record)
{
HASH_LINK *pos;
uint flag,idx;
- DBUG_ENTER("hash_search");
+ DBUG_ENTER("hash_first");
flag=1;
if (hash->records)
@@ -206,7 +217,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length)
if (!hashcmp(hash,pos,key,length))
{
DBUG_PRINT("exit",("found key at %d",idx));
- hash->current_record= idx;
+ *current_record= idx;
DBUG_RETURN (pos->data);
}
if (flag)
@@ -218,31 +229,32 @@ gptr hash_search(HASH *hash,const byte *key,uint length)
}
while ((idx=pos->next) != NO_RECORD);
}
- hash->current_record= NO_RECORD;
+ *current_record= NO_RECORD;
DBUG_RETURN(0);
}
/* Get next record with identical key */
/* Can only be called if previous calls was hash_search */
-gptr hash_next(HASH *hash,const byte *key,uint length)
+gptr hash_next(const HASH *hash, const byte *key, uint length,
+ HASH_SEARCH_STATE *current_record)
{
HASH_LINK *pos;
uint idx;
- if (hash->current_record != NO_RECORD)
+ if (*current_record != NO_RECORD)
{
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
- for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next)
+ for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next)
{
pos=data+idx;
if (!hashcmp(hash,pos,key,length))
{
- hash->current_record= idx;
+ *current_record= idx;
return pos->data;
}
}
- hash->current_record=NO_RECORD;
+ *current_record= NO_RECORD;
}
return 0;
}
@@ -282,7 +294,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
> 0 key of record > key
*/
-static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
+static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key,
+ uint length)
{
uint rec_keylength;
byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1);
@@ -308,7 +321,6 @@ my_bool my_hash_insert(HASH *info,const byte *record)
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
return(TRUE); /* No more memory */
- info->current_record= NO_RECORD;
data=dynamic_element(&info->array,0,HASH_LINK*);
halfbuff= info->blength >> 1;
@@ -451,7 +463,6 @@ my_bool hash_delete(HASH *hash,byte *record)
}
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
- hash->current_record= NO_RECORD;
lastpos=data+hash->records;
/* Remove link to record */
@@ -544,7 +555,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
if ((idx=pos->next) == NO_RECORD)
DBUG_RETURN(1); /* Not found in links */
}
- hash->current_record= NO_RECORD;
org_link= *pos;
empty=idx;
@@ -594,10 +604,10 @@ byte *hash_element(HASH *hash,uint idx)
isn't changed
*/
-void hash_replace(HASH *hash, uint idx, byte *new_row)
+void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, byte *new_row)
{
- if (idx != NO_RECORD) /* Safety */
- dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row;
+ if (*current_record != NO_RECORD) /* Safety */
+ dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;
}
diff --git a/mysys/sha1.c b/mysys/sha1.c
index d93b4571baf..110d24f8bfc 100644
--- a/mysys/sha1.c
+++ b/mysys/sha1.c
@@ -69,7 +69,7 @@ static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
Initialize SHA1Context
SYNOPSIS
- sha1_reset()
+ mysql_sha1_reset()
context [in/out] The context to reset.
DESCRIPTION
@@ -92,7 +92,7 @@ const uint32 sha_const_key[5]=
};
-int sha1_reset(SHA1_CONTEXT *context)
+int mysql_sha1_reset(SHA1_CONTEXT *context)
{
#ifndef DBUG_OFF
if (!context)
@@ -119,7 +119,7 @@ int sha1_reset(SHA1_CONTEXT *context)
Return the 160-bit message digest into the array provided by the caller
SYNOPSIS
- sha1_result()
+ mysql_sha1_result()
context [in/out] The context to use to calculate the SHA-1 hash.
Message_Digest: [out] Where the digest is returned.
@@ -132,8 +132,8 @@ int sha1_reset(SHA1_CONTEXT *context)
!= SHA_SUCCESS sha Error Code.
*/
-int sha1_result(SHA1_CONTEXT *context,
- uint8 Message_Digest[SHA1_HASH_SIZE])
+int mysql_sha1_result(SHA1_CONTEXT *context,
+ uint8 Message_Digest[SHA1_HASH_SIZE])
{
int i;
@@ -165,7 +165,7 @@ int sha1_result(SHA1_CONTEXT *context,
Accepts an array of octets as the next portion of the message.
SYNOPSIS
- sha1_input()
+ mysql_sha1_input()
context [in/out] The SHA context to update
message_array An array of characters representing the next portion
of the message.
@@ -176,8 +176,8 @@ int sha1_result(SHA1_CONTEXT *context,
!= SHA_SUCCESS sha Error Code.
*/
-int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
- unsigned length)
+int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
+ unsigned length)
{
if (!length)
return SHA_SUCCESS;
diff --git a/mysys/testhash.c b/mysys/testhash.c
index 72badffdbcd..d15016113cd 100644
--- a/mysys/testhash.c
+++ b/mysys/testhash.c
@@ -74,7 +74,7 @@ static int do_test()
bzero((char*) key1,sizeof(key1[0])*1000);
printf("- Creating hash\n");
- if (hash_init(&hash,recant/2,0,6,0,free_record,0))
+ if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0))
goto err;
printf("- Writing records:\n");
@@ -172,15 +172,16 @@ static int do_test()
break;
if (key1[j] > 1)
{
+ HASH_SEARCH_STATE state;
printf("- Testing identical read\n");
sprintf(key,"%6d",j);
pos=1;
- if (!(recpos=hash_search(&hash,key,0)))
+ if (!(recpos= hash_first(&hash, key, 0, &state)))
{
printf("can't find key1: \"%s\"\n",key);
goto err;
}
- while (hash_next(&hash,key,0) && pos < (ulong) (key1[j]+10))
+ while (hash_next(&hash, key, 0, &state) && pos < (ulong) (key1[j]+10))
pos++;
if (pos != (ulong) key1[j])
{
@@ -189,7 +190,7 @@ static int do_test()
}
}
printf("- Creating output heap-file 2\n");
- if (hash_init(&hash2,hash.records,0,0,hash2_key,free_record,0))
+ if (hash_init(&hash2, default_charset_info, hash.records, 0, 0, hash2_key, free_record,0))
goto err;
printf("- Copying and removing records\n");
diff --git a/ndb/include/logger/LogHandler.hpp b/ndb/include/logger/LogHandler.hpp
index 7df6ad864e5..8b9aa43d7a9 100644
--- a/ndb/include/logger/LogHandler.hpp
+++ b/ndb/include/logger/LogHandler.hpp
@@ -126,6 +126,18 @@ public:
void setErrorCode(int code);
/**
+ * Returns the error string.
+ */
+ char* getErrorStr();
+
+ /**
+ * Sets the error string.
+ *
+ * @param str the error string.
+ */
+ void setErrorStr(char* str);
+
+ /**
* Parse logstring parameters
*
* @param params list of parameters, formatted as "param=value",
@@ -195,6 +207,7 @@ private:
const char* m_pDateTimeFormat;
int m_errorCode;
+ char* m_errorStr;
// for handling repeated messages
unsigned m_count_repeated_messages;
diff --git a/ndb/include/logger/Logger.hpp b/ndb/include/logger/Logger.hpp
index ee762098fb6..3414468d42d 100644
--- a/ndb/include/logger/Logger.hpp
+++ b/ndb/include/logger/Logger.hpp
@@ -178,8 +178,11 @@ public:
* Add a new handler
*
* @param logstring string describing the handler to add
+ * @param err OS errno in event of error
+ * @param len max length of errStr buffer
+ * @param errStr logger error string in event of error
*/
- bool addHandler(const BaseString &logstring);
+ bool addHandler(const BaseString &logstring, int *err, int len, char* errStr);
/**
* Remove a log handler.
diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h
index 2e3b47eb42e..9076f18c5ac 100644
--- a/ndb/include/mgmapi/mgmapi_config_parameters.h
+++ b/ndb/include/mgmapi/mgmapi_config_parameters.h
@@ -85,6 +85,11 @@
#define CFG_DB_BACKUP_DATADIR 158
#define CFG_DB_MAX_OPEN_FILES 159
+#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160 /* used from 5.1 */
+#define CFG_DB_STRING_MEMORY 161 /* used from 5.1 */
+#define CFG_DB_INITIAL_OPEN_FILES 162 /* used from 5.1 */
+
+#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */
#define CFG_NODE_ARBIT_RANK 200
#define CFG_NODE_ARBIT_DELAY 201
diff --git a/ndb/src/common/logger/FileLogHandler.cpp b/ndb/src/common/logger/FileLogHandler.cpp
index 8678b999b6f..3d29e63ac1f 100644
--- a/ndb/src/common/logger/FileLogHandler.cpp
+++ b/ndb/src/common/logger/FileLogHandler.cpp
@@ -187,6 +187,7 @@ FileLogHandler::setParam(const BaseString &param, const BaseString &value){
return setMaxSize(value);
if(param == "maxfiles")
return setMaxFiles(value);
+ setErrorStr("Invalid parameter");
return false;
}
@@ -196,16 +197,18 @@ FileLogHandler::setFilename(const BaseString &filename) {
if(m_pLogFile)
delete m_pLogFile;
m_pLogFile = new File_class(filename.c_str(), "a+");
- open();
- return true;
+ return open();
}
bool
FileLogHandler::setMaxSize(const BaseString &size) {
char *end;
long val = strtol(size.c_str(), &end, 0); /* XXX */
- if(size.c_str() == end)
+ if(size.c_str() == end || val < 0)
+ {
+ setErrorStr("Invalid file size");
return false;
+ }
if(end[0] == 'M')
val *= 1024*1024;
if(end[0] == 'k')
@@ -220,8 +223,11 @@ bool
FileLogHandler::setMaxFiles(const BaseString &files) {
char *end;
long val = strtol(files.c_str(), &end, 0);
- if(files.c_str() == end)
+ if(files.c_str() == end || val < 1)
+ {
+ setErrorStr("Invalid maximum number of files");
return false;
+ }
m_maxNoFiles = val;
return true;
@@ -230,6 +236,9 @@ FileLogHandler::setMaxFiles(const BaseString &files) {
bool
FileLogHandler::checkParams() {
if(m_pLogFile == NULL)
+ {
+ setErrorStr("Log file cannot be null.");
return false;
+ }
return true;
}
diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp
index 521bd346fd3..c11f962d4fb 100644
--- a/ndb/src/common/logger/LogHandler.cpp
+++ b/ndb/src/common/logger/LogHandler.cpp
@@ -23,7 +23,8 @@
//
LogHandler::LogHandler() :
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
- m_errorCode(0)
+ m_errorCode(0),
+ m_errorStr(NULL)
{
m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
m_count_repeated_messages= 0;
@@ -155,6 +156,19 @@ LogHandler::setErrorCode(int code)
m_errorCode = code;
}
+
+char*
+LogHandler::getErrorStr()
+{
+ return m_errorStr;
+}
+
+void
+LogHandler::setErrorStr(char* str)
+{
+ m_errorStr= str;
+}
+
bool
LogHandler::parseParams(const BaseString &_params) {
Vector<BaseString> v_args;
@@ -165,9 +179,18 @@ LogHandler::parseParams(const BaseString &_params) {
for(size_t i=0; i < v_args.size(); i++) {
Vector<BaseString> v_param_value;
if(v_args[i].split(v_param_value, "=", 2) != 2)
+ {
ret = false;
- else if (!setParam(v_param_value[0], v_param_value[1]))
- ret = false;
+ setErrorStr("Can't find key=value pair.");
+ }
+ else
+ {
+ v_param_value[0].trim(" \t");
+ if (!setParam(v_param_value[0], v_param_value[1]))
+ {
+ ret = false;
+ }
+ }
}
if(!checkParams())
diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp
index 4a48236053d..48e084a782b 100644
--- a/ndb/src/common/logger/Logger.cpp
+++ b/ndb/src/common/logger/Logger.cpp
@@ -167,7 +167,7 @@ Logger::addHandler(LogHandler* pHandler)
}
bool
-Logger::addHandler(const BaseString &logstring) {
+Logger::addHandler(const BaseString &logstring, int *err, int len, char* errStr) {
size_t i;
Vector<BaseString> logdest;
Vector<LogHandler *>loghandlers;
@@ -200,9 +200,18 @@ Logger::addHandler(const BaseString &logstring) {
handler = new ConsoleLogHandler();
if(handler == NULL)
+ {
+ snprintf(errStr,len,"Could not create log destination: %s",
+ logdest[i].c_str());
DBUG_RETURN(false);
+ }
if(!handler->parseParams(params))
+ {
+ *err= handler->getErrorCode();
+ if(handler->getErrorStr())
+ strncpy(errStr, handler->getErrorStr(), len);
DBUG_RETURN(false);
+ }
loghandlers.push_back(handler);
}
diff --git a/ndb/src/common/logger/SysLogHandler.cpp b/ndb/src/common/logger/SysLogHandler.cpp
index 5b1b8d85ca7..c7fcb102dd4 100644
--- a/ndb/src/common/logger/SysLogHandler.cpp
+++ b/ndb/src/common/logger/SysLogHandler.cpp
@@ -154,5 +154,6 @@ SysLogHandler::setFacility(const BaseString &facility) {
return true;
}
}
+ setErrorStr("Invalid syslog facility name");
return false;
}
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index 9997d365fa4..f61f01d680b 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -3774,7 +3774,7 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
req->userReference = reference();
req->varIndex = 0;
req->offset = tmp - c_startOfPages;
- req->size = sz; // Avrunda uppot
+ req->size = sz; // Round up
sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
FsAppendReq::SignalLength, JBA);
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 1d2124e1b32..776e59ea495 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -11023,7 +11023,11 @@ void Dbdih::initCommonData()
cnoReplicas = 1;
ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
- cnoReplicas = cnoReplicas > 4 ? 4 : cnoReplicas;
+ if (cnoReplicas > 4)
+ {
+ progError(__LINE__, ERR_INVALID_CONFIG,
+ "Only up to four replicas are supported. Check NoOfReplicas.");
+ }
cgcpDelay = 2000;
ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
@@ -11616,14 +11620,14 @@ void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
break;
case CheckNodeGroups::GetNodeGroupMembers: {
ok = true;
- Uint32 ownNodeGoup =
+ Uint32 ownNodeGroup =
Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
- sd->output = ownNodeGoup;
+ sd->output = ownNodeGroup;
sd->mask.clear();
NodeGroupRecordPtr ngPtr;
- ngPtr.i = ownNodeGoup;
+ ngPtr.i = ownNodeGroup;
ptrAss(ngPtr, nodeGroupRecord);
for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
jam();
@@ -11631,7 +11635,7 @@ void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
}
#if 0
for (int i = 0; i < MAX_NDB_NODES; i++) {
- if (ownNodeGoup ==
+ if (ownNodeGroup ==
Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) {
sd->mask.set(i);
}
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index fb6aa026b3b..ff7e3c32924 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -18489,60 +18489,54 @@ void
Dblqh::execCREATE_TRIG_REQ(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference tupref = calcTupBlockRef(myNodeId);
- sendSignal(tupref, GSN_CREATE_TRIG_REQ, signal, CreateTrigReq::SignalLength, JBB);
+ sendSignal(DBTUP_REF, GSN_CREATE_TRIG_REQ, signal,
+ CreateTrigReq::SignalLength, JBB);
}
void
Dblqh::execCREATE_TRIG_CONF(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference dictref = calcDictBlockRef(myNodeId);
- sendSignal(dictref, GSN_CREATE_TRIG_CONF, signal, CreateTrigConf::SignalLength, JBB);
+ sendSignal(DBDICT_REF, GSN_CREATE_TRIG_CONF, signal,
+ CreateTrigConf::SignalLength, JBB);
}
void
Dblqh::execCREATE_TRIG_REF(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference dictref = calcDictBlockRef(myNodeId);
- sendSignal(dictref, GSN_CREATE_TRIG_REF, signal, CreateTrigRef::SignalLength, JBB);
+ sendSignal(DBDICT_REF, GSN_CREATE_TRIG_REF, signal,
+ CreateTrigRef::SignalLength, JBB);
}
void
Dblqh::execDROP_TRIG_REQ(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference tupref = calcTupBlockRef(myNodeId);
- sendSignal(tupref, GSN_DROP_TRIG_REQ, signal, DropTrigReq::SignalLength, JBB);
+ sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ, signal,
+ DropTrigReq::SignalLength, JBB);
}
void
Dblqh::execDROP_TRIG_CONF(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference dictref = calcDictBlockRef(myNodeId);
- sendSignal(dictref, GSN_DROP_TRIG_CONF, signal, DropTrigConf::SignalLength, JBB);
+ sendSignal(DBDICT_REF, GSN_DROP_TRIG_CONF, signal,
+ DropTrigConf::SignalLength, JBB);
}
void
Dblqh::execDROP_TRIG_REF(Signal* signal)
{
jamEntry();
- NodeId myNodeId = getOwnNodeId();
- BlockReference dictref = calcDictBlockRef(myNodeId);
- sendSignal(dictref, GSN_DROP_TRIG_REF, signal, DropTrigRef::SignalLength, JBB);
+ sendSignal(DBDICT_REF, GSN_DROP_TRIG_REF, signal,
+ DropTrigRef::SignalLength, JBB);
}
Uint32 Dblqh::calcPageCheckSum(LogPageRecordPtr logP){
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
index 470b98fd04c..e16d3df6d8d 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
@@ -445,6 +445,7 @@ Dbtup::commitRecord(Signal* signal,
befOpPtr.p->changeMask.bitOR(attributeMask);
befOpPtr.p->gci = regOperPtr->gci;
+ befOpPtr.p->optype = opType;
operPtr.p = befOpPtr.p;
checkDetachedTriggers(signal,
befOpPtr.p,
@@ -483,6 +484,7 @@ Dbtup::commitRecord(Signal* signal,
befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC;
befOpPtr.p->gci = regOperPtr->gci;
+ befOpPtr.p->optype = opType;
operPtr.p = befOpPtr.p;
checkDetachedTriggers(signal,
befOpPtr.p,
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 3ee0dc6e750..47d156c1f9e 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -179,6 +179,8 @@ MgmtSrvr::startEventLog()
}
const char * tmp;
+ char errStr[100];
+ int err= 0;
BaseString logdest;
char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId);
NdbAutoPtr<char> tmp_aptr(clusterLog);
@@ -192,9 +194,17 @@ MgmtSrvr::startEventLog()
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
clusterLog);
}
- if(!g_eventLogger.addHandler(logdest)) {
+ errStr[0]='\0';
+ if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) {
ndbout << "Warning: could not add log destination \""
- << logdest.c_str() << "\"" << endl;
+ << logdest.c_str() << "\". Reason: ";
+ if(err)
+ ndbout << strerror(err);
+ if(err && errStr[0]!='\0')
+ ndbout << ", ";
+ if(errStr[0]!='\0')
+ ndbout << errStr;
+ ndbout << endl;
}
}
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index c5692d79e83..416e983ec14 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -959,6 +959,8 @@ int
NdbBlob::deletePartsUnknown(Uint32 part)
{
DBG("deletePartsUnknown [in] part=" << part << " count=all");
+ if (thePartSize == 0) // tinyblob
+ return 0;
static const unsigned maxbat = 256;
static const unsigned minbat = 1;
unsigned bat = minbat;
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index efbdceac5a6..4c82f718788 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -841,9 +841,6 @@ insertPk(int style)
CHK(g_con->execute(NoCommit) == 0);
CHK(writeBlobData(tup) == 0);
}
- // just another trap
- if (urandom(10) == 0)
- CHK(g_con->execute(NoCommit) == 0);
if (++n == g_opt.m_batch) {
CHK(g_con->execute(Commit) == 0);
g_ndb->closeTransaction(g_con);
@@ -965,21 +962,31 @@ static int
deletePk()
{
DBG("--- deletePk ---");
+ unsigned n = 0;
+ CHK((g_con = g_ndb->startTransaction()) != 0);
for (unsigned k = 0; k < g_opt.m_rows; k++) {
Tup& tup = g_tups[k];
DBG("deletePk pk1=" << hex << tup.m_pk1);
- CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->deleteTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
if (g_opt.m_pk2len != 0)
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
- CHK(g_con->execute(Commit) == 0);
- g_ndb->closeTransaction(g_con);
+ if (++n == g_opt.m_batch) {
+ CHK(g_con->execute(Commit) == 0);
+ g_ndb->closeTransaction(g_con);
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ n = 0;
+ }
g_opr = 0;
- g_con = 0;
tup.m_exists = false;
}
+ if (n != 0) {
+ CHK(g_con->execute(Commit) == 0);
+ n = 0;
+ }
+ g_ndb->closeTransaction(g_con);
+ g_con = 0;
return 0;
}
@@ -1082,19 +1089,27 @@ static int
deleteIdx()
{
DBG("--- deleteIdx ---");
+ unsigned n = 0;
+ CHK((g_con = g_ndb->startTransaction()) != 0);
for (unsigned k = 0; k < g_opt.m_rows; k++) {
Tup& tup = g_tups[k];
DBG("deleteIdx pk1=" << hex << tup.m_pk1);
- CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
CHK(g_opx->deleteTuple() == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
- CHK(g_con->execute(Commit) == 0);
- g_ndb->closeTransaction(g_con);
+ if (++n == g_opt.m_batch) {
+ CHK(g_con->execute(Commit) == 0);
+ g_ndb->closeTransaction(g_con);
+ CHK((g_con = g_ndb->startTransaction()) != 0);
+ n = 0;
+ }
g_opx = 0;
- g_con = 0;
tup.m_exists = false;
}
+ if (n != 0) {
+ CHK(g_con->execute(Commit) == 0);
+ n = 0;
+ }
return 0;
}
@@ -1225,20 +1240,49 @@ deleteScan(bool idx)
CHK(g_ops->getValue("PK2", tup.m_pk2) != 0);
CHK(g_con->execute(NoCommit) == 0);
unsigned rows = 0;
+ unsigned n = 0;
while (1) {
int ret;
tup.m_pk1 = (Uint32)-1;
memset(tup.m_pk2, 'x', g_opt.m_pk2len);
- CHK((ret = rs->nextResult()) == 0 || ret == 1);
+ CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
- DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1);
- CHK(rs->deleteTuple() == 0);
- CHK(g_con->execute(NoCommit) == 0);
- Uint32 k = tup.m_pk1 - g_opt.m_pk1off;
- CHK(k < g_opt.m_rows && g_tups[k].m_exists);
- g_tups[k].m_exists = false;
- rows++;
+ while (1) {
+ DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1);
+ Uint32 k = tup.m_pk1 - g_opt.m_pk1off;
+ CHK(k < g_opt.m_rows && g_tups[k].m_exists);
+ g_tups[k].m_exists = false;
+ CHK(rs->deleteTuple() == 0);
+ rows++;
+ tup.m_pk1 = (Uint32)-1;
+ memset(tup.m_pk2, 'x', g_opt.m_pk2len);
+ CHK((ret = rs->nextResult(false)) == 0 || ret == 1 || ret == 2);
+ if (++n == g_opt.m_batch || ret == 2) {
+ DBG("execute batch: n=" << n << " ret=" << ret);
+ switch (0) {
+ case 0: // works normally
+ CHK(g_con->execute(NoCommit) == 0);
+ CHK(true || g_con->restart() == 0);
+ break;
+ case 1: // nonsense - g_con is invalid for 2nd batch
+ CHK(g_con->execute(Commit) == 0);
+ CHK(true || g_con->restart() == 0);
+ break;
+ case 2: // DBTC sendSignalErrorRefuseLab
+ CHK(g_con->execute(NoCommit) == 0);
+ CHK(g_con->restart() == 0);
+ break;
+ case 3: // 266 time-out
+ CHK(g_con->execute(Commit) == 0);
+ CHK(g_con->restart() == 0);
+ break;
+ }
+ n = 0;
+ }
+ if (ret == 2)
+ break;
+ }
}
CHK(g_con->execute(Commit) == 0);
g_ndb->closeTransaction(g_con);
@@ -1488,13 +1532,16 @@ testperf()
// insert char (one trans)
{
DBG("--- insert char ---");
+ char b[20];
t1.on();
CHK((g_con = g_ndb->startTransaction()) != 0);
for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
CHK(g_opr->insertTuple() == 0);
CHK(g_opr->equal(cA, (char*)&k) == 0);
- CHK(g_opr->setValue(cB, "b") == 0);
+ memset(b, 0x20, sizeof(b));
+ b[0] = 'b';
+ CHK(g_opr->setValue(cB, b) == 0);
CHK(g_con->execute(NoCommit) == 0);
}
t1.off(g_opt.m_rowsperf);
@@ -1531,12 +1578,15 @@ testperf()
{
DBG("--- insert for read test ---");
unsigned n = 0;
+ char b[20];
CHK((g_con = g_ndb->startTransaction()) != 0);
for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) {
CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0);
CHK(g_opr->insertTuple() == 0);
CHK(g_opr->equal(cA, (char*)&k) == 0);
- CHK(g_opr->setValue(cB, "b") == 0);
+ memset(b, 0x20, sizeof(b));
+ b[0] = 'b';
+ CHK(g_opr->setValue(cB, b) == 0);
CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0);
CHK((g_bh1->setValue("c", 1) == 0));
if (++n == g_opt.m_batch) {
@@ -1570,7 +1620,7 @@ testperf()
a = (Uint32)-1;
b[0] = 0;
CHK(g_con->execute(NoCommit) == 0);
- CHK(a == k && strcmp(b, "b") == 0);
+ CHK(a == k && b[0] == 'b');
}
CHK(g_con->execute(Commit) == 0);
t1.off(g_opt.m_rowsperf);
@@ -1596,7 +1646,7 @@ testperf()
CHK(g_con->execute(NoCommit) == 0);
Uint32 m = 20;
CHK(g_bh1->readData(c, m) == 0);
- CHK(a == k && m == 1 && strcmp(c, "c") == 0);
+ CHK(a == k && m == 1 && c[0] == 'c');
}
CHK(g_con->execute(Commit) == 0);
t2.off(g_opt.m_rowsperf);
@@ -1629,7 +1679,7 @@ testperf()
CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
- CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0);
+ CHK(a < g_opt.m_rowsperf && b[0] == 'b');
n++;
}
CHK(n == g_opt.m_rowsperf);
@@ -1661,7 +1711,7 @@ testperf()
break;
Uint32 m = 20;
CHK(g_bh1->readData(c, m) == 0);
- CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0);
+ CHK(a < g_opt.m_rowsperf && m == 1 && c[0] == 'c');
n++;
}
CHK(n == g_opt.m_rowsperf);
diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp
index 21e0c2ac089..d4a07fdf505 100644
--- a/ndb/tools/delete_all.cpp
+++ b/ndb/tools/delete_all.cpp
@@ -22,7 +22,8 @@
#include <NdbSleep.h>
#include <NDBT.hpp>
-static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism=240);
+static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
+ bool commit_across_open_cursor, int parallelism=240);
NDB_STD_OPTS_VARS;
@@ -81,8 +82,18 @@ int main(int argc, char** argv){
ndbout << " Table " << argv[i] << " does not exist!" << endl;
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+ // Check if we have any blobs
+ bool commit_across_open_cursor = true;
+ for (int j = 0; j < pTab->getNoOfColumns(); j++) {
+ NdbDictionary::Column::Type t = pTab->getColumn(j)->getType();
+ if (t == NdbDictionary::Column::Blob ||
+ t == NdbDictionary::Column::Text) {
+ commit_across_open_cursor = false;
+ break;
+ }
+ }
ndbout << "Deleting all from " << argv[i] << "...";
- if(clear_table(&MyNdb, pTab) == NDBT_FAILED){
+ if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){
res = NDBT_FAILED;
ndbout << "FAILED" << endl;
}
@@ -91,7 +102,8 @@ int main(int argc, char** argv){
}
-int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism)
+int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
+ bool commit_across_open_cursor, int parallelism)
{
// Scan all records exclusive and delete
// them one by one
@@ -153,8 +165,12 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism)
} while((check = rs->nextResult(false)) == 0);
if(check != -1){
- check = pTrans->execute(Commit);
- pTrans->restart();
+ if (commit_across_open_cursor) {
+ check = pTrans->execute(Commit);
+ pTrans->restart(); // new tx id
+ } else {
+ check = pTrans->execute(NoCommit);
+ }
}
err = pTrans->getNdbError();
@@ -180,6 +196,10 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism)
}
goto failed;
}
+ if (! commit_across_open_cursor && pTrans->execute(Commit) != 0) {
+ err = pTrans->getNdbError();
+ goto failed;
+ }
pNdb->closeTransaction(pTrans);
return NDBT_OK;
}
diff --git a/ndb/tools/ndb_error_reporter b/ndb/tools/ndb_error_reporter
new file mode 100755
index 00000000000..2b5aadb6171
--- /dev/null
+++ b/ndb/tools/ndb_error_reporter
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+if(@ARGV < 1)
+{
+ print STDERR "Usage:\n";
+ print STDERR "\tndb_error_reporter config.ini [username] [--fs]\n\n";
+ print STDERR "\tusername is a user that you can use to ssh into\n";
+ print STDERR "\t all of your nodes with.\n\n";
+ print STDERR "\t--fs means include the filesystems in the report\n";
+ print STDERR "\t WARNING: This may require a lot of disk space.\n";
+ print STDERR "\t Only use this option when asked to.\n\n";
+ exit(1);
+}
+
+my $config_file= $ARGV[0];
+my $config_get_fs= 0;
+my $config_username= '';
+if(defined($ARGV[1]))
+{
+ $config_get_fs= 1 if $ARGV[1] eq '--fs';
+ $config_username= $ARGV[1].'@' if $ARGV[1] ne '--fs';
+ $config_get_fs= (defined $ARGV[2] && $ARGV[2] eq '--fs')?1:$config_get_fs;
+}
+
+if(!stat($config_file))
+{
+ print STDERR "Cannot open configuration file.\n\n";
+ exit(1);
+}
+
+my @nodes= split ' ',`ndb_config --config-file=$ARGV[0] --nodes --query=id --type=ndbd`;
+
+push @nodes, split ' ',`ndb_config --config-file=$ARGV[0] --nodes --query=id --type=ndb_mgmd`;
+
+sub config {
+ my $nodeid= shift;
+ my $query= shift;
+ my $res= `ndb_config --config-file=$ARGV[0] --id=$nodeid --query=$query`;
+ chomp $res;
+ $res;
+}
+
+my @t= localtime();
+my $reportdir= sprintf('ndb_error_report_%u%02u%02u%02u%02u%02u',
+ ($t[5]+1900),($t[4]+1),$t[3],$t[2],$t[1],$t[0]);
+
+if(stat($reportdir) || stat($reportdir.'tar.bz2'))
+{
+ print STDERR "It looks like another ndb_error_report process is running.\n";
+ print STDERR "If that is not the case, remove the ndb_error_report directory";
+ print STDERR " and run ndb_error_report again.\n\n";
+ exit(1);
+}
+
+mkdir($reportdir);
+
+foreach my $node (@nodes)
+{
+ print "\n\n Copying data from node $node".
+ (($config_get_fs)?" with filesystem":"").
+ "\n\n";
+ my $recurse= ($config_get_fs)?'-r ':'';
+ system 'scp '.$recurse.$config_username.config($node,'host').
+ ':'.config($node,'datadir')."/ndb_".$node."* ".
+ "$reportdir/\n";
+}
+
+print "\n\n Copying configuration file...\n\n\t$config_file\n\n";
+system "cp $config_file $reportdir/";
+
+my $r = system 'bzip2 2>&1 > /dev/null < /dev/null';
+my $outfile;
+if($r==0)
+{
+ $outfile= "$reportdir.tar.bz2";
+ system "tar c $reportdir|bzip2 > $outfile";
+}
+else
+{
+ $outfile= "$reportdir.tar.gz";
+ system "tar c $reportdir|gzip > $outfile";
+}
+
+system "rm -rf $reportdir";
+
+print "\n\nPlease attach $outfile to your error report\n\n";
diff --git a/ndb/tools/ndb_size.pl b/ndb/tools/ndb_size.pl
index ece0901e0b2..c285a7590fd 100644
--- a/ndb/tools/ndb_size.pl
+++ b/ndb/tools/ndb_size.pl
@@ -146,9 +146,9 @@ foreach(@{$tables})
elsif($type =~ /varchar/ || $type =~ /varbinary/)
{
my $fixed= 1+$size;
- my @dynamic=$dbh->selectrow_array("select avg(length("
- .$dbh->quote($name)
- .")) from `".$table.'`');
+ my @dynamic=$dbh->selectrow_array("select avg(length(`"
+ .$name
+ ."`)) from `".$table.'`');
$dynamic[0]=0 if !$dynamic[0];
@realsize= ($fixed,$fixed,ceil($dynamic[0]));
}
diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c
index a307b52bb7e..8e8f5111241 100644
--- a/netware/mysqld_safe.c
+++ b/netware/mysqld_safe.c
@@ -258,11 +258,11 @@ void finish_defaults()
void read_defaults(arg_list_t *pal)
{
arg_list_t al;
- char defaults_file[PATH_MAX];
+ char defaults_file[PATH_MAX];
char mydefaults[PATH_MAX];
char line[PATH_MAX];
FILE *fp;
-
+
// defaults output file
snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
remove(defaults_file);
@@ -270,7 +270,7 @@ void read_defaults(arg_list_t *pal)
// mysqladmin file
snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
- // args
+ // args
init_args(&al);
add_arg(&al, mydefaults);
if (default_option[0])
@@ -279,11 +279,11 @@ void read_defaults(arg_list_t *pal)
add_arg(&al, "server");
add_arg(&al, "mysqld_safe");
add_arg(&al, "safe_mysqld");
-
+
spawn(mydefaults, &al, TRUE, NULL, defaults_file, NULL);
-
+
free_args(&al);
-
+
// gather defaults
if ((fp= fopen(defaults_file, "r")) != NULL)
{
diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh
index 2e93ebcb007..2e312e0c3cf 100644
--- a/scripts/make_win_src_distribution.sh
+++ b/scripts/make_win_src_distribution.sh
@@ -199,7 +199,7 @@ copy_dir_files()
print_debug "Creating directory '$arg'"
mkdir $BASE/$arg
fi
- for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def *.hpp *.dsp *.dsw \
+ for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def *.hpp \
README INSTALL* LICENSE AUTHORS NEWS ChangeLog \
*.inc *.test *.result *.pem Moscow_leap des_key_file \
*.vcproj *.sln *.dat *.000001 *.require *.opt
@@ -340,7 +340,7 @@ mv $BASE/sql/sql_yacc.cpp-new $BASE/sql/sql_yacc.cpp
#
# Search the tree for plain text files and adapt the line end marker
#
-find $BASE \( -name "*.dsp" -o -name "*.dsw" -o -name "*.cnf" -o -name "*.ini" \
+find $BASE \( -name "*.cnf" -o -name "*.ini" \
-o -name COPYING -o -name ChangeLog -o -name EXCEPTIONS-CLIENT \
-o -name "INSTALL*" -o -name LICENSE -o -name "README*" \
-o -name "*.vcproj" -o -name "*.sln" \) -type f -print \
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 7fff4cbb731..4a6f380494f 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -718,9 +718,6 @@ sub usage
print <<EOF;
$my_progname version $VER by Jani Tolonen
-This software comes with ABSOLUTELY NO WARRANTY. This is free software,
-and you are welcome to modify and redistribute it under the GPL license.
-
Description:
$my_progname can be used to start, or stop any number of separate
mysqld processes running in different TCP/IP ports and UNIX sockets.
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 40d7799e274..3c46a944ba9 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -514,18 +514,34 @@ fractional:
/* Get fractional second part */
if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
{
- uint field_length=5;
+ int field_length= 5;
str++; value=(uint) (uchar) (*str - '0');
- while (++str != end &&
- my_isdigit(&my_charset_latin1,str[0]) &&
- field_length--)
- value=value*10 + (uint) (uchar) (*str - '0');
- if (field_length)
+ while (++str != end && my_isdigit(&my_charset_latin1, *str))
+ {
+ if (field_length-- > 0)
+ value= value*10 + (uint) (uchar) (*str - '0');
+ }
+ if (field_length > 0)
value*= (long) log_10_int[field_length];
+ else if (field_length < 0)
+ *was_cut= 1;
date[4]=value;
}
else
date[4]=0;
+
+ /* Check for exponent part: E<gigit> | E<sign><digit> */
+ /* (may occur as result of %g formatting of time value) */
+ if ((end - str) > 1 &&
+ (*str == 'e' || *str == 'E') &&
+ (my_isdigit(&my_charset_latin1, str[1]) ||
+ ((str[1] == '-' || str[1] == '+') &&
+ (end - str) > 2 &&
+ my_isdigit(&my_charset_latin1, str[2]))))
+ {
+ *was_cut= 1;
+ return 1;
+ }
if (internal_format_positions[7] != 255)
{
diff --git a/sql/field.cc b/sql/field.cc
index abb5297f458..b1d9167aee2 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6949,11 +6949,11 @@ uint32 Field_blob::max_length()
switch (packlength)
{
case 1:
- return 255;
+ return 255 * field_charset->mbmaxlen;
case 2:
- return 65535;
+ return 65535 * field_charset->mbmaxlen;
case 3:
- return 16777215;
+ return 16777215 * field_charset->mbmaxlen;
case 4:
return (uint32) 4294967295U;
default:
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index f8c2e6cc338..ab0ab5d8b64 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -68,7 +68,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
ha_heap::info(), which is always called before key statistics are
used.
*/
- key_stats_ok= FALSE;
+ key_stat_version= file->s->key_stat_version-1;
}
return (file ? 0 : 1);
}
@@ -114,14 +114,21 @@ void ha_heap::update_key_stats()
continue;
if (key->algorithm != HA_KEY_ALG_BTREE)
{
- ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
- key->rec_per_key[key->key_parts-1]=
- hash_buckets ? file->s->records/hash_buckets : 0;
+ if (key->flags & HA_NOSAME)
+ key->rec_per_key[key->key_parts-1]= 1;
+ else
+ {
+ ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
+ uint no_records= hash_buckets ? file->s->records/hash_buckets : 2;
+ if (no_records < 2)
+ no_records= 2;
+ key->rec_per_key[key->key_parts-1]= no_records;
+ }
}
}
records_changed= 0;
/* At the end of update_key_stats() we can proudly claim they are OK. */
- key_stats_ok= TRUE;
+ key_stat_version= file->s->key_stat_version;
}
int ha_heap::write_row(byte * buf)
@@ -135,7 +142,13 @@ int ha_heap::write_row(byte * buf)
res= heap_write(file,buf);
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -148,7 +161,13 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
res= heap_update(file,old_data,new_data);
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -159,7 +178,13 @@ int ha_heap::delete_row(const byte * buf)
res= heap_delete(file,buf);
if (!res && table->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -277,7 +302,7 @@ void ha_heap::info(uint flag)
have to update the key statistics. Hoping that a table lock is now
in place.
*/
- if (! key_stats_ok)
+ if (key_stat_version != file->s->key_stat_version)
update_key_stats();
}
@@ -290,7 +315,13 @@ int ha_heap::delete_all_rows()
{
heap_clear(file);
if (table->tmp_table == NO_TMP_TABLE)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return 0;
}
@@ -451,9 +482,14 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
return HA_POS_ERROR; // Can only use exact keys
else
{
- /* Assert that info() did run. We need current statistics here. */
- DBUG_ASSERT(key_stats_ok);
- return key->rec_per_key[key->key_parts-1];
+ if (records <= 1)
+ return records;
+ else
+ {
+ /* Assert that info() did run. We need current statistics here. */
+ DBUG_ASSERT(key_stat_version == file->s->key_stat_version);
+ return key->rec_per_key[key->key_parts-1];
+ }
}
}
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index cbe2474492d..0a087fde1b0 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -29,10 +29,10 @@ class ha_heap: public handler
key_map btree_keys;
/* number of records changed since last statistics update */
uint records_changed;
- bool key_stats_ok;
+ uint key_stat_version;
public:
ha_heap(TABLE *table): handler(table), file(0), records_changed(0),
- key_stats_ok(0) {}
+ key_stat_version(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
const char *index_type(uint inx)
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index b188cfcba21..d24587e23ea 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2016,6 +2016,22 @@ get_innobase_type_from_mysql_type(
}
/***********************************************************************
+Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
+storage format. */
+inline
+void
+innobase_write_to_2_little_endian(
+/*==============================*/
+ byte* buf, /* in: where to store */
+ ulint val) /* in: value to write, must be < 64k */
+{
+ ut_a(val < 256 * 256);
+
+ buf[0] = (byte)(val & 0xFF);
+ buf[1] = (byte)(val / 256);
+}
+
+/***********************************************************************
Stores a key value for a row to a buffer. */
uint
@@ -2034,8 +2050,6 @@ ha_innobase::store_key_val_for_row(
char* buff_start = buff;
enum_field_types mysql_type;
Field* field;
- ulint blob_len;
- byte* blob_data;
ibool is_null;
DBUG_ENTER("store_key_val_for_row");
@@ -2084,13 +2098,25 @@ ha_innobase::store_key_val_for_row(
|| mysql_type == FIELD_TYPE_BLOB
|| mysql_type == FIELD_TYPE_LONG_BLOB) {
+ CHARSET_INFO* cs;
+ ulint key_len;
+ ulint len;
+ ulint true_len;
+ int error=0;
+ ulint blob_len;
+ byte* blob_data;
+
ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
+ key_len = key_part->length;
+
if (is_null) {
- buff += key_part->length + 2;
+ buff += key_len + 2;
continue;
}
+
+ cs = field->charset();
blob_data = row_mysql_read_blob_ref(&blob_len,
(byte*) (record
@@ -2099,29 +2125,108 @@ ha_innobase::store_key_val_for_row(
ut_a(get_field_offset(table, field)
== key_part->offset);
- if (blob_len > key_part->length) {
- blob_len = key_part->length;
+
+ true_len = blob_len;
+
+ /* For multi byte character sets we need to calculate
+ the true length of the key */
+
+ if (key_len > 0 && cs->mbmaxlen > 1) {
+ true_len = (ulint) cs->cset->well_formed_len(cs,
+ (const char *) blob_data,
+ (const char *) blob_data
+ + blob_len,
+ key_len / cs->mbmaxlen,
+ &error);
+ }
+
+ /* All indexes on BLOB and TEXT are column prefix
+ indexes, and we may need to truncate the data to be
+ stored in the key value: */
+
+ if (true_len > key_len) {
+ true_len = key_len;
}
/* MySQL reserves 2 bytes for the length and the
storage of the number is little-endian */
- ut_a(blob_len < 256);
- *((byte*)buff) = (byte)blob_len;
+ innobase_write_to_2_little_endian(
+ (byte*)buff, true_len);
buff += 2;
- memcpy(buff, blob_data, blob_len);
+ memcpy(buff, blob_data, true_len);
- buff += key_part->length;
+ /* Note that we always reserve the maximum possible
+ length of the BLOB prefix in the key value. */
+
+ buff += key_len;
} else {
+ /* Here we handle all other data types except the
+ true VARCHAR, BLOB and TEXT. Note that the column
+ value we store may be also in a column prefix
+ index. */
+
+ CHARSET_INFO* cs;
+ ulint true_len;
+ ulint key_len;
+ const mysql_byte* src_start;
+ int error=0;
+ enum_field_types real_type;
+
+ key_len = key_part->length;
+
if (is_null) {
- buff += key_part->length;
+ buff += key_len;
continue;
}
- memcpy(buff, record + key_part->offset,
- key_part->length);
- buff += key_part->length;
+
+ src_start = record + key_part->offset;
+ real_type = field->real_type();
+ true_len = key_len;
+
+ /* Character set for the field is defined only
+ to fields whose type is string and real field
+ type is not enum or set. For these fields check
+ if character set is multi byte. */
+
+ if (real_type != FIELD_TYPE_ENUM
+ && real_type != FIELD_TYPE_SET
+ && ( mysql_type == MYSQL_TYPE_VAR_STRING
+ || mysql_type == MYSQL_TYPE_STRING)) {
+
+ cs = field->charset();
+
+ /* For multi byte character sets we need to
+ calculate the true length of the key */
+
+ if (key_len > 0 && cs->mbmaxlen > 1) {
+
+ true_len = (ulint)
+ cs->cset->well_formed_len(cs,
+ (const char *)src_start,
+ (const char *)src_start
+ + key_len,
+ key_len / cs->mbmaxlen,
+ &error);
+ }
+ }
+
+ memcpy(buff, src_start, true_len);
+ buff += true_len;
+
+ /* Pad the unused space with spaces. Note that no
+ padding is ever needed for UCS-2 because in MySQL,
+ all UCS2 characters are 2 bytes, as MySQL does not
+ support surrogate pairs, which are needed to represent
+ characters in the range U+10000 to U+10FFFF. */
+
+ if (true_len < key_len) {
+ ulint pad_len = key_len - true_len;
+ memset(buff, ' ', pad_len);
+ buff += pad_len;
+ }
}
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 594551b918a..6a80ba83017 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3046,9 +3046,26 @@ int ha_ndbcluster::end_bulk_insert()
"rows_inserted:%d, bulk_insert_rows: %d",
(int) m_rows_inserted, (int) m_bulk_insert_rows));
m_bulk_insert_not_flushed= FALSE;
- if (execute_no_commit(this,trans) != 0) {
- no_uncommitted_rows_execute_failure();
- my_errno= error= ndb_err(trans);
+ if (m_transaction_on)
+ {
+ if (execute_no_commit(this, trans) != 0)
+ {
+ no_uncommitted_rows_execute_failure();
+ my_errno= error= ndb_err(trans);
+ }
+ }
+ else
+ {
+ if (execute_commit(this, trans) != 0)
+ {
+ no_uncommitted_rows_execute_failure();
+ my_errno= error= ndb_err(trans);
+ }
+ else
+ {
+ int res= trans->restart();
+ DBUG_ASSERT(res == 0);
+ }
}
}
@@ -4867,7 +4884,7 @@ bool ha_ndbcluster::low_byte_first() const
}
bool ha_ndbcluster::has_transactions()
{
- return m_transaction_on;
+ return TRUE;
}
const char* ha_ndbcluster::index_type(uint key_number)
{
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2c76c7ec7b3..f9aa220c181 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2524,6 +2524,12 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
return 0;
}
+void Item_func_like::cleanup()
+{
+ canDoTurboBM= FALSE;
+ Item_bool_func2::cleanup();
+}
+
#ifdef USE_REGEX
bool
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 045566a46d5..ade09113c63 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -911,6 +911,7 @@ public:
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "like"; }
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
+ void cleanup();
};
#ifdef USE_REGEX
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d0a68e9f93e..c82d505c1bb 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -359,10 +359,19 @@ String *Item_num_func::val_str(String *str)
void Item_func::fix_num_length_and_dec()
{
+ uint fl_length= 0;
decimals=0;
for (uint i=0 ; i < arg_count ; i++)
+ {
set_if_bigger(decimals,args[i]->decimals);
+ set_if_bigger(fl_length, args[i]->max_length);
+ }
max_length=float_length(decimals);
+ if (fl_length > max_length)
+ {
+ decimals= NOT_FIXED_DEC;
+ max_length= float_length(NOT_FIXED_DEC);
+ }
}
Item *Item_func::get_tmp_table_item(THD *thd)
diff --git a/sql/item_func.h b/sql/item_func.h
index 2c4976d1152..51f9d3fb36f 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1056,16 +1056,13 @@ public:
if (!master && ft_handler)
{
ft_handler->please->close_search(ft_handler);
- ft_handler=0;
- if (join_key)
- table->file->ft_handler=0;
- table->fulltext_searched=0;
}
if (concat)
{
delete concat;
concat= 0;
}
+ ft_handler= 0;
DBUG_VOID_RETURN;
}
enum Functype functype() const { return FT_FUNC; }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 60cb3348590..04765e18191 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -131,11 +131,13 @@ String *Item_func_sha::val_str(String *str)
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
/* Temporary buffer to store 160bit digest */
uint8 digest[SHA1_HASH_SIZE];
- sha1_reset(&context); /* We do not have to check for error here */
+ mysql_sha1_reset(&context); /* We do not have to check for error here */
/* No need to check error as the only case would be too long message */
- sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length());
+ mysql_sha1_input(&context,
+ (const unsigned char *) sptr->ptr(), sptr->length());
/* Ensure that memory is free and we got result */
- if (!( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest))))
+ if (!( str->alloc(SHA1_HASH_SIZE*2) ||
+ (mysql_sha1_result(&context,digest))))
{
sprintf((char *) str->ptr(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index eb58b180ed7..d6b57464d59 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2750,9 +2750,9 @@ void Item_func_str_to_date::fix_length_and_dec()
cached_field_type= MYSQL_TYPE_STRING;
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
- if ((const_item= args[1]->const_item()))
+ format= args[1]->val_str(&format_str);
+ if (!args[1]->null_value && (const_item= args[1]->const_item()))
{
- format= args[1]->val_str(&format_str);
cached_format_type= get_date_time_result_type(format->ptr(),
format->length());
switch (cached_format_type) {
diff --git a/sql/lock.cc b/sql/lock.cc
index 944c36d4d1e..f65ce69bb80 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -394,6 +394,88 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
}
+/*
+ Find duplicate lock in tables.
+
+ SYNOPSIS
+ mysql_lock_have_duplicate()
+ thd The current thread.
+ table The table to check for duplicate lock.
+ tables The list of tables to search for the dup lock.
+
+ NOTE
+ This is mainly meant for MERGE tables in INSERT ... SELECT
+ situations. The 'real', underlying tables can be found only after
+ the table is opened. The easier way is to check this after the
+ tables are locked.
+
+ RETURN
+ 1 A table from 'tables' matches a lock on 'table'.
+ 0 No duplicate lock is present.
+ -1 Error.
+*/
+
+int mysql_lock_have_duplicate(THD *thd, TABLE *table, TABLE_LIST *tables)
+{
+ uint count;
+ MYSQL_LOCK *sql_lock1;
+ MYSQL_LOCK *sql_lock2;
+ TABLE **tables1= &table;
+ TABLE **tables2;
+ TABLE **table_ptr;
+ TABLE_LIST *tablist2;
+ TABLE *write_lock_used;
+ THR_LOCK_DATA **lock_data1;
+ THR_LOCK_DATA **end_data1;
+ THR_LOCK_DATA **lock_data2;
+ THR_LOCK_DATA **end_data2;
+ THR_LOCK *lock1;
+ DBUG_ENTER("mysql_lock_have_duplicate");
+
+ if (! (sql_lock1= get_lock_data(thd, tables1, 1, 1, &write_lock_used)))
+ goto err0;
+
+ count=0;
+ for (tablist2 = tables; tablist2; tablist2= tablist2->next)
+ count++;
+ if (! (tables2= (TABLE**) sql_alloc(sizeof(TABLE*) * count)))
+ goto err1;
+ table_ptr= tables2;
+ for (tablist2 = tables; tablist2; tablist2= tablist2->next)
+ *(table_ptr++)= tablist2->table;
+ if (! (sql_lock2= get_lock_data(thd, tables2, count, 1, &write_lock_used)))
+ goto err1;
+
+ count= 1;
+ for (lock_data1= sql_lock1->locks,
+ end_data1= lock_data1 + sql_lock1->lock_count;
+ lock_data1 < end_data1;
+ lock_data1++)
+ {
+ lock1= (*lock_data1)->lock;
+ for (lock_data2= sql_lock2->locks,
+ end_data2= lock_data2 + sql_lock2->lock_count;
+ lock_data2 < end_data2;
+ lock_data2++)
+ {
+ if ((*lock_data2)->lock == lock1)
+ goto end;
+ }
+ }
+ count= 0;
+
+ end:
+ my_free((gptr) sql_lock2, MYF(0));
+ my_free((gptr) sql_lock1, MYF(0));
+ DBUG_RETURN(count);
+
+ err1:
+ my_free((gptr) sql_lock1, MYF(0));
+ err0:
+ DBUG_RETURN(-1);
+}
+
+
/* unlock a set of external */
static int unlock_external(THD *thd, TABLE **table,uint count)
@@ -430,6 +512,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
MYSQL_LOCK *sql_lock;
THR_LOCK_DATA **locks;
TABLE **to;
+ DBUG_ENTER("get_lock_data");
*write_lock_used=0;
for (i=tables=lock_count=0 ; i < count ; i++)
@@ -445,7 +528,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
my_malloc(sizeof(*sql_lock)+
sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count,
MYF(0))))
- return 0;
+ DBUG_RETURN(0);
locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
to=sql_lock->table=(TABLE**) (locks+tables);
sql_lock->table_count=lock_count;
@@ -465,7 +548,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name);
my_free((gptr) sql_lock,MYF(0));
- return 0;
+ DBUG_RETURN(0);
}
}
THR_LOCK_DATA **org_locks = locks;
@@ -475,7 +558,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
for ( ; org_locks != locks ; org_locks++)
(*org_locks)->debug_print_param= (void *) table;
}
- return sql_lock;
+ DBUG_RETURN(sql_lock);
}
@@ -558,6 +641,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
char key[MAX_DBKEY_LENGTH];
char *db= table_list->db;
uint key_length;
+ HASH_SEARCH_STATE state;
DBUG_ENTER("lock_table_name");
DBUG_PRINT("enter",("db: %s name: %s", db, table_list->real_name));
@@ -568,9 +652,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
/* Only insert the table if we haven't insert it already */
- for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
+ for (table=(TABLE*) hash_first(&open_cache, (byte*)key, key_length, &state);
table ;
- table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
+ table = (TABLE*) hash_next(&open_cache, (byte*)key, key_length, &state))
if (table->in_use == thd)
DBUG_RETURN(0);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index c128fac8d9e..429a71b4437 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1022,6 +1022,7 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table);
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
+int mysql_lock_have_duplicate(THD *thd, TABLE *table, TABLE_LIST *tables);
bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a38763ac9a8..cce48cc0d54 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3089,6 +3089,12 @@ int main(int argc, char **argv)
}
}
#endif
+#ifdef __NETWARE__
+ /* Increasing stacksize of threads on NetWare */
+
+ pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
+#endif
+
thread_stack_min=thread_stack - STACK_MIN_SIZE;
(void) thr_setconcurrency(concurrency); // 10 by default
@@ -4370,7 +4376,7 @@ Disable with --skip-bdb (will save memory).",
{"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
- "Don't use client side character set value sent during handshake.",
+ "Don't ignore client side character set value sent during handshake.",
(gptr*) &opt_character_set_client_handshake,
(gptr*) &opt_character_set_client_handshake,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
@@ -5950,7 +5956,7 @@ static void mysql_init_variables(void)
#else
have_openssl=SHOW_OPTION_NO;
#endif
-#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
+#ifdef HAVE_BROKEN_REALPATH
have_symlink=SHOW_OPTION_NO;
#else
have_symlink=SHOW_OPTION_YES;
@@ -6631,7 +6637,7 @@ static void get_options(int argc,char **argv)
usage();
exit(0);
}
-#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
+#if defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
have_symlink=SHOW_OPTION_NO;
diff --git a/sql/password.c b/sql/password.c
index 04b3a46bd48..94b9dc440be 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -392,15 +392,15 @@ make_scrambled_password(char *to, const char *password)
SHA1_CONTEXT sha1_context;
uint8 hash_stage2[SHA1_HASH_SIZE];
- sha1_reset(&sha1_context);
+ mysql_sha1_reset(&sha1_context);
/* stage 1: hash password */
- sha1_input(&sha1_context, (uint8 *) password, strlen(password));
- sha1_result(&sha1_context, (uint8 *) to);
+ mysql_sha1_input(&sha1_context, (uint8 *) password, strlen(password));
+ mysql_sha1_result(&sha1_context, (uint8 *) to);
/* stage 2: hash stage1 output */
- sha1_reset(&sha1_context);
- sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE);
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE);
/* separate buffer is used to pass 'to' in octet2hex */
- sha1_result(&sha1_context, hash_stage2);
+ mysql_sha1_result(&sha1_context, hash_stage2);
/* convert hash_stage2 to hex string */
*to++= PVERSION41_CHAR;
octet2hex(to, hash_stage2, SHA1_HASH_SIZE);
@@ -431,20 +431,20 @@ scramble(char *to, const char *message, const char *password)
uint8 hash_stage1[SHA1_HASH_SIZE];
uint8 hash_stage2[SHA1_HASH_SIZE];
- sha1_reset(&sha1_context);
+ mysql_sha1_reset(&sha1_context);
/* stage 1: hash password */
- sha1_input(&sha1_context, (uint8 *) password, strlen(password));
- sha1_result(&sha1_context, hash_stage1);
+ mysql_sha1_input(&sha1_context, (uint8 *) password, strlen(password));
+ mysql_sha1_result(&sha1_context, hash_stage1);
/* stage 2: hash stage 1; note that hash_stage2 is stored in the database */
- sha1_reset(&sha1_context);
- sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE);
- sha1_result(&sha1_context, hash_stage2);
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, hash_stage2);
/* create crypt string as sha1(message, hash_stage2) */;
- sha1_reset(&sha1_context);
- sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
- sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
+ mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
/* xor allows 'from' and 'to' overlap: lets take advantage of it */
- sha1_result(&sha1_context, (uint8 *) to);
+ mysql_sha1_result(&sha1_context, (uint8 *) to);
my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
}
@@ -477,17 +477,17 @@ check_scramble(const char *scramble, const char *message,
uint8 buf[SHA1_HASH_SIZE];
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
- sha1_reset(&sha1_context);
+ mysql_sha1_reset(&sha1_context);
/* create key to encrypt scramble */
- sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
- sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
- sha1_result(&sha1_context, buf);
+ mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
+ mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, buf);
/* encrypt scramble */
my_crypt((char *) buf, buf, (const uchar *) scramble, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
- sha1_reset(&sha1_context);
- sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
- sha1_result(&sha1_context, hash_stage2_reassured);
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, hash_stage2_reassured);
return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 6a17ae2f95b..a2287740f1e 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -565,9 +565,23 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
else
{
/* With conversion */
+ uint max_char_len;
int2store(pos, thd_charset->number);
- uint char_len= field.length / item->collation.collation->mbmaxlen;
- int4store(pos+2, char_len * thd_charset->mbmaxlen);
+ /*
+ For TEXT/BLOB columns, field_length describes the maximum data
+ length in bytes. There is no limit to the number of characters
+ that a TEXT column can store, as long as the data fits into
+ the designated space.
+ For the rest of textual columns, field_length is evaluated as
+ char_count * mbmaxlen, where character count is taken from the
+ definition of the column. In other words, the maximum number
+ of characters here is limited by the column definition.
+ */
+ max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
+ field.type <= (int) MYSQL_TYPE_BLOB) ?
+ field.length / item->collation.collation->mbminlen :
+ field.length / item->collation.collation->mbmaxlen;
+ int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
}
pos[6]= field.type;
int2store(pos+7,field.flags);
diff --git a/sql/spatial.h b/sql/spatial.h
index ec5e80e00fd..206958b3eaf 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -142,7 +142,7 @@ struct MBR
bool inner_point(double x, double y) const
{
/* The following should be safe, even if we compare doubles */
- return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>x);
+ return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>y);
}
int overlaps(const MBR *mbr)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 1ade6ce3064..c1847d010c5 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1151,7 +1151,7 @@ static void init_check_host(void)
if (j == acl_wild_hosts.elements) // If new
(void) push_dynamic(&acl_wild_hosts,(char*) &acl_user->host);
}
- else if (!hash_search(&acl_check_hosts,(byte*) &acl_user->host,
+ else if (!hash_search(&acl_check_hosts,(byte*) acl_user->host.hostname,
(uint) strlen(acl_user->host.hostname)))
{
if (my_hash_insert(&acl_check_hosts,(byte*) acl_user))
@@ -1371,7 +1371,8 @@ find_acl_user(const char *host, const char *user, my_bool exact)
acl_user->user && !strcmp(user,acl_user->user))
{
if (exact ? !my_strcasecmp(&my_charset_latin1, host,
- acl_user->host.hostname) :
+ acl_user->host.hostname ?
+ acl_user->host.hostname : "") :
compare_hostname(&acl_user->host,host,host))
{
DBUG_RETURN(acl_user);
@@ -1988,14 +1989,15 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
char helping [NAME_LEN*2+USERNAME_LENGTH+3];
uint len;
GRANT_TABLE *grant_table,*found=0;
+ HASH_SEARCH_STATE state;
len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
- for (grant_table=(GRANT_TABLE*) hash_search(&column_priv_hash,
- (byte*) helping,
- len) ;
+ for (grant_table=(GRANT_TABLE*) hash_first(&column_priv_hash,
+ (byte*) helping,
+ len, &state) ;
grant_table ;
grant_table= (GRANT_TABLE*) hash_next(&column_priv_hash,(byte*) helping,
- len))
+ len, &state))
{
if (exact)
{
@@ -3604,7 +3606,7 @@ ACL_USER *check_acl_user(LEX_USER *user_name,
if (!(user=acl_user->user))
user= "";
if (!(host=acl_user->host.hostname))
- host= "%";
+ host= "";
if (!strcmp(user_name->user.str,user) &&
!my_strcasecmp(system_charset_info, user_name->host.str, host))
break;
@@ -3719,17 +3721,25 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list)
record[0])))
{
tables[0].table->file->print_error(error, MYF(0));
- DBUG_RETURN(-1);
+ result= -1;
+ goto end;
}
delete_dynamic_element(&acl_users, acl_userd);
}
}
+ if (result)
+ my_error(ER_DROP_USER, MYF(0));
+
+end:
+ /* Reload acl_check_hosts as its memory is mapped to acl_user */
+ delete_dynamic(&acl_wild_hosts);
+ hash_free(&acl_check_hosts);
+ init_check_host();
+
VOID(pthread_mutex_unlock(&acl_cache->lock));
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_error(ER_DROP_USER, MYF(0));
DBUG_RETURN(result);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8b1fa754929..223e8482f49 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -799,6 +799,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
reg1 TABLE *table;
char key[MAX_DBKEY_LENGTH];
uint key_length;
+ HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
/* find a unused table in the open table cache */
@@ -863,9 +864,11 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
/* close handler tables which are marked for flush */
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
- for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
+ for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length,
+ &state);
table && table->in_use ;
- table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
+ table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
+ &state))
{
if (table->version != refresh_version)
{
@@ -985,6 +988,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->used_keys= table->keys_for_keyread;
+ table->file->ft_handler=0;
+ table->fulltext_searched=0;
if (table->timestamp_field)
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
DBUG_ASSERT(table->key_read == 0);
@@ -1009,10 +1014,20 @@ TABLE *find_locked_table(THD *thd, const char *db,const char *table_name)
/****************************************************************************
-** Reopen an table because the definition has changed. The date file for the
-** table is already closed.
-** Returns 0 if ok.
-** If table can't be reopened, the entry is unchanged.
+ Reopen an table because the definition has changed. The date file for the
+ table is already closed.
+
+ SYNOPSIS
+ reopen_table()
+ table Table to be opened
+ locked 1 if we have already a lock on LOCK_open
+
+ NOTES
+ table->query_id will be 0 if table was reopened
+
+ RETURN
+ 0 ok
+ 1 error ('table' is unchanged if table couldn't be reopened)
****************************************************************************/
bool reopen_table(TABLE *table,bool locked)
@@ -1082,8 +1097,10 @@ bool reopen_table(TABLE *table,bool locked)
(*field)->table_name=table->table_name;
}
for (key=0 ; key < table->keys ; key++)
+ {
for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
table->key_info[key].key_part[part].field->table= table;
+ }
VOID(pthread_cond_broadcast(&COND_refresh));
error=0;
@@ -1236,12 +1253,14 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
{
do
{
+ HASH_SEARCH_STATE state;
char *key= table->table_cache_key;
uint key_length=table->key_length;
- for (TABLE *search=(TABLE*) hash_search(&open_cache,
- (byte*) key,key_length) ;
+ for (TABLE *search= (TABLE*) hash_first(&open_cache, (byte*) key,
+ key_length, &state);
search ;
- search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
+ search= (TABLE*) hash_next(&open_cache, (byte*) key,
+ key_length, &state))
{
if (search->locked_by_flush ||
search->locked_by_name && wait_for_name_lock ||
@@ -2958,11 +2977,14 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
for (;;)
{
+ HASH_SEARCH_STATE state;
result= signalled= 0;
- for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
+ for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length,
+ &state);
table;
- table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
+ table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
+ &state))
{
THD *in_use;
table->version=0L; /* Free when thread is ready */
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index b40257511f7..457478e90db 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -2873,6 +2873,7 @@ my_bool Query_cache::move_by_type(byte **border,
}
case Query_cache_block::TABLE:
{
+ HASH_SEARCH_STATE record_idx;
DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block));
if (*border == 0)
break;
@@ -2890,7 +2891,7 @@ my_bool Query_cache::move_by_type(byte **border,
byte *key;
uint key_length;
key=query_cache_table_get_key((byte*) block, &key_length, 0);
- hash_search(&tables, (byte*) key, key_length);
+ hash_first(&tables, (byte*) key, key_length, &record_idx);
block->destroy();
new_block->init(len);
@@ -2924,7 +2925,7 @@ my_bool Query_cache::move_by_type(byte **border,
/* Fix pointer to table name */
new_block->table()->table(new_block->table()->db() + tablename_offset);
/* Fix hash to point at moved block */
- hash_replace(&tables, tables.current_record, (byte*) new_block);
+ hash_replace(&tables, &record_idx, (byte*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border));
@@ -2932,6 +2933,7 @@ my_bool Query_cache::move_by_type(byte **border,
}
case Query_cache_block::QUERY:
{
+ HASH_SEARCH_STATE record_idx;
DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block));
if (*border == 0)
break;
@@ -2949,7 +2951,7 @@ my_bool Query_cache::move_by_type(byte **border,
byte *key;
uint key_length;
key=query_cache_query_get_key((byte*) block, &key_length, 0);
- hash_search(&queries, (byte*) key, key_length);
+ hash_first(&queries, (byte*) key, key_length, &record_idx);
// Move table of used tables
memmove((char*) new_block->table(0), (char*) block->table(0),
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
@@ -3017,7 +3019,7 @@ my_bool Query_cache::move_by_type(byte **border,
net->query_cache_query= (gptr) new_block;
}
/* Fix hash to point at moved block */
- hash_replace(&queries, queries.current_record, (byte*) new_block);
+ hash_replace(&queries, &record_idx, (byte*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border));
break;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ef938a13489..6e24e951aa4 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1681,7 +1681,10 @@ bool select_dumpvar::send_eof()
void TMP_TABLE_PARAM::init()
{
+ DBUG_ENTER("TMP_TABLE_PARAM::init");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
field_count= sum_func_count= func_count= hidden_field_count= 0;
group_parts= group_length= group_null_parts= 0;
quick_group= 1;
+ DBUG_VOID_RETURN;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 7c834c91183..035a0b22a6b 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -388,6 +388,12 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
silent Used by replication when internally creating a database.
In this case the entry should not be logged.
+ SIDE-EFFECTS
+ 1. Report back to client that command succeeded (send_ok)
+ 2. Report errors to client
+ 3. Log event to binary log
+ (The 'silent' flags turns off 1 and 3.)
+
RETURN VALUES
0 ok
-1 Error
@@ -421,16 +427,17 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
if (my_stat(path,&stat_info,MYF(0)))
{
- if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
+ if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{
my_error(ER_DB_CREATE_EXISTS,MYF(0),db);
error= -1;
goto exit;
}
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
+ ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
+ if (!silent)
+ send_ok(thd);
error= 0;
- send_ok(thd);
goto exit;
}
else
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 12acf344c31..1c5381a9fa0 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -384,27 +384,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p",
hash_tables->db, hash_tables->real_name,
hash_tables->alias, table));
- /* Table might have been flushed. */
- if (table && (table->version != refresh_version))
- {
- /*
- We must follow the thd->handler_tables chain, as we need the
- address of the 'next' pointer referencing this table
- for close_thread_table().
- */
- for (table_ptr= &(thd->handler_tables);
- *table_ptr && (*table_ptr != table);
- table_ptr= &(*table_ptr)->next)
- {}
- VOID(pthread_mutex_lock(&LOCK_open));
- if (close_thread_table(thd, table_ptr))
- {
- /* Tell threads waiting for refresh that something has happened */
- VOID(pthread_cond_broadcast(&COND_refresh));
- }
- VOID(pthread_mutex_unlock(&LOCK_open));
- table= hash_tables->table= NULL;
- }
if (!table)
{
/*
@@ -451,9 +430,21 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
}
tables->table=table;
- if (cond && ((!cond->fixed &&
- cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1)))
- goto err0;
+ HANDLER_TABLES_HACK(thd);
+ lock= mysql_lock_tables(thd, &tables->table, 1, 0);
+ HANDLER_TABLES_HACK(thd);
+
+ if (!lock)
+ goto err0; // mysql_lock_tables() printed error message already
+
+ if (cond)
+ {
+ if (table->query_id != thd->query_id)
+ cond->cleanup(); // File was reopened
+ if ((!cond->fixed &&
+ cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1))
+ goto err0;
+ }
if (keyname)
{
@@ -471,13 +462,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
select_limit+=offset_limit;
protocol->send_fields(&list,1);
- HANDLER_TABLES_HACK(thd);
- lock= mysql_lock_tables(thd, &tables->table, 1, 0);
- HANDLER_TABLES_HACK(thd);
-
- if (!lock)
- goto err0; // mysql_lock_tables() printed error message already
-
/*
In ::external_lock InnoDB resets the fields which tell it that
the handle is used in the HANDLER interface. Tell it again that
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index aa4ea3e6c8c..4e6c458cc43 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -285,8 +285,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
error=read_sep_field(thd,info,table,fields,read_info,*enclosed,
skip_lines);
- if (table->file->end_bulk_insert())
- error=1; /* purecov: inspected */
+ if (table->file->end_bulk_insert() && !error)
+ {
+ table->file->print_error(my_errno, MYF(0));
+ error= 1;
+ }
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->next_number_field=0;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index fbca542dc24..1daa0a5ffec 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2840,21 +2840,26 @@ unsent_create_error:
if ((res= multi_update_precheck(thd, tables)))
break;
- if ((res= mysql_multi_update_lock(thd, tables, &select_lex->item_list,
- select_lex)))
- break;
-
+ res= mysql_multi_update_lock(thd, tables, &select_lex->item_list,
+ select_lex);
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
if (thd->slave_thread)
if (all_tables_not_ok(thd,tables))
{
+ if (res!= 0)
+ {
+ res= 0; /* don't care of prev failure */
+ thd->clear_error(); /* filters are of highest prior */
+ }
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break;
}
#endif /* HAVE_REPLICATION */
-
+ if (res)
+ break;
+
res= mysql_multi_update(thd,tables,
&select_lex->item_list,
&lex->value_list,
@@ -2897,16 +2902,17 @@ unsent_create_error:
if (unit->select_limit_cnt < select_lex->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // No limit
- if (find_real_table_in_list(tables->next, tables->db, tables->real_name))
+ if ((res= open_and_lock_tables(thd, tables)))
+ break;
+
+ insert_table= tables->table;
+ /* MERGE sub-tables can only be detected after open. */
+ if (mysql_lock_have_duplicate(thd, insert_table, tables->next))
{
/* Using same table for INSERT and SELECT */
select_lex->options |= OPTION_BUFFER_RESULT;
}
- if ((res= open_and_lock_tables(thd, tables)))
- break;
-
- insert_table= tables->table;
/* Skip first table, which is the table we are inserting in */
select_lex->table_list.first= (byte*) first_local_table->next;
tables= (TABLE_LIST *) select_lex->table_list.first;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5e29c98e2c8..ec62e80ba13 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -287,7 +287,7 @@ JOIN::prepare(Item ***rref_pointer_array,
if (having_fix_rc || thd->net.report_error)
DBUG_RETURN(-1); /* purecov: inspected */
if (having->with_sum_func)
- having->split_sum_func(thd, ref_pointer_array, all_fields);
+ having->split_sum_func2(thd, ref_pointer_array, all_fields, &having);
}
// Is it subselect
@@ -4107,6 +4107,20 @@ JOIN::join_free(bool full)
problems in free_elements() as some of the elements are then deleted.
*/
tmp_table_param.copy_funcs.empty();
+ /*
+ If we have tmp_join and 'this' JOIN is not tmp_join and
+ tmp_table_param.copy_field's of them are equal then we have to remove
+ pointer to tmp_table_param.copy_field from tmp_join, because it qill
+ be removed in tmp_table_param.cleanup().
+ */
+ if (tmp_join &&
+ tmp_join != this &&
+ tmp_join->tmp_table_param.copy_field ==
+ tmp_table_param.copy_field)
+ {
+ tmp_join->tmp_table_param.copy_field=
+ tmp_join->tmp_table_param.save_copy_field= 0;
+ }
tmp_table_param.cleanup();
}
DBUG_VOID_RETURN;
@@ -5292,7 +5306,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*(reg_field++) =new_field;
}
if (!--hidden_field_count)
+ {
hidden_null_count=null_count;
+ /*
+ We need to update hidden_field_count as we may have stored group
+ functions with constant arguments
+ */
+ param->hidden_field_count= (uint) (reg_field - table->field);
+ }
}
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
field_count= (uint) (reg_field - table->field);
@@ -5488,7 +5509,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
}
- if (distinct)
+ if (distinct && field_count != param->hidden_field_count)
{
/*
Create an unique key or an unique constraint over all columns
@@ -5942,21 +5963,19 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
if (table)
{
- int tmp;
+ int tmp, new_errno= 0;
if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
{
DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed"));
- my_errno= tmp;
- error= -1;
+ new_errno= tmp;
}
if ((tmp=table->file->ha_index_or_rnd_end()))
{
DBUG_PRINT("error",("ha_index_or_rnd_end() failed"));
- my_errno= tmp;
- error= -1;
+ new_errno= tmp;
}
- if (error == -1)
- table->file->print_error(my_errno,MYF(0));
+ if (new_errno)
+ table->file->print_error(new_errno,MYF(0));
}
#ifndef DBUG_OFF
if (error)
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 636ee967645..94cc8839466 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -227,7 +227,14 @@ class JOIN :public Sql_alloc
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
-
+
+ JOIN(JOIN &join)
+ :fields_list(join.fields_list)
+ {
+ init(join.thd, join.fields_list, join.select_options,
+ join.result);
+ }
+
void init(THD *thd_arg, List<Item> &fields_arg, ulong select_options_arg,
select_result *result_arg)
{
@@ -272,7 +279,7 @@ class JOIN :public Sql_alloc
fields_list= fields_arg;
bzero((char*) &keyuse,sizeof(keyuse));
- tmp_table_param.copy_field=0;
+ tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;
rollup.state= ROLLUP::STATE_NONE;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 294c59af90f..71cbc0be1e3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -678,6 +678,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields--;
sql_field->flags= dup_field->flags;
+ sql_field->interval= dup_field->interval;
it2.remove(); // Remove first (create) definition
select_field_pos--;
break;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 7b1d5988bde..48a8cf93917 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -212,7 +212,6 @@ int mysql_update(THD *thd,
SORT_FIELD *sortorder;
ha_rows examined_rows;
- used_index= MAX_KEY; // For call to init_read_record()
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
@@ -244,7 +243,17 @@ int mysql_update(THD *thd,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
- if (used_index == MAX_KEY)
+ /*
+ When we get here, we have one of the following options:
+ A. used_index == MAX_KEY
+ This means we should use full table scan, and start it with
+ init_read_record call
+ B. used_index != MAX_KEY
+ B.1 quick select is used, start the scan with init_read_record
+ B.2 quick select is not used, this is full index scan (with LIMIT)
+ Full index scan must be started with init_read_record_idx
+ */
+ if (used_index == MAX_KEY || (select && select->quick))
init_read_record(&info,thd,table,select,0,1);
else
init_read_record_idx(&info, thd, table, 1, used_index);
@@ -854,8 +863,7 @@ int multi_update::prepare(List<Item> &not_used_values,
{
TABLE *table=table_ref->table;
if (!(tables_to_update & table->map) &&
- find_real_table_in_list(update_tables, table_ref->db,
- table_ref->real_name))
+ mysql_lock_have_duplicate(thd, table, update_tables))
table->no_cache= 1; // Disable row cache
}
DBUG_RETURN(thd->is_fatal_error != 0);
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index f15e97de5be..2863b192f50 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -8635,6 +8635,41 @@ my_mb_wc_euc_kr(CHARSET_INFO *cs __attribute__((unused)),
}
+/*
+ Returns well formed length of a EUC-KR string.
+*/
+static uint
+my_well_formed_len_euckr(CHARSET_INFO *cs __attribute__((unused)),
+ const char *b, const char *e,
+ uint pos, int *error)
+{
+ const char *b0= b;
+ const char *emb= e - 1; /* Last possible end of an MB character */
+
+ *error= 0;
+ while (pos-- && b < e)
+ {
+ if ((uchar) b[0] < 128)
+ {
+ /* Single byte ascii character */
+ b++;
+ }
+ else if (b < emb && iseuc_kr(*b) && iseuc_kr(b[1]))
+ {
+ /* Double byte character */
+ b+= 2;
+ }
+ else
+ {
+ /* Wrong byte sequence */
+ *error= 1;
+ break;
+ }
+ }
+ return (uint) (b - b0);
+}
+
+
static MY_COLLATION_HANDLER my_collation_ci_handler =
{
NULL, /* init */
@@ -8655,7 +8690,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
mbcharlen_euc_kr,
my_numchars_mb,
my_charpos_mb,
- my_well_formed_len_mb,
+ my_well_formed_len_euckr,
my_lengthsp_8bit,
my_numcells_8bit,
my_mb_wc_euc_kr, /* mb_wc */
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index 0cbad2d1c55..52dd61a8462 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -5686,6 +5686,41 @@ my_mb_wc_gb2312(CHARSET_INFO *cs __attribute__((unused)),
}
+/*
+ Returns well formed length of a EUC-KR string.
+*/
+static uint
+my_well_formed_len_gb2312(CHARSET_INFO *cs __attribute__((unused)),
+ const char *b, const char *e,
+ uint pos, int *error)
+{
+ const char *b0= b;
+ const char *emb= e - 1; /* Last possible end of an MB character */
+
+ *error= 0;
+ while (pos-- && b < e)
+ {
+ if ((uchar) b[0] < 128)
+ {
+ /* Single byte ascii character */
+ b++;
+ }
+ else if (b < emb && isgb2312head(*b) && isgb2312tail(b[1]))
+ {
+ /* Double byte character */
+ b+= 2;
+ }
+ else
+ {
+ /* Wrong byte sequence */
+ *error= 1;
+ break;
+ }
+ }
+ return (uint) (b - b0);
+}
+
+
static MY_COLLATION_HANDLER my_collation_ci_handler =
{
NULL, /* init */
@@ -5706,7 +5741,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
mbcharlen_gb2312,
my_numchars_mb,
my_charpos_mb,
- my_well_formed_len_mb,
+ my_well_formed_len_gb2312,
my_lengthsp_8bit,
my_numcells_8bit,
my_mb_wc_gb2312, /* mb_wc */
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index ad07fd9903c..d8985a890d9 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1352,11 +1352,48 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs,
return t_is_prefix ? (int) (t - te) : (int) ((se-s) - (te-t));
}
-static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs,
+static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)),
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
- return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0);
+ const uchar *se, *te;
+ uint minlen;
+
+ /* extra safety to make sure the lengths are even numbers */
+ slen= (slen >> 1) << 1;
+ tlen= (tlen >> 1) << 1;
+
+ se= s + slen;
+ te= t + tlen;
+
+ for (minlen= min(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+ if ( s_wc != t_wc )
+ return s_wc > t_wc ? 1 : -1;
+
+ s+= 2;
+ t+= 2;
+ }
+
+ if (slen != tlen)
+ {
+ int swap= 1;
+ if (slen < tlen)
+ {
+ s= t;
+ se= te;
+ swap= -1;
+ }
+
+ for ( ; s < se ; s+= 2)
+ {
+ if (s[0] || s[1] != ' ')
+ return (s[0] == 0 && s[1] < ' ') ? -swap : swap;
+ }
+ }
+ return 0;
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index f0566995262..dbc2f582466 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -11706,6 +11706,37 @@ static void test_bug12001()
DIE_UNLESS(res==1);
}
+static void test_bug12744()
+{
+ MYSQL_STMT *prep_stmt = NULL;
+ int rc;
+ myheader("test_bug12744");
+
+ prep_stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
+ DIE_UNLESS(rc==0);
+
+ rc= mysql_kill(mysql, mysql_thread_id(mysql));
+ DIE_UNLESS(rc==0);
+
+ if (rc= mysql_stmt_execute(prep_stmt))
+ {
+ if (rc= mysql_stmt_reset(prep_stmt))
+ printf("OK!\n");
+ else
+ {
+ printf("Error!");
+ DIE_UNLESS(1==0);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "expected error but no error occured\n");
+ DIE_UNLESS(1==0);
+ }
+ rc= mysql_stmt_close(prep_stmt);
+}
+
/*
Bug#11718: query with function, join and order by returns wrong type
*/
@@ -11753,6 +11784,89 @@ static void test_bug12925()
}
+/* Bug #16144: mysql_stmt_attr_get type error */
+
+static void test_bug16144()
+{
+ const my_bool flag_orig= (my_bool) 0xde;
+ my_bool flag= flag_orig;
+ MYSQL_STMT *stmt;
+ myheader("test_bug16144");
+
+ /* Check that attr_get returns correct data on little and big endian CPUs */
+ stmt= mysql_stmt_init(mysql);
+ mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
+ mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
+ DIE_UNLESS(flag == flag_orig);
+
+ mysql_stmt_close(stmt);
+}
+
+
+/*
+ Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
+ field length"
+*/
+
+static void test_bug15613()
+{
+ MYSQL_STMT *stmt;
+ const char *stmt_text;
+ MYSQL_RES *metadata;
+ MYSQL_FIELD *field;
+ int rc;
+ myheader("test_bug15613");
+
+ /* I. Prepare the table */
+ rc= mysql_query(mysql, "set names latin1");
+ myquery(rc);
+ mysql_query(mysql, "drop table if exists t1");
+ rc= mysql_query(mysql,
+ "create table t1 (t text character set utf8, "
+ "tt tinytext character set utf8, "
+ "mt mediumtext character set utf8, "
+ "lt longtext character set utf8, "
+ "vl varchar(255) character set latin1,"
+ "vb varchar(255) character set binary,"
+ "vu varchar(255) character set utf8)");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+
+ /* II. Check SELECT metadata */
+ stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_fields(metadata);
+ if (!opt_silent)
+ {
+ printf("Field lengths (client character set is latin1):\n"
+ "text character set utf8:\t\t%lu\n"
+ "tinytext character set utf8:\t\t%lu\n"
+ "mediumtext character set utf8:\t\t%lu\n"
+ "longtext character set utf8:\t\t%lu\n"
+ "varchar(255) character set latin1:\t%lu\n"
+ "varchar(255) character set binary:\t%lu\n"
+ "varchar(255) character set utf8:\t%lu\n",
+ field[0].length, field[1].length, field[2].length, field[3].length,
+ field[4].length, field[5].length, field[6].length);
+ }
+ DIE_UNLESS(field[0].length == 65535);
+ DIE_UNLESS(field[1].length == 255);
+ DIE_UNLESS(field[2].length == 16777215);
+ DIE_UNLESS(field[3].length == 4294967295UL);
+ DIE_UNLESS(field[4].length == 255);
+ DIE_UNLESS(field[5].length == 255);
+ DIE_UNLESS(field[6].length == 255);
+
+ /* III. Cleanup */
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "set names default");
+ myquery(rc);
+ mysql_stmt_close(stmt);
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -11971,9 +12085,12 @@ static struct my_tests_st my_tests[]= {
{ "test_bug8378", test_bug8378 },
{ "test_bug9735", test_bug9735 },
{ "test_bug11183", test_bug11183 },
+ { "test_bug12744", test_bug12744 },
{ "test_bug12001", test_bug12001 },
{ "test_bug11718", test_bug11718 },
{ "test_bug12925", test_bug12925 },
+ { "test_bug16144", test_bug16144 },
+ { "test_bug15613", test_bug15613 },
{ 0, 0 }
};
diff --git a/zlib/Makefile.am b/zlib/Makefile.am
index e94d184a841..11b1991fa62 100644
--- a/zlib/Makefile.am
+++ b/zlib/Makefile.am
@@ -18,6 +18,8 @@
pkglib_LTLIBRARIES=libz.la
+libz_la_LDFLAGS= -version-info 3:3:2
+
noinst_HEADERS= crc32.h deflate.h inffast.h inffixed.h inflate.h \
inftrees.h trees.h zconf.h zlib.h zutil.h