diff options
author | unknown <jonas@perch.ndb.mysql.com> | 2005-12-13 11:45:42 +0100 |
---|---|---|
committer | unknown <jonas@perch.ndb.mysql.com> | 2005-12-13 11:45:42 +0100 |
commit | 12aef413ee7615b4f2cd9391921878ec28643488 (patch) | |
tree | 49b74059b86c9029944323ce43e57b68686eb582 | |
parent | 40ec24036c7ee3c1d0b898de58a83e71bae0aee6 (diff) | |
parent | 8c911a25fede70529455a984138d8946ace0ba87 (diff) | |
download | mariadb-git-12aef413ee7615b4f2cd9391921878ec28643488.tar.gz |
Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1
into perch.ndb.mysql.com:/home/jonas/src/mysql-4.1-push
75 files changed, 813 insertions, 346 deletions
diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index a54086a0d0d..a09da93adaf 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -2,7 +2,7 @@ #shift FROM=$USER@mysql.com -INTERNALS=internals@lists.mysql.com +COMMITS=commits@lists.mysql.com DOCS=docs-commit@mysql.com LIMIT=10000 VERSION="4.1" @@ -61,14 +61,14 @@ EOF ) | head -n $LIMIT | /usr/sbin/sendmail -t #++ -# internals@ mail +# commits@ mail #-- - echo "Notifying internals list at $INTERNALS" + echo "Notifying commits list at $COMMITS" ( cat <<EOF List-ID: <bk.mysql-$VERSION> From: $FROM -To: $INTERNALS +To: $COMMITS Subject: bk commit into $VERSION tree ($CHANGESET)$BS X-CSetKey: <$CSETKEY> $BH diff --git a/client/mysql.cc b/client/mysql.cc index 1c4fbf8f06f..14a27413687 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -509,7 +509,7 @@ static struct my_option my_long_options[] = {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"auto-rehash", OPT_AUTO_REHASH, diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index da790bce375..7bb3061f412 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -127,7 +127,7 @@ static TYPELIB command_typelib= static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"count", 'c', diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 802d5081ad6..627e0945d93 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -433,7 +433,7 @@ static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif #ifndef DBUG_OFF diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 2a2ae1311c9..f0f7c247553 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -63,7 +63,7 @@ static struct my_option my_long_options[] = (gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"auto-repair", OPT_AUTO_REPAIR, diff --git a/client/mysqldump.c b/client/mysqldump.c index 3458f74d8a2..7ff9504607f 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -165,7 +165,7 @@ static struct my_option my_long_options[] = "Allow creation of column names that are keywords.", (gptr*) &opt_keywords, (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 32e2a7ccffe..a7872740c0c 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -59,7 +59,7 @@ static char *shared_memory_base_name=0; static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 44fc9448782..3b714c20ba7 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -156,7 +156,7 @@ int main(int argc, char **argv) static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", 'c', "Directory where character sets are.", diff --git a/configure.in b/configure.in index 41475ffcd4a..9afd2034796 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ 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.16) +AM_INIT_AUTOMAKE(mysql, 4.1.17) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -16,7 +16,7 @@ SHARED_LIB_VERSION=14:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=16 +NDB_VERSION_BUILD=17 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? diff --git a/include/config-win.h b/include/config-win.h index 9663947683e..e1972051e67 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -278,10 +278,10 @@ inline double ulonglong2double(ulonglong value) *((T)+4)=(uchar) (((A) >> 32)); } #define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A) -#define doubleget(V,M) { *((long *) &V) = *((long*) M); \ - *(((long *) &V)+1) = *(((long*) M)+1); } -#define doublestore(T,V) { *((long *) T) = *((long*) &V); \ - *(((long *) T)+1) = *(((long*) &V)+1); } +#define doubleget(V,M) do { *((long *) &V) = *((long*) M); \ + *(((long *) &V)+1) = *(((long*) M)+1); } while(0) +#define doublestore(T,V) do { *((long *) T) = *((long*) &V); \ + *(((long *) T)+1) = *(((long*) &V)+1); } while(0) #define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); } #define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float)) #define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b0327f77fd3..0cdd593b678 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2077,8 +2077,11 @@ dict_foreign_find_index( dict_table_t* table, /* in: table */ const char** columns,/* in: array of column names */ ulint n_cols, /* in: number of columns */ - dict_index_t* types_idx)/* in: NULL or an index to whose types the - column types must match */ + dict_index_t* types_idx, /* in: NULL or an index to whose types the + column types must match */ + ibool check_charsets) /* in: whether to check charsets. + only has an effect if types_idx != + NULL. */ { dict_index_t* index; const char* col_name; @@ -2107,7 +2110,8 @@ dict_foreign_find_index( if (types_idx && !cmp_types_are_equal( dict_index_get_nth_type(index, i), - dict_index_get_nth_type(types_idx, i))) { + dict_index_get_nth_type(types_idx, i), + check_charsets)) { break; } @@ -2178,7 +2182,8 @@ dict_foreign_add_to_cache( /*======================*/ /* out: DB_SUCCESS or error code */ dict_foreign_t* foreign, /* in, own: foreign key constraint */ - ibool check_types) /* in: TRUE=check type compatibility */ + ibool check_charsets) /* in: TRUE=check charset + compatibility */ { dict_table_t* for_table; dict_table_t* ref_table; @@ -2214,16 +2219,10 @@ dict_foreign_add_to_cache( } if (for_in_cache->referenced_table == NULL && ref_table) { - dict_index_t* types_idx; - if (check_types) { - types_idx = for_in_cache->foreign_index; - } else { - types_idx = NULL; - } index = dict_foreign_find_index(ref_table, (const char**) for_in_cache->referenced_col_names, for_in_cache->n_fields, - types_idx); + for_in_cache->foreign_index, check_charsets); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, @@ -2247,16 +2246,10 @@ dict_foreign_add_to_cache( } if (for_in_cache->foreign_table == NULL && for_table) { - dict_index_t* types_idx; - if (check_types) { - types_idx = for_in_cache->referenced_index; - } else { - types_idx = NULL; - } index = dict_foreign_find_index(for_table, (const char**) for_in_cache->foreign_col_names, for_in_cache->n_fields, - types_idx); + for_in_cache->referenced_index, check_charsets); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, @@ -3033,7 +3026,7 @@ col_loop1: /* Try to find an index which contains the columns as the first fields and in the right order */ - index = dict_foreign_find_index(table, column_names, i, NULL); + index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); if (!index) { mutex_enter(&dict_foreign_err_mutex); @@ -3298,8 +3291,7 @@ try_find_index: if (referenced_table) { index = dict_foreign_find_index(referenced_table, - column_names, i, - foreign->foreign_index); + column_names, i, foreign->foreign_index, TRUE); if (!index) { dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 0d58823a2ea..5127e258f56 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -1094,7 +1094,7 @@ dict_load_foreign( /* out: DB_SUCCESS or error code */ const char* id, /* in: foreign constraint id as a null-terminated string */ - ibool check_types)/* in: TRUE=check type compatibility */ + ibool check_charsets)/* in: TRUE=check charset compatibility */ { dict_foreign_t* foreign; dict_table_t* sys_foreign; @@ -1205,7 +1205,7 @@ dict_load_foreign( a new foreign key constraint but loading one from the data dictionary. */ - return(dict_foreign_add_to_cache(foreign, check_types)); + return(dict_foreign_add_to_cache(foreign, check_charsets)); } /*************************************************************************** @@ -1220,7 +1220,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ - ibool check_types) /* in: TRUE=check type compatibility */ + ibool check_charsets) /* in: TRUE=check charset + compatibility */ { btr_pcur_t pcur; mem_heap_t* heap; @@ -1319,7 +1320,7 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_types); + err = dict_load_foreign(id, check_charsets); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 3333385ec56..bf1382e8bb2 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -197,7 +197,8 @@ dict_foreign_add_to_cache( /*======================*/ /* out: DB_SUCCESS or error code */ dict_foreign_t* foreign, /* in, own: foreign key constraint */ - ibool check_types); /* in: TRUE=check type compatibility */ + ibool check_charsets);/* in: TRUE=check charset + compatibility */ /************************************************************************* Checks if a table is referenced by foreign keys. */ diff --git a/innobase/include/dict0load.h b/innobase/include/dict0load.h index f13620bc6e8..741123614ab 100644 --- a/innobase/include/dict0load.h +++ b/innobase/include/dict0load.h @@ -82,7 +82,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ - ibool check_types); /* in: TRUE=check type compatibility */ + ibool check_charsets);/* in: TRUE=check charsets + compatibility */ /************************************************************************ Prints to the standard output information on all tables found in the data dictionary system table. */ diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 280a949c1c5..cd07eb49cd6 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -182,7 +182,7 @@ Creates a temporary file. */ FILE* os_file_create_tmpfile(void); /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle, or NULL on error */ /*************************************************************************** The os_file_opendir() function opens a directory stream corresponding to the directory named by the dirname argument. The directory stream is positioned diff --git a/innobase/include/rem0cmp.h b/innobase/include/rem0cmp.h index 712e263350e..6288d47bd63 100644 --- a/innobase/include/rem0cmp.h +++ b/innobase/include/rem0cmp.h @@ -24,7 +24,8 @@ cmp_types_are_equal( /* out: TRUE if the types are considered equal in comparisons */ dtype_t* type1, /* in: type 1 */ - dtype_t* type2); /* in: type 2 */ + dtype_t* type2, /* in: type 2 */ + ibool check_charsets); /* in: whether to check charsets */ /***************************************************************** This function is used to compare two data fields for which we know the data type. */ diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 4352083b21f..992271e32ee 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -34,6 +34,12 @@ extern ibool srv_lower_case_table_names; extern mutex_t srv_monitor_file_mutex; /* Temporary file for innodb monitor output */ extern FILE* srv_monitor_file; +/* Mutex for locking srv_dict_tmpfile. +This mutex has a very high rank; threads reserving it should not +be holding any InnoDB latches. */ +extern mutex_t srv_dict_tmpfile_mutex; +/* Temporary file for output from the data dictionary */ +extern FILE* srv_dict_tmpfile; /* Server parameters which are read from the initfile */ diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index f2dc8a7021a..ce3ed6e6355 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -98,7 +98,8 @@ cmp_types_are_equal( /* out: TRUE if the types are considered equal in comparisons */ dtype_t* type1, /* in: type 1 */ - dtype_t* type2) /* in: type 2 */ + dtype_t* type2, /* in: type 2 */ + ibool check_charsets) /* in: whether to check charsets */ { if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype) && dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) { @@ -106,12 +107,12 @@ cmp_types_are_equal( /* Both are non-binary string types: they can be compared if and only if the charset-collation is the same */ - if (dtype_get_charset_coll(type1->prtype) - == dtype_get_charset_coll(type2->prtype)) { + if (check_charsets) { + return(dtype_get_charset_coll(type1->prtype) + == dtype_get_charset_coll(type2->prtype)); + } else { return(TRUE); } - - return(FALSE); } if (dtype_is_binary_string_type(type1->mtype, type1->prtype) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 456bb51d424..26ae0e6cc76 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -522,7 +522,7 @@ row_ins_cascade_calc_update_vec( && ufield->new_val.len < dtype_get_fixed_size(type)) { - ulint cset; + ulint cset; ufield->new_val.data = mem_heap_alloc(heap, @@ -530,42 +530,42 @@ row_ins_cascade_calc_update_vec( ufield->new_val.len = dtype_get_fixed_size(type); - /* Handle UCS2 strings differently. - As no new collations will be - introduced in 4.1, we hardcode the - charset-collation codes here. - In 5.0, the logic is based on - mbminlen. */ - cset = dtype_get_charset_coll( - dtype_get_prtype(type)); - - if (cset == 35/*ucs2_general_ci*/ - || cset == 90/*ucs2_bin*/ - || (cset >= 128/*ucs2_unicode_ci*/ - && cset <= 144 - /*ucs2_persian_ci*/)) { - /* space=0x0020 */ - ulint i; - for (i = 0; - i < ufield->new_val.len; - i += 2) { - mach_write_to_2(((byte*) - ufield->new_val.data) - + i, 0x0020); - } - } else { - ut_a(dtype_get_pad_char(type) - != ULINT_UNDEFINED); - - memset(ufield->new_val.data, - (byte)dtype_get_pad_char( - type), - ufield->new_val.len); - } - - memcpy(ufield->new_val.data, - parent_ufield->new_val.data, - parent_ufield->new_val.len); + /* Handle UCS2 strings differently. + As no new collations will be + introduced in 4.1, we hardcode the + charset-collation codes here. + In 5.0, the logic is based on + mbminlen. */ + cset = dtype_get_charset_coll( + dtype_get_prtype(type)); + + if (cset == 35/*ucs2_general_ci*/ + || cset == 90/*ucs2_bin*/ + || (cset >= 128/*ucs2_unicode_ci*/ + && cset <= 144 + /*ucs2_persian_ci*/)) { + /* space=0x0020 */ + ulint i; + for (i = 0; + i < ufield->new_val.len; + i += 2) { + mach_write_to_2(((byte*) + ufield->new_val.data) + + i, 0x0020); + } + } else { + ut_a(dtype_get_pad_char(type) + != ULINT_UNDEFINED); + + memset(ufield->new_val.data, + (byte)dtype_get_pad_char( + type), + ufield->new_val.len); + } + + memcpy(ufield->new_val.data, + parent_ufield->new_val.data, + parent_ufield->new_val.len); } ufield->extern_storage = FALSE; diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 7ce5c766e06..ba50e6a3511 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1804,7 +1804,7 @@ row_table_add_foreign_constraints( if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, trx->check_foreigns); + err = dict_load_foreigns(name, TRUE); } if (err != DB_SUCCESS) { @@ -2963,7 +2963,8 @@ row_rename_table_for_mysql( mem_heap_t* heap = NULL; const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; - ibool recovering_temp_table = FALSE; + ibool recovering_temp_table = FALSE; + ibool old_is_tmp, new_is_tmp; ulint len; ulint i; ibool success; @@ -3003,6 +3004,9 @@ row_rename_table_for_mysql( trx->op_info = "renaming table"; trx_start_if_not_started(trx); + old_is_tmp = row_is_mysql_tmp_table_name(old_name); + new_is_tmp = row_is_mysql_tmp_table_name(new_name); + if (row_mysql_is_recovered_tmp_table(new_name)) { recovering_temp_table = TRUE; @@ -3047,7 +3051,7 @@ row_rename_table_for_mysql( len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); - if (row_is_mysql_tmp_table_name(new_name)) { + if (new_is_tmp) { db_name_len = dict_get_db_name_len(old_name) + 1; /* MySQL is doing an ALTER TABLE command and it renames the @@ -3200,7 +3204,7 @@ row_rename_table_for_mysql( the table is stored in a single-table tablespace */ success = dict_table_rename_in_cache(table, new_name, - !row_is_mysql_tmp_table_name(new_name)); + !new_is_tmp); if (!success) { trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -3217,19 +3221,16 @@ row_rename_table_for_mysql( goto funct_exit; } - err = dict_load_foreigns(new_name, trx->check_foreigns); - - if (row_is_mysql_tmp_table_name(old_name)) { + /* We only want to switch off some of the type checking in + an ALTER, not in a RENAME. */ + + err = dict_load_foreigns(new_name, + old_is_tmp ? trx->check_foreigns : TRUE); - /* MySQL is doing an ALTER TABLE command and it - renames the created temporary table to the name - of the original table. In the ALTER TABLE we maybe - created some FOREIGN KEY constraints for the temporary - table. But we want to load also the foreign key - constraint definitions for the original table name. */ + if (err != DB_SUCCESS) { + ut_print_timestamp(stderr); - if (err != DB_SUCCESS) { - ut_print_timestamp(stderr); + if (old_is_tmp) { fputs(" InnoDB: Error: in ALTER TABLE ", stderr); ut_print_name(stderr, trx, new_name); @@ -3237,36 +3238,23 @@ row_rename_table_for_mysql( "InnoDB: has or is referenced in foreign key constraints\n" "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; - } - } else { - if (err != DB_SUCCESS) { - - ut_print_timestamp(stderr); - + } else { fputs( " InnoDB: Error: in RENAME TABLE table ", stderr); ut_print_name(stderr, trx, new_name); fputs("\n" - "InnoDB: is referenced in foreign key constraints\n" - "InnoDB: which are not compatible with the new table definition.\n", + "InnoDB: is referenced in foreign key constraints\n" + "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; } + + ut_a(dict_table_rename_in_cache(table, + old_name, FALSE)); + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, + NULL); + trx->error_state = DB_SUCCESS; } } funct_exit: diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index e56389a8541..d7bd698fe0e 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -334,6 +334,12 @@ mutex_t srv_innodb_monitor_mutex; mutex_t srv_monitor_file_mutex; /* Temporary file for innodb monitor output */ FILE* srv_monitor_file; +/* Mutex for locking srv_dict_tmpfile. +This mutex has a very high rank; threads reserving it should not +be holding any InnoDB latches. */ +mutex_t srv_dict_tmpfile_mutex; +/* Temporary file for output from the data dictionary */ +FILE* srv_dict_tmpfile; ulint srv_main_thread_process_no = 0; ulint srv_main_thread_id = 0; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 87f4c31257a..4d208ea2d15 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1178,6 +1178,13 @@ NetWare. */ } } + mutex_create(&srv_dict_tmpfile_mutex); + mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION); + srv_dict_tmpfile = os_file_create_tmpfile(); + if (!srv_dict_tmpfile) { + return(DB_ERROR); + } + /* Restrict the maximum number of file i/o threads */ if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) { @@ -1804,8 +1811,13 @@ innobase_shutdown_for_mysql(void) mem_free(srv_monitor_file_name); } } - + if (srv_dict_tmpfile) { + fclose(srv_dict_tmpfile); + srv_dict_tmpfile = 0; + } + mutex_free(&srv_monitor_file_mutex); + mutex_free(&srv_dict_tmpfile_mutex); /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ diff --git a/isam/isamchk.c b/isam/isamchk.c index 2912131d25b..cacfca8be0a 100644 --- a/isam/isamchk.c +++ b/isam/isamchk.c @@ -244,7 +244,7 @@ static struct my_option my_long_options[] = "Analyze distribution of keys. Will make some joins in MySQL faster.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR_IC, diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index 8e4769ebc75..fad8b5c4273 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -147,8 +147,10 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, for (word->pos=doc; doc<end; length++, mbl=my_mbcharlen(cs, *(uchar *)doc), doc+=(mbl ? mbl : 1)) if (true_word_char(cs,*doc)) mwc=0; - else if (!misc_word_char(*doc) || mwc++) + else if (!misc_word_char(*doc) || mwc) break; + else + mwc++; param->prev='A'; /* be sure *prev is true_word_char */ word->len= (uint)(doc-word->pos) - mwc; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index d68ea410852..49e3ea0f142 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -165,7 +165,7 @@ static struct my_option my_long_options[] = "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"block-search", 'b', diff --git a/myisam/myisampack.c b/myisam/myisampack.c index f017e4d23ab..39eaf8927a6 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -239,7 +239,7 @@ enum options_mp {OPT_CHARSETS_DIR_MP=256, OPT_AUTO_CLOSE}; static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"backup", 'b', "Make a backup of the table as table_name.OLD.", diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c3025060e37..58308f0ccdd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -871,7 +871,7 @@ sub executable_setup () { "/usr/bin/false"); } $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); - $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); @@ -885,6 +885,7 @@ sub executable_setup () { { $path_client_bindir= mtr_path_exists("$glob_basedir/bin"); $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 6da3dbb929d..9fb42a0f6fd 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1284,3 +1284,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd"); id 4 DROP TABLE t1; +create table t1 (a int, key(a)) engine=bdb; +create table t2 (b int, key(b)) engine=bdb; +insert into t1 values (1),(1),(2),(3),(4); +insert into t2 values (1),(5),(6),(7); +delete from t1 where (a in (select b from t2)); +select count(*) from t1; +count(*) +3 +insert into t1 set a=(select b from t2); +ERROR 21000: Subquery returns more than 1 row +select count(*) from t1; +count(*) +3 +update t1 set a = a + 1 where (a in (select b from t2)); +select count(*) from t1; +count(*) +3 +drop table t1, t2; +End of 4.1 tests diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 1c75988fd21..0b5c6f8974c 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -181,11 +181,18 @@ select * from t1 where a=_koi8r'×ÁÓÑ'; a ×ÁÓÑ select * from t1 where a=concat(_koi8r'×ÁÓÑ'); -ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '=' +a +×ÁÓÑ select * from t1 where a=_latin1'×ÁÓÑ'; ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' drop table t1; set names latin1; +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +a + xxx +drop table t1; set names koi8r; create table t1 (c1 char(10) character set cp1251); insert into t1 values ('ß'); diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 87551f96a13..ebd6880a10e 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -432,4 +432,7 @@ INSERT INTO t1 VALUES('testword\'\''); SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); a testword'' +SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); +a +testword'' DROP TABLE t1; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 2d464c891bf..181ecf7b65b 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -49,3 +49,11 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) ); a 2004-01-06 12:34:00 drop table t1; +create table t1 as select uuid(), length(uuid()); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `uuid()` char(36) character set utf8 NOT NULL default '', + `length(uuid())` int(10) NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index a50293752ec..0a406c1ffc2 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -351,10 +351,10 @@ GRANT USAGE ON *.* TO 'grant_user'@'localhost' GRANT INSERT (a, d, c, b) ON `test`.`t1` TO 'grant_user'@'localhost' select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv; Host Db User Table_name Column_name Column_priv -localhost test grant_user t1 c Insert localhost test grant_user t1 b Insert -localhost test grant_user t1 a Insert localhost test grant_user t1 d Insert +localhost test grant_user t1 a Insert +localhost test grant_user t1 c Insert revoke ALL PRIVILEGES on t1 from grant_user@localhost; show grants for grant_user@localhost; Grants for grant_user@localhost @@ -377,9 +377,9 @@ show grants for mysqltest_3@localhost; Grants for mysqltest_3@localhost GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost' GRANT SELECT (b) ON `mysqltest_1`.`t2` TO 'mysqltest_3'@'localhost' -GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (a) ON `mysqltest_1`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost' +GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 't1' update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; @@ -443,3 +443,24 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +hex(Db) +D0B1D0B4 +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +flush privileges; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +set names latin1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index ca78d23e6dc..b43d00bda1c 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1722,3 +1722,35 @@ checksum table test_checksum; Table Checksum test.test_checksum 2050879373 drop table test_checksum; +set foreign_key_checks=0; +create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; +create table t1(a char(10) primary key, b varchar(20)) engine = innodb; +ERROR HY000: Can't create table './test/t1.frm' (errno: 150) +set foreign_key_checks=1; +drop table t2; +set foreign_key_checks=0; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; +ERROR HY000: Can't create table './test/t2.frm' (errno: 150) +set foreign_key_checks=1; +drop table t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; +create table t1(a varchar(10) primary key) engine = innodb; +alter table t1 modify column a int; +Got one of the listed errors +set foreign_key_checks=1; +drop table t2,t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +alter table t1 convert to character set utf8; +set foreign_key_checks=1; +drop table t2,t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; +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; diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 62e8455ae9f..b5fceba7cee 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -179,7 +179,7 @@ a b c 2 two two alter table t1 drop index c; select * from t1 where b = 'two'; -ERROR HY000: Table definition has changed, please retry transaction +ERROR HY000: Can't lock file (errno: 241) select * from t1 where b = 'two'; a b c 2 two two diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f5bf3ffa96d..d46c2d5b3d5 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -699,3 +699,22 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names default; +deallocate prepare stmt; diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result index f883bef8591..1d66bad7eb7 100644 --- a/mysql-test/r/ps_grant.result +++ b/mysql-test/r/ps_grant.result @@ -32,19 +32,19 @@ identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index ed87e2be2b4..24363ea27ab 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -982,4 +982,29 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 drop table t1; +create table t1 (a int); +flush status; +(select a from t1) union (select a from t1); +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +(select a from t1) union (select a from t1); +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +drop table t1; set GLOBAL query_cache_size=0; diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 5772f176919..6bbfe36c56b 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -31,7 +31,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-bin.000001 244 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 244 # Master master-bin.000001 244 No # start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -41,7 +41,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-no-such-bin.000001 291 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 244 # Master master-no-such-bin.000001 291 No # start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; select * from t2; n @@ -49,7 +49,7 @@ n 2 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 449 # Relay slave-relay-bin.000002 537 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 449 # Relay slave-relay-bin.000002 537 No # start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=561; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 64c329ee104..b80ca2b195e 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2706,3 +2706,11 @@ select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; count(f2) >0 1 drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 318bfa2cda8..a9b2345d834 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1253,3 +1253,29 @@ id 5 99 drop table t1; +create table t1 (f1 decimal(60,25), f2 decimal(60,25)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +f1 +0.0000000000000000000000000 +0.0000000000000000000000000 +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +description f1 +XXXXXXXXXXXXXXXXXXXX 0.0000000000000000000000000 +YYYYYYYYYYYYYYYYYYYY 0.0000000000000000000000000 +drop table t1; +create table t1 (f1 decimal(60,24), f2 decimal(60,24)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +f1 +0.000000000000000000000000 +0.000000000000000000000000 +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +description f1 +XXXXXXXXXXXXXXXXXXXX 0.000000000000000000000000 +YYYYYYYYYYYYYYYYYYYY 0.000000000000000000000000 +drop table t1; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 74c628f96c4..7854fd773a1 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -345,3 +345,16 @@ f1 2000-01-01 2002-02-02 drop table t1; +create table t1 (f1 int); +create table t2 (f2 int); +insert into t1 values(1),(2); +insert into t2 values(1),(1); +update t1,t2 set f1=3,f2=3 where f1=f2 and f1=1; +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +update t2 set f2=1; +update t1 set f1=1 where f1=3; +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; diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 6ceb0ea0789..de9709b97ad 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -930,4 +930,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera"); SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd"); DROP TABLE t1; -# End of 4.1 tests +# +# Bug #15536: Crash when DELETE with subquery using BDB tables +# +create table t1 (a int, key(a)) engine=bdb; +create table t2 (b int, key(b)) engine=bdb; +insert into t1 values (1),(1),(2),(3),(4); +insert into t2 values (1),(5),(6),(7); +delete from t1 where (a in (select b from t2)); +select count(*) from t1; +# INSERT also blows up +--error 1242 +insert into t1 set a=(select b from t2); +select count(*) from t1; +# UPDATE also blows up +update t1 set a = a + 1 where (a in (select b from t2)); +select count(*) from t1; +drop table t1, t2; + +--echo End of 4.1 tests diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 9949ef88da4..5648cea7fd3 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); insert into t1 values (_koi8r'×ÁÓÑ'); # this is possible: select * from t1 where a=_koi8r'×ÁÓÑ'; -# this is not possible, because we have a function, not just a constant: ---error 1267 +# this is possible, because we have a function with constant arguments: select * from t1 where a=concat(_koi8r'×ÁÓÑ'); # this is not posible, cannot convert _latin1'×ÁÓÑ' into cp1251: --error 1267 @@ -154,6 +153,14 @@ drop table t1; set names latin1; # +# Bug#10446 Illegal mix of collations +# +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +drop table t1; + +# # Check more automatic conversion # set names koi8r; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 7c7927b638b..1399b9bfdff 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -354,6 +354,7 @@ SET myisam_repair_threads=@@global.myisam_repair_threads; # INSERT INTO t1 VALUES('testword\'\''); 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; # End of 4.1 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 72af9024070..87d9d601c87 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -38,4 +38,9 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) ); drop table t1; +# Test for BUG#9535 +create table t1 as select uuid(), length(uuid()); +show create table t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b0de62e679c..039e41dcf34 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -409,4 +409,16 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +show grants for root@localhost; +flush privileges; +show grants for root@localhost; +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +set names latin1; + # End of 4.1 tests diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 3a693968769..03aa113c662 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1280,4 +1280,53 @@ connection a; checksum table test_checksum; drop table test_checksum; +# tests for bugs #9802 and #13778 + +# test that FKs between invalid types are not accepted + +set foreign_key_checks=0; +create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; +-- error 1005 +create table t1(a char(10) primary key, b varchar(20)) engine = innodb; +set foreign_key_checks=1; +drop table t2; + +# test that FKs between different charsets are not accepted in CREATE even +# when f_k_c is 0 + +set foreign_key_checks=0; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +-- error 1005 +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; +set foreign_key_checks=1; +drop table t1; + +# test that invalid datatype conversions with ALTER are not allowed + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; +create table t1(a varchar(10) primary key) engine = innodb; +-- error 1025,1025 +alter table t1 modify column a int; +set foreign_key_checks=1; +drop table t2,t1; + +# test that charset conversions with ALTER are allowed when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +alter table t1 convert to character set utf8; +set foreign_key_checks=1; +drop table t2,t1; + +# test that RENAME does not allow invalid charsets when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; +-- error 1025 +rename table t3 to t1; +set foreign_key_checks=1; +drop table t2,t3; # End of 4.1 tests diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index d89b81859e7..22383a82bca 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -149,7 +149,7 @@ connection server1; alter table t1 drop index c; connection server2; # This should fail since index information is not automatically refreshed ---error 1105 +--error 1015 select * from t1 where b = 'two'; select * from t1 where b = 'two'; connection server1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c4cb0056763..82dfc643801 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -718,4 +718,33 @@ set @@tx_isolation=default; execute stmt; deallocate prepare stmt; +# +# Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" +# +# Part I. Make sure the typelib for ENUM is created in the statement memory +# root. +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Part II. Make sure that when the default value is converted to UTF-8, +# the new item is # created in the statement memory root. +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Cleanup +set names default; +deallocate prepare stmt; + # End of 4.1 tests + diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index d08dc5fb352..3140739309e 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -712,6 +712,21 @@ show status like "Qcache_inserts"; show status like "Qcache_hits"; drop table t1; +# +# BUG#14652: Queries with leading '(' characters. +# +create table t1 (a int); +flush status; +(select a from t1) union (select a from t1); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +(select a from t1) union (select a from t1); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +drop table t1; + set GLOBAL query_cache_size=0; # End of 4.1 tests diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 6fd58252ed4..57ebc67db1d 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -29,7 +29,7 @@ sleep 2; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # this should fail right after start @@ -38,7 +38,7 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29 select * from t1; sleep 2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # try replicate all until second insert to t2; @@ -46,7 +46,7 @@ start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; sleep 4; select * from t2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # clean up diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 39c7cdfa8a9..996d5854854 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2237,4 +2237,15 @@ insert into t1 values (1,1); insert into t2 values (1,1),(1,2); select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; drop table t1,t2; + +# +# Bug #14482 Server crash when subselecting from the same table +# +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +drop table t1,t2; + # End of 4.1 tests diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 6a54909536a..1f6fc2c8d3b 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -756,4 +756,22 @@ select 99 union all select id from t1 order by 1; select id from t1 union all select 99 order by 1; drop table t1; +# +# Bug #14216: UNION + DECIMAL wrong values in result +# +create table t1 (f1 decimal(60,25), f2 decimal(60,25)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +drop table t1; +create table t1 (f1 decimal(60,24), f2 decimal(60,24)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index a21d10b6571..95adb40962c 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -270,4 +270,21 @@ insert into t1 values('2000-01-01'),('0000-00-00'); update t1 set f1='2002-02-02' where f1 is null; select * from t1; drop table t1; + +# +# Bug#15028 Multitable update returns different numbers of matched rows +# depending on table order +create table t1 (f1 int); +create table t2 (f2 int); +insert into t1 values(1),(2); +insert into t2 values(1),(1); +--enable_info +update t1,t2 set f1=3,f2=3 where f1=f2 and f1=1; +--disable_info +update t2 set f2=1; +update t1 set f1=1 where f1=3; +--enable_info +update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1; +--disable_info +drop table t1,t2; # End of 4.1 tests diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 56af24c5cf0..9997d365fa4 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -786,13 +786,17 @@ Backup::checkNodeFail(Signal* signal, pos= &ref->nodeId - signal->getDataPtr(); break; } + case GSN_WAIT_GCP_REQ: + case GSN_DROP_TRIG_REQ: case GSN_CREATE_TRIG_REQ: case GSN_ALTER_TRIG_REQ: - case GSN_WAIT_GCP_REQ: + ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail); + return; case GSN_UTIL_SEQUENCE_REQ: case GSN_UTIL_LOCK_REQ: - case GSN_DROP_TRIG_REQ: return; + default: + ndbrequire(false); } for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; ) @@ -1803,7 +1807,7 @@ Backup::execBACKUP_FRAGMENT_CONF(Signal* signal) const Uint32 nodeId = refToNode(signal->senderBlockRef()); const Uint32 noOfBytes = conf->noOfBytes; const Uint32 noOfRecords = conf->noOfRecords; - + BackupRecordPtr ptr; c_backupPool.getPtr(ptr, ptrI); @@ -1880,7 +1884,7 @@ Backup::execBACKUP_FRAGMENT_REF(Signal* signal) } } } - ndbrequire(false); + goto err; done: ptr.p->masterData.sendCounter--; @@ -1892,7 +1896,8 @@ done: masterAbort(signal, ptr); return; }//if - + +err: AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend(); ord->backupId = ptr.p->backupId; ord->backupPtr = ptr.i; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 5bd35812b47..6564963f61a 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -11694,7 +11694,6 @@ Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr) // broken trigger allowed if force if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) { jam(); - ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE); alterTrigger_sendReply(signal, opPtr, false); return; } diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 37800c5d79b..c23264cdbbd 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -347,6 +347,8 @@ void start_master() add_arg(&al, "--character-sets-dir=%s", char_dir); add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); add_arg(&al, "--language=%s", lang_dir); + add_arg(&al, "--log-slow-queries"); + add_arg(&al, "--log-queries-not-using-indexes"); #ifdef DEBUG //only for debug builds add_arg(&al, "--debug"); #endif @@ -520,6 +522,8 @@ void start_slave() add_arg(&al, "--master-retry-count=10"); add_arg(&al, "-O"); add_arg(&al, "slave_net_timeout=10"); + add_arg(&al, "--log-slow-queries"); + add_arg(&al, "--log-queries-not-using-indexes"); #ifdef DEBUG //only for debug builds add_arg(&al, "--debug"); #endif diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 5c81dd2163c..b188cfcba21 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4729,6 +4729,7 @@ ha_innobase::update_table_comment( uint length = strlen(comment); char* str; row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + long flen; /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table @@ -4748,43 +4749,43 @@ ha_innobase::update_table_comment( trx_search_latch_release_if_reserved(prebuilt->trx); str = NULL; - if (FILE* file = os_file_create_tmpfile()) { - long flen; + /* output the data to a temporary file */ - /* output the data to a temporary file */ - fprintf(file, "InnoDB free: %lu kB", + mutex_enter_noninline(&srv_dict_tmpfile_mutex); + rewind(srv_dict_tmpfile); + + fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB", (ulong) fsp_get_available_space_in_free_extents( prebuilt->table->space)); - dict_print_info_on_foreign_keys(FALSE, file, + dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile, prebuilt->trx, prebuilt->table); - flen = ftell(file); - if (flen < 0) { - flen = 0; - } else if (length + flen + 3 > 64000) { - flen = 64000 - 3 - length; - } + flen = ftell(srv_dict_tmpfile); + if (flen < 0) { + flen = 0; + } else if (length + flen + 3 > 64000) { + flen = 64000 - 3 - length; + } - /* allocate buffer for the full string, and - read the contents of the temporary file */ + /* allocate buffer for the full string, and + read the contents of the temporary file */ - str = my_malloc(length + flen + 3, MYF(0)); + str = my_malloc(length + flen + 3, MYF(0)); - if (str) { - char* pos = str + length; - if(length) { - memcpy(str, comment, length); - *pos++ = ';'; - *pos++ = ' '; - } - rewind(file); - flen = fread(pos, 1, flen, file); - pos[flen] = 0; + if (str) { + char* pos = str + length; + if (length) { + memcpy(str, comment, length); + *pos++ = ';'; + *pos++ = ' '; } - - fclose(file); + rewind(srv_dict_tmpfile); + flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile); + pos[flen] = 0; } + mutex_exit_noninline(&srv_dict_tmpfile_mutex); + prebuilt->trx->op_info = (char*)""; return(str ? str : (char*) comment); @@ -4802,6 +4803,7 @@ ha_innobase::get_foreign_key_create_info(void) { row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; char* str = 0; + long flen; ut_a(prebuilt != NULL); @@ -4811,47 +4813,42 @@ ha_innobase::get_foreign_key_create_info(void) update_thd(current_thd); - if (FILE* file = os_file_create_tmpfile()) { - long flen; + prebuilt->trx->op_info = (char*)"getting info on foreign keys"; - prebuilt->trx->op_info = (char*)"getting info on foreign keys"; + /* In case MySQL calls this in the middle of a SELECT query, + release possible adaptive hash latch to avoid + deadlocks of threads */ - /* In case MySQL calls this in the middle of a SELECT query, - release possible adaptive hash latch to avoid - deadlocks of threads */ + trx_search_latch_release_if_reserved(prebuilt->trx); - trx_search_latch_release_if_reserved(prebuilt->trx); + mutex_enter_noninline(&srv_dict_tmpfile_mutex); + rewind(srv_dict_tmpfile); - /* output the data to a temporary file */ - dict_print_info_on_foreign_keys(TRUE, file, + /* output the data to a temporary file */ + dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile, prebuilt->trx, prebuilt->table); - prebuilt->trx->op_info = (char*)""; - - flen = ftell(file); - if (flen < 0) { - flen = 0; - } else if(flen > 64000 - 1) { - flen = 64000 - 1; - } + prebuilt->trx->op_info = (char*)""; - /* allocate buffer for the string, and - read the contents of the temporary file */ + flen = ftell(srv_dict_tmpfile); + if (flen < 0) { + flen = 0; + } else if (flen > 64000 - 1) { + flen = 64000 - 1; + } - str = my_malloc(flen + 1, MYF(0)); + /* allocate buffer for the string, and + read the contents of the temporary file */ - if (str) { - rewind(file); - flen = fread(str, 1, flen, file); - str[flen] = 0; - } + str = my_malloc(flen + 1, MYF(0)); - fclose(file); - } else { - /* unable to create temporary file */ - str = my_strdup( -"/* Error: cannot display foreign key constraints */", MYF(0)); + if (str) { + rewind(srv_dict_tmpfile); + flen = (uint) fread(str, 1, flen, srv_dict_tmpfile); + str[flen] = 0; } + mutex_exit_noninline(&srv_dict_tmpfile_mutex); + return(str); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4dc113ed443..594551b918a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3285,12 +3285,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); } - if (m_table != (void *)tab) - { - m_table= (void *)tab; - m_table_version = tab->getObjectVersion(); - } - else if (m_table_version < tab->getObjectVersion()) + if (m_table_version < tab->getObjectVersion()) { /* The table has been altered, caller has to retry @@ -3298,6 +3293,13 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); DBUG_RETURN(ndb_to_mysql_error(&err)); } + if (m_table != (void *)tab) + { + m_table= (void *)tab; + m_table_version = tab->getObjectVersion(); + if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + DBUG_RETURN(my_errno); + } m_table_info= tab_info; } no_uncommitted_rows_init(thd); diff --git a/sql/item.cc b/sql/item.cc index 642a0ccf1b4..f996e962cca 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -211,16 +211,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const Item *Item::safe_charset_converter(CHARSET_INFO *tocs) { - /* - Allow conversion from and to "binary". - Don't allow automatic conversion to non-Unicode charsets, - as it potentially loses data. - */ - if (collation.collation != &my_charset_bin && - tocs != &my_charset_bin && - !(tocs->state & MY_CS_UNICODE)) - return NULL; // safe conversion is not possible - return new Item_func_conv_charset(this, tocs); + Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1); + return conv->safe ? conv : NULL; } @@ -2863,7 +2855,7 @@ Item_result item_cmp_type(Item_result a,Item_result b) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; - Item *new_item; + Item *new_item= NULL; if (item->basic_const_item()) return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), @@ -2892,8 +2884,17 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } - else if (res_type == ROW_RESULT) + else if (res_type == ROW_RESULT && item->type() == Item::ROW_ITEM && + comp_item->type() == Item::ROW_ITEM) { + /* + Substitute constants only in Item_rows. Don't affect other Items + with ROW_RESULT (eg Item_singlerow_subselect). + + For such Items more optimal is to detect if it is constant and replace + it with Item_row. This would optimize queries like this: + SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); + */ Item_row *item_row= (Item_row*) item; Item_row *comp_item_row= (Item_row*) comp_item; uint col; @@ -2910,7 +2911,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) while (col-- > 0) resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col)); } - else + else if (res_type == REAL_RESULT) { // It must REAL_RESULT double result=item->val(); uint length=item->max_length,decimals=item->decimals; @@ -3274,8 +3275,11 @@ bool Item_type_holder::join_types(THD *thd, Item *item) { int delta1= max_length_orig - decimals_orig; int delta2= item->max_length - item->decimals; - max_length= min(max(delta1, delta2) + decimals, - (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7); + if (fld_type == MYSQL_TYPE_DECIMAL) + max_length= max(delta1, delta2) + decimals; + else + max_length= min(max(delta1, delta2) + decimals, + (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7); } else max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6ca6ce62c54..60cb3348590 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2252,6 +2252,8 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (use_cached_value) + return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 87aee9ac25c..89bab4a909c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -614,10 +614,40 @@ public: class Item_func_conv_charset :public Item_str_func { + bool use_cached_value; public: + bool safe; CHARSET_INFO *conv_charset; // keep it public - Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { conv_charset=cs; } + Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) + { conv_charset= cs; use_cached_value= 0; safe= 0; } + Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) + :Item_str_func(a) + { + DBUG_ASSERT(args[0]->fixed); + conv_charset= cs; + if (cache_if_const && args[0]->const_item()) + { + uint errors= 0; + String tmp, *str= args[0]->val_str(&tmp); + if (!str || str_value.copy(str->ptr(), str->length(), + str->charset(), conv_charset, &errors)) + null_value= 1; + use_cached_value= 1; + safe= (errors == 0); + } + else + { + use_cached_value= 0; + /* + Conversion from and to "binary" is safe. + Conversion to Unicode is safe. + Other kind of conversions are potentially lossy. + */ + safe= (args[0]->collation.collation == &my_charset_bin || + cs == &my_charset_bin || + (cs->state & MY_CS_UNICODE)); + } + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "convert"; } @@ -718,7 +748,12 @@ public: Item_func_uuid(): Item_str_func() {} void fix_length_and_dec() { collation.set(system_charset_info); - max_length= UUID_LENGTH; + /* + NOTE! uuid() should be changed to use 'ascii' + charset when hex(), format(), md5(), etc, and implicit + number-to-string conversion will use 'ascii' + */ + max_length= UUID_LENGTH * system_charset_info->mbmaxlen; } const char *func_name() const{ return "uuid"; } String *val_str(String *); diff --git a/sql/log_event.cc b/sql/log_event.cc index be4654bccd3..3f545df5776 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2035,7 +2035,7 @@ Rotate_log_event::Rotate_log_event(THD* thd_arg, llstr(pos_arg, buff), flags)); #endif if (flags & DUP_NAME) - new_log_ident= my_strdup_with_length(new_log_ident_arg, + new_log_ident= my_strdup_with_length((byte*) new_log_ident_arg, ident_len, MYF(MY_WME)); DBUG_VOID_RETURN; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a9057ae24f6..c128fac8d9e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1119,7 +1119,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week); uint calc_week(TIME *l_time, uint week_behaviour, uint *year); void find_date(char *pos,uint *vek,uint flag); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); -TYPELIB *typelib(List<String> &strings); +TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); diff --git a/sql/share/charsets/latin5.xml b/sql/share/charsets/latin5.xml index 67e5873c503..5004f045889 100644 --- a/sql/share/charsets/latin5.xml +++ b/sql/share/charsets/latin5.xml @@ -112,11 +112,6 @@ <collation name="latin5_turkish_ci"> -<!-- -# Note: all accented characters are compared separately (this -# is different from the default latin1 character set, where -# e.g. a = ä = á, etc.). ---> <map> 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F @@ -130,10 +125,10 @@ 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB - CC CD CE CF D0 D1 D2 44 D3 D4 D5 D6 D7 D8 D9 DA - 49 DB DC DD DE DF 53 E0 E1 E2 E3 E4 5B 4C 58 E5 - CC CD CE CF D0 D1 D2 44 D3 D4 D5 D6 D7 D8 D9 DA - 49 DB DC DD DE DF 53 FA E1 E2 E3 E4 5B 4B 58 FF + 41 41 41 41 41 41 41 44 46 46 46 46 4C 4C 4C 4C + 49 51 52 52 52 52 53 E0 52 5A 5A 5A 5B 4C 58 57 + 41 41 41 41 41 41 41 44 46 46 46 46 4C 4C 4C 4C + 49 51 52 52 52 52 53 FA 52 5A 5A 5A 5B 4B 58 5F </map> </collation> diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 47c6343bc3b..1ade6ce3064 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -903,7 +903,7 @@ static void acl_update_user(const char *user, const char *host, { if (!acl_user->host.hostname && !host[0] || acl_user->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_user->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) { acl_user->access=privileges; if (mqh->bits & 1) @@ -982,7 +982,7 @@ static void acl_update_db(const char *user, const char *host, const char *db, { if (!acl_db->host.hostname && !host[0] || acl_db->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_db->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -1128,7 +1128,7 @@ static void init_check_host(void) DBUG_ENTER("init_check_host"); VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); - VOID(hash_init(&acl_check_hosts,&my_charset_latin1,acl_users.elements,0,0, + VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,0)); if (!allow_all_hosts) { @@ -1144,7 +1144,7 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(&my_charset_latin1, + if (!my_strcasecmp(system_charset_info, acl_user->host.hostname, acl->hostname)) break; // already stored } @@ -1225,7 +1225,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(&my_charset_latin1, host, thd->priv_host))) + my_strcasecmp(system_charset_info, host, thd->priv_host))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) return(1); @@ -1434,7 +1434,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, return (tmp & host->ip_mask) == host->ip; } return (!host->hostname || - (hostname && !wild_case_compare(&my_charset_latin1, + (hostname && !wild_case_compare(system_charset_info, hostname,host->hostname)) || (ip && !wild_compare(ip,host->hostname,0))); } @@ -1447,7 +1447,7 @@ bool hostname_requires_resolving(const char *hostname) int namelen= strlen(hostname); int lhlen= strlen(my_localhost); if ((namelen == lhlen) && - !my_strnncoll(&my_charset_latin1, (const uchar *)hostname, namelen, + !my_strnncoll(system_charset_info, (const uchar *)hostname, namelen, (const uchar *)my_localhost, strlen(my_localhost))) return FALSE; for (; (cur=*hostname); hostname++) @@ -1481,8 +1481,8 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_ENTER("update_user_table"); DBUG_PRINT("enter",("user: %s host: %s",user,host)); - table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1); - table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -1494,7 +1494,7 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - table->field[2]->store(new_password, new_password_len, &my_charset_latin1); + table->field[2]->store(new_password, new_password_len, system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1559,8 +1559,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, password=combo.password.str; } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, (byte*) table->field[0]->ptr, @@ -1579,18 +1579,18 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values table->field[0]->store(combo.host.str,combo.host.length, - &my_charset_latin1); + system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, - &my_charset_latin1); + system_charset_info); table->field[2]->store(password, password_len, - &my_charset_latin1); + system_charset_info); } else { old_row_exists = 1; store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password, password_len, &my_charset_latin1); + table->field[2]->store(password, password_len, system_charset_info); else if (!rights && !revoke_grant && thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !thd->lex->mqh.bits) { @@ -1637,15 +1637,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (thd->lex->ssl_cipher) table->field[next_field+1]->store(thd->lex->ssl_cipher, strlen(thd->lex->ssl_cipher), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_issuer) table->field[next_field+2]->store(thd->lex->x509_issuer, strlen(thd->lex->x509_issuer), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_subject) table->field[next_field+3]->store(thd->lex->x509_subject, strlen(thd->lex->x509_subject), - &my_charset_latin1); + system_charset_info); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1750,9 +1750,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr, @@ -1766,9 +1766,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1880,7 +1880,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); } @@ -1916,17 +1916,17 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) privs = fix_rights_for_table(privs); cols = fix_rights_for_column(cols); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); if (cols) { int key_len; col_privs->field[0]->store(host.hostname, host.hostname ? (uint) strlen(host.hostname) : 0, - &my_charset_latin1); - col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); - col_privs->field[3]->store(tname,(uint) strlen(tname), &my_charset_latin1); + system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ @@ -2032,10 +2032,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table,0,key_length); @@ -2053,7 +2053,7 @@ static int replace_column_table(GRANT_TABLE *g_t, bool old_row_exists=0; key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, @@ -2071,7 +2071,7 @@ static int replace_column_table(GRANT_TABLE *g_t, restore_record(table,default_values); // Get empty record key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); } else { @@ -2143,7 +2143,8 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf),&my_charset_latin1); + String column_name(colum_name_buf,sizeof(colum_name_buf), + system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -2213,10 +2214,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,default_values); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,record[1]); // store at pos 1 table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -2261,7 +2262,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2727,7 +2728,7 @@ static my_bool grant_load(TABLE_LIST *tables) DBUG_ENTER("grant_load"); grant_option = FALSE; - (void) hash_init(&column_priv_hash,&my_charset_latin1, + (void) hash_init(&column_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); @@ -3206,7 +3207,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_user->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } if (counter == acl_users.elements) @@ -3340,7 +3341,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; if (want_access) @@ -3400,7 +3401,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) user= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, + !my_strcasecmp(system_charset_info, lex_user->host.str, grant_table->host.hostname)) { ulong table_access= grant_table->privs; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 4214c9a7c07..b40257511f7 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -956,16 +956,26 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) goto err; } - /* - Test if the query is a SELECT - (pre-space is removed in dispatch_command) - */ - if (my_toupper(system_charset_info, sql[0]) != 'S' || - my_toupper(system_charset_info, sql[1]) != 'E' || - my_toupper(system_charset_info,sql[2]) !='L') { - DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); - goto err; + uint i= 0; + /* + Skip '(' characters in queries like following: + (select a from t1) union (select a from t1); + */ + while (sql[i]=='(') + i++; + + /* + Test if the query is a SELECT + (pre-space is removed in dispatch_command) + */ + if (my_toupper(system_charset_info, sql[i]) != 'S' || + my_toupper(system_charset_info, sql[i + 1]) != 'E' || + my_toupper(system_charset_info, sql[i + 2]) != 'L') + { + DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); + goto err; + } } STRUCT_LOCK(&structure_guard_mutex); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 079a301818c..203173f52f4 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -241,6 +241,7 @@ cleanup: if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; } + free_underlaid_joins(thd, &thd->lex->select_lex); if (transactional_table) { if (ha_autocommit_or_rollback(thd,error >= 0)) @@ -252,7 +253,6 @@ cleanup: mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0); else diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8c6fed26f8e..283fe571d53 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -194,7 +194,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, runs without --log-update or --log-bin). */ int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ; - bool transactional_table, log_delayed; + bool transactional_table, log_delayed, joins_freed= FALSE; uint value_count; ulong counter = 1; ulonglong id; @@ -386,6 +386,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->row_count++; } + free_underlaid_joins(thd, &thd->lex->select_lex); + joins_freed= TRUE; + /* Now all rows are inserted. Time to update logs and sends response to user @@ -480,7 +483,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff); } - free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; DBUG_RETURN(0); @@ -489,7 +491,8 @@ abort: if (lock_type == TL_WRITE_DELAYED) end_delayed_insert(thd); #endif - free_underlaid_joins(thd, &thd->lex->select_lex); + if (!joins_freed) + free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; DBUG_RETURN(-1); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a2ad8a414f8..fbca542dc24 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -689,6 +689,9 @@ static int check_connection(THD *thd) DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); +#ifdef SIGNAL_WITH_VIO_CLOSE + thd->set_active_vio(net->vio); +#endif if (!thd->host) // If TCP/IP connection { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0e0a05ea099..294c59af90f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -524,7 +524,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (!interval) { - interval= sql_field->interval= typelib(sql_field->interval_list); + /* + Create the typelib in prepared statement memory if we're + executing one. + */ + MEM_ROOT *stmt_root= thd->current_arena->mem_root; + + interval= sql_field->interval= typelib(stmt_root, + sql_field->interval_list); List_iterator<String> it(sql_field->interval_list); String conv, *tmp; for (uint i= 0; (tmp= it++); i++) @@ -534,7 +541,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - char *buf= (char*) sql_alloc(conv.length()+1); + char *buf= (char*) alloc_root(stmt_root, conv.length()+1); memcpy(buf, conv.ptr(), conv.length()); buf[conv.length()]= '\0'; interval->type_names[i]= buf; @@ -556,8 +563,22 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && cs != sql_field->def->collation.collation) { - if (!(sql_field->def= - sql_field->def->safe_charset_converter(cs))) + Item_arena backup_arena; + bool need_to_change_arena= + !thd->current_arena->is_conventional_execution(); + if (need_to_change_arena) + { + /* Asser that we don't do that at every PS execute */ + DBUG_ASSERT(thd->current_arena->is_first_stmt_execute()); + thd->set_n_backup_item_arena(thd->current_arena, &backup_arena); + } + + sql_field->def= sql_field->def->safe_charset_converter(cs); + + if (need_to_change_arena) + thd->restore_backup_item_arena(thd->current_arena, &backup_arena); + + if (! sql_field->def) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index cb8064bef87..7b1d5988bde 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -377,6 +377,7 @@ int mysql_update(THD *thd, if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; } + free_underlaid_joins(thd, &thd->lex->select_lex); if (transactional_table) { if (ha_autocommit_or_rollback(thd, error >= 0)) @@ -389,7 +390,6 @@ int mysql_update(THD *thd, thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */ else @@ -1082,22 +1082,23 @@ bool multi_update::send_data(List<Item> ¬_used_values) int error; TABLE *tmp_table= tmp_tables[offset]; fill_record(tmp_table->field+1, *values_for_table[offset], 1); - found++; /* Store pointer to row */ memcpy((char*) tmp_table->field[0]->ptr, (char*) table->file->ref, table->file->ref_length); /* Write row, ignoring duplicated updates to a row */ - if ((error= tmp_table->file->write_row(tmp_table->record[0])) && - (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE)) + if (error= tmp_table->file->write_row(tmp_table->record[0])) { - if (create_myisam_from_heap(thd, tmp_table, tmp_table_param + offset, - error, 1)) + if (error != HA_ERR_FOUND_DUPP_KEY && + error != HA_ERR_FOUND_DUPP_UNIQUE && + create_myisam_from_heap(thd, tmp_table, + tmp_table_param + offset, error, 1)) { do_update=0; DBUG_RETURN(1); // Not a table_is_full error } } + else + found++; } } DBUG_RETURN(0); diff --git a/sql/table.cc b/sql/table.cc index 04d1a95cd9b..de539205ffd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, } /* fix_type_pointers */ -TYPELIB *typelib(List<String> &strings) +TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings) { - TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB)); + TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); if (!result) return 0; result->count=strings.elements; result->name=""; uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); - if (!(result->type_names= (const char**) sql_alloc(nbytes))) + if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) return 0; result->type_lengths= (uint*) (result->type_names + result->count + 1); List_iterator<String> it(strings); diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 7a1219736ae..7afdae69439 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -249,7 +249,6 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --enable-thread-safe-client \ - --with-zlib-dir=bundled \ --with-readline ; # Add this for more debugging support # --with-debug @@ -351,8 +350,9 @@ BuildMySQL "--disable-shared \ %if %{STATIC_BUILD} --with-mysqld-ldflags='-all-static' \ --with-client-ldflags='-all-static' \ - --with-zlib-dir=bundled \ $USE_OTHER_LIBC_DIR \ +%else + --with-zlib-dir=bundled \ %endif --with-comment=\"MySQL Community Edition - Standard (GPL)\" \ --with-server-suffix='%{server_suffix}' \ @@ -487,22 +487,22 @@ echo "Restarting mysqld." %preun server if test $1 = 0 then - # Stop MySQL before uninstalling it + # Stop MySQL before uninstalling it if test -x %{_sysconfdir}/init.d/mysql then %{_sysconfdir}/init.d/mysql stop > /dev/null - fi - # Remove autostart of mysql - # for older SuSE Linux versions - if test -x /sbin/insserv - then - /sbin/insserv -r %{_sysconfdir}/init.d/mysql - # use chkconfig on Red Hat and newer SuSE releases - elif test -x /sbin/chkconfig - then - /sbin/chkconfig --del mysql - fi + # Remove autostart of mysql + # for older SuSE Linux versions + if test -x /sbin/insserv + then + /sbin/insserv -r %{_sysconfdir}/init.d/mysql + # use chkconfig on Red Hat and newer SuSE releases + elif test -x /sbin/chkconfig + then + /sbin/chkconfig --del mysql + fi + fi fi # We do not remove the mysql user since it may still own a lot of @@ -689,6 +689,17 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Dec 05 2005 Joerg Bruehe <joerg@mysql.com> + +- Avoid using the "bundled" zlib on "shared" builds: + As it is not installed (on the build system), this gives dependency + problems with "libtool" causing the build to fail. + +* Tue Nov 22 2005 Joerg Bruehe <joerg@mysql.com> + +- Extend the file existence check for "init.d/mysql" on un-install + to also guard the call to "insserv"/"chkconfig". + * Thu Oct 27 2005 Lenz Grimmer <lenz@grimmer.com> - added more man pages diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 498d10da0ee..46306cf48bb 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -191,9 +191,6 @@ void netware_ssl_cleanup() /* NetWare SSL initialization */ static void netware_ssl_init() { - /* initialize OpenSSL library */ - SSL_library_init(); - /* cleanup OpenSSL library */ NXVmRegisterExitHandler(netware_ssl_cleanup, NULL); } @@ -231,16 +228,17 @@ new_VioSSLConnectorFd(const char* key_file, ptr->ssl_method= 0; /* FIXME: constants! */ -#ifdef __NETWARE__ - netware_ssl_init(); -#endif - if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; + SSL_library_init(); OpenSSL_add_all_algorithms(); } +#ifdef __NETWARE__ + netware_ssl_init(); +#endif + if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo:SSL_load_error_strings()")); @@ -325,17 +323,18 @@ new_VioSSLAcceptorFd(const char *key_file, /* FIXME: constants! */ ptr->session_id_context= ptr; -#ifdef __NETWARE__ - netware_ssl_init(); -#endif - if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; + SSL_library_init(); OpenSSL_add_all_algorithms(); } +#ifdef __NETWARE__ + netware_ssl_init(); +#endif + if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo: SSL_load_error_strings()")); |