From 462ee7c4175436938785c06c77394247b83d0d87 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 19:26:11 +0500 Subject: [PATCH 01/17] A fix (bug #2631: mlockall called after dropping root permissions). --- sql/mysqld.cc | 124 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 37 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 670e6a5a63e..06599cf0ea7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -414,6 +414,7 @@ char mysql_real_data_home[FN_REFLEN], max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; char *language_ptr= language; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; +struct passwd *user_info; #ifndef EMBEDDED_LIBRARY bool mysql_embedded=0; #else @@ -1028,27 +1029,26 @@ static void set_ports() } } -/* Change to run as another user if started with --user */ -static void set_user(const char *user) +static struct passwd *check_user(const char *user) { -#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) - struct passwd *ent; +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + struct passwd *user_info; uid_t user_id= geteuid(); - - // don't bother if we aren't superuser + + // Don't bother if we aren't superuser if (user_id) { if (user) { - /* Don't give a warning, if real user is same as given with --user */ - struct passwd *user_info= getpwnam(user); + // Don't give a warning, if real user is same as given with --user + user_info= getpwnam(user); if ((!user_info || user_id != user_info->pw_uid) && - global_system_variables.log_warnings) - fprintf(stderr, - "Warning: One can only use the --user switch if running as root\n"); + global_system_variables.log_warnings) + fprintf(stderr, + "Warning: One can only use the --user switch if running as root\n"); } - return; + return NULL; } if (!user) { @@ -1057,38 +1057,52 @@ static void set_user(const char *user) fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n"); unireg_abort(1); } - return; + return NULL; } if (!strcmp(user,"root")) - return; // Avoid problem with dynamic libraries - - uid_t uid; - if (!(ent = getpwnam(user))) + return NULL; // Avoid problem with dynamic libraries + if (!(user_info= getpwnam(user))) { - // allow a numeric uid to be used + // Allow a numeric uid to be used const char *pos; - for (pos=user; isdigit(*pos); pos++) ; - if (*pos) // Not numeric id - { - fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); - unireg_abort(1); - } - uid=atoi(user); // Use numberic uid + for (pos= user; isdigit(*pos); pos++); + if (*pos) // Not numeric id + goto err; + if (!(user_info= getpwuid(atoi(user)))) + goto err; + else + return user_info; } else { -#ifdef HAVE_INITGROUPS - initgroups((char*) user,ent->pw_gid); -#endif - if (setgid(ent->pw_gid) == -1) - { - sql_perror("setgid"); - unireg_abort(1); - } - uid=ent->pw_uid; + return user_info; } - if (setuid(uid) == -1) +err: + fprintf(stderr, + "Fatal error: Can't change to run as user '%s'. Please check that the user exists!\n", + user); + unireg_abort(1); + return NULL; +#else + return NULL; +#endif +} + + +static void set_user(const char *user, struct passwd *user_info) +{ +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + DBUG_ASSERT(user_info); +#ifdef HAVE_INITGROUPS + initgroups((char*) user, user_info->pw_gid); +#endif + if (setgid(user_info->pw_gid) == -1) + { + sql_perror("setgid"); + unireg_abort(1); + } + if (setuid(user_info->pw_uid) == -1) { sql_perror("setuid"); unireg_abort(1); @@ -1096,6 +1110,24 @@ static void set_user(const char *user) #endif } +static void set_effective_user(struct passwd *user_info) +{ +#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) + DBUG_ASSERT(user_info); + if (setegid(user_info->pw_gid) == -1) + { + sql_perror("setegid"); + unireg_abort(1); + } + if (seteuid(user_info->pw_uid) == -1) + { + sql_perror("seteuid"); + unireg_abort(1); + } +#endif +} + + /* Change root user if started with --chroot */ static void set_root(const char *path) @@ -1171,7 +1203,18 @@ static void server_init(void) unireg_abort(1); } } - set_user(mysqld_user); // Works also with mysqld_user==NULL + + if ((user_info= check_user(mysqld_user))) + { +#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) + if (locked_in_memory && !getuid()) + set_effective_user(user_info); + else + set_user(mysqld_user, user_info); +#else + set_user(mysqld_user, user_info); +#endif + } #ifdef __NT__ /* create named pipe */ @@ -2466,8 +2509,13 @@ You should consider changing lower_case_table_names to 1 or 2", } ha_key_cache(); #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) - if (locked_in_memory && !geteuid()) + if (locked_in_memory && !getuid()) { + if (seteuid(0) == -1) + { // this should never happen + sql_perror("seteuid"); + unireg_abort(1); + } if (mlockall(MCL_CURRENT)) { if (global_system_variables.log_warnings) @@ -2475,6 +2523,8 @@ You should consider changing lower_case_table_names to 1 or 2", } else locked_in_memory=1; + if (user_info) + set_user(mysqld_user, user_info); } #else locked_in_memory=0; From 8838c971fa6ced3a8cb90c154bc5b9e0ec4bfba5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 19:59:29 +0500 Subject: [PATCH 02/17] A fix (Bug #4980: union statement with () union () order by produces wrong explain). --- mysql-test/r/union.result | 9 ++++++++- mysql-test/t/union.test | 9 +++++++++ sql/sql_union.cc | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 4b9555c334b..8f33bc4c316 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -88,7 +88,6 @@ explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a l table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 4 t2 ALL NULL NULL NULL NULL 4 Using filesort -t1 ALL NULL NULL NULL NULL 4 (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; a b 1 a @@ -424,8 +423,16 @@ create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list select a from t1 union select a from t2 order by t2.a; Unknown column 't2.a' in 'ORDER BY' +drop table t1; drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; * 1 2 +create table t1 (a int); +insert into t1 values (0), (3), (1), (2); +explain (select * from t1) union (select * from t1) order by a; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 4 +t1 ALL NULL NULL NULL NULL 4 +drop table t1; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c978aef9ce0..65b062d663f 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -228,6 +228,7 @@ create temporary table t1 select a from t1 union select a from t2; create table t1 select a from t1 union select a from t2; --error 1054 select a from t1 union select a from t2 order by t2.a; +drop table t1; # Drop temporary table drop table t1,t2; # @@ -236,3 +237,11 @@ drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; +# +# Bug #4980: problem with explain +# + +create table t1 (a int); +insert into t1 values (0), (3), (1), (2); +explain (select * from t1) union (select * from t1) order by a; +drop table t1; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8088737c0de..f79ff7967db 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -148,6 +148,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { ha_rows records_at_start; lex->select=sl; +#if MYSQL_VERSION_ID < 40100 + if (describe && sl->linkage == NOT_A_SELECT) + break; // Skip extra item in case of 'explain' +#endif /* Don't use offset for the last union if there is no braces */ if (sl != lex_sl) { From 0d34c63536031ee2e104ec8cb94e5a1a3dd68ab4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 10:56:55 -0500 Subject: [PATCH 03/17] sql_yacc.yy: Allow FROM or IN in SHOW KEYS, as in other SHOW statements. sql/sql_yacc.yy: Allow FROM or IN in SHOW KEYS, as in other SHOW statements. --- sql/sql_yacc.yy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2199a0c8be5..6b073db2e36 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2917,7 +2917,7 @@ show_param: lex->select->select_limit= lex->thd->variables.select_limit; lex->select->offset_limit= 0L; } limit_clause - | keys_or_index FROM table_ident opt_db + | keys_or_index from_or_in table_ident opt_db { Lex->sql_command= SQLCOM_SHOW_KEYS; if ($4) From e9a404525242a1e9745f479a53d4b793b844b58b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Sep 2004 11:27:31 +0200 Subject: [PATCH 04/17] union.test: drop table added BitKeeper/etc/ignore: Added support-files/my-innodb-heavy-4G.cnf to the ignore list mysql-test/r/union.result: drop table added mysql-test/t/union.test: drop table added --- .bzrignore | 1 + mysql-test/r/union.result | 1 + mysql-test/t/union.test | 1 + 3 files changed, 3 insertions(+) diff --git a/.bzrignore b/.bzrignore index 8583b7ef437..1d14c09a602 100644 --- a/.bzrignore +++ b/.bzrignore @@ -545,3 +545,4 @@ vio/test-sslserver vio/viotest-ssl scripts/make_win_binary_distribution EXCEPTIONS-CLIENT +support-files/my-innodb-heavy-4G.cnf diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 4b9555c334b..45866cdf495 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -420,6 +420,7 @@ a (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; Wrong usage/placement of 'SQL_CALC_FOUND_ROWS' create temporary table t1 select a from t1 union select a from t2; +drop table t1; create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list select a from t1 union select a from t2 order by t2.a; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c978aef9ce0..2bcd50b11de 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -224,6 +224,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; create temporary table t1 select a from t1 union select a from t2; +drop table t1; --error 1093 create table t1 select a from t1 union select a from t2; --error 1054 From 71ba3e55b788e8c701b7292051f04e6fce55f26f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 16:48:11 +0500 Subject: [PATCH 05/17] A fix (bug #2205 USE database doesn't work after DROP database + CREATE database) (Jani's CS 1.1675 04/01/05 21:45:14 was adapted an aplied). client/mysql.cc: A fix (bug #2205 USE database doesn't work after DROP database + CREATE database). --- client/mysql.cc | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 154695aa9e5..1858699e8da 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2200,8 +2200,9 @@ static int com_source(String *buffer, char *line) static int com_use(String *buffer __attribute__((unused)), char *line) { - char *tmp; - char buff[256]; + char *tmp, buff[FN_REFLEN + 1]; + MYSQL_RES *res; + MYSQL_ROW row; while (isspace(*line)) line++; @@ -2214,6 +2215,30 @@ com_use(String *buffer __attribute__((unused)), char *line) put_info("USE must be followed by a database name",INFO_ERROR); return 0; } + /* + We need to recheck the current database, because it may change + under our feet, for example if DROP DATABASE or RENAME DATABASE + (latter one not yet available by the time the comment was written) + */ + current_db= 0; // Let's reset current_db, assume it's gone + /* + We don't care about in case of an error below because current_db + was just set to 0. + */ + if (!mysql_query(&mysql, "SELECT DATABASE()") && + (res= mysql_use_result(&mysql))) + { + row= mysql_fetch_row(res); + if (row[0] && + (!current_db || cmp_database(current_db, row[0]))) + { + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(row[0], MYF(MY_WME)); + } + (void) mysql_fetch_row(res); // Read eof + mysql_free_result(res); + } + if (!current_db || cmp_database(current_db,tmp)) { if (one_database) From 982a78829af9bc579fc884e641f5ec10cb1f478e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:20:40 +0200 Subject: [PATCH 06/17] bug#5389 merge.test fails on qnx - uninitalized variable in myrg_open() myisammrg/myrg_open.c: backport from 4.1 mysql-test/r/union.result: after merge fix mysql-test/t/union.test: after merge fix sql/log.cc: backward compatibility: inhibit severity labels in error log --- myisammrg/myrg_open.c | 28 ++++++++++++++-------------- mysql-test/r/union.result | 1 - mysql-test/t/union.test | 1 - sql/log.cc | 20 +++++++++++++------- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 4c6ffb98ad5..a59ccb7d966 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -34,14 +34,17 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,errpos=0; uint files=0,i,dir_length,length,key_parts; - ulonglong file_offset; + ulonglong file_offset=0; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO *m_info=0; File fd; IO_CACHE file; MI_INFO *isam=0; + uint found_merge_insert_method= 0; DBUG_ENTER("myrg_open"); + LINT_INIT(key_parts); + bzero((char*) &file,sizeof(file)); if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4), O_RDONLY | O_SHARE,MYF(0))) < 0) @@ -69,10 +72,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) continue; /* Skip empty lines */ if (buff[0] == '#') { - if( !strncmp(buff+1,"INSERT_METHOD=",14)) + if (!strncmp(buff+1,"INSERT_METHOD=",14)) { /* Lookup insert method */ int tmp=find_type(buff+15,&merge_insert_method,2); - m_info->merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); + found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); } continue; /* Skip comments */ } @@ -84,8 +87,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) VOID(cleanup_dirname(buff,name_buff)); } if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) - goto err; - if (!m_info) + goto err; + if (!m_info) /* First file */ { key_parts=isam->s->base.key_parts; if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO) + @@ -97,15 +100,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { m_info->open_tables=(MYRG_TABLE *) (m_info+1); m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files); + m_info->tables= files; + files= 0; } - else - { - m_info->open_tables=0; - m_info->rec_per_key_part=0; - } - m_info->tables=files; m_info->reclength=isam->s->base.reclength; - file_offset=files=0; errpos=3; } m_info->open_tables[files].table= isam; @@ -122,14 +120,16 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->del+= isam->state->del; m_info->data_file_length+= isam->state->data_file_length; for (i=0; i < key_parts; i++) - m_info->rec_per_key_part[i]+=isam->s->state.rec_per_key_part[i] / m_info->tables; + m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] / + m_info->tables); } if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO), - MYF(MY_WME|MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL)))) goto err; /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + m_info->merge_insert_method= found_merge_insert_method; if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 79c589774d8..0db18b090bc 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -424,7 +424,6 @@ create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list select a from t1 union select a from t2 order by t2.a; Unknown column 't2.a' in 'ORDER BY' -drop table t1; drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; * diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index e55cb3ea272..eb2d8dd6efa 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -229,7 +229,6 @@ drop table t1; create table t1 select a from t1 union select a from t2; --error 1054 select a from t1 union select a from t2 order by t2.a; -drop table t1; # Drop temporary table drop table t1,t2; # diff --git a/sql/log.cc b/sql/log.cc index 55ef2e72960..151d613f637 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1221,7 +1221,7 @@ bool MYSQL_LOG::write(Log_event* event_info) if (e.write(file)) goto err; } -#if MYSQL_VERSION_ID < 40100 +#if MYSQL_VERSION_ID < 40100 if (thd->variables.convert_set) { Query_log_event e(thd, "SET CHARACTER SET DEFAULT", 25, 0); @@ -1761,15 +1761,21 @@ void print_buffer_to_file(enum loglevel level, const char *buffer) skr=time(NULL); localtime_r(&skr, &tm_tmp); start=&tm_tmp; +#if MYSQL_VERSION_ID > 40100 fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", - start->tm_year % 100, - start->tm_mon+1, - start->tm_mday, - start->tm_hour, - start->tm_min, - start->tm_sec, +#else + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d %s\n", +#endif + start->tm_year % 100, + start->tm_mon+1, + start->tm_mday, + start->tm_hour, + start->tm_min, + start->tm_sec, +#if MYSQL_VERSION_ID > 40100 (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "WARNING" : "INFORMATION"), +#endif buffer); fflush(stderr); From e663f91ad7a7315c339713f390bf1fc5fec381ad Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:30:16 +0200 Subject: [PATCH 07/17] Dependency fix. We observed that doing any change to class THD in sql_class.h resulted in mysqld going crazy (parsing errors, query cache errors in query_cache.test). This is because sql_yacc.cc depends on several .h files but those were not listed in the dependencies of sql_yacc.o. The present patch does fix the issue; but my auto*-expert colleagues may have a better one. sql/Makefile.am: sql_yacc.c includes mysql_priv.h, slave.h etc, so sql_yacc.o does depend on these .h files; so they need to be listed in the dependencies. --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index 0a664a120a5..0fc81a48c63 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -108,7 +108,7 @@ gen_lex_hash.o: gen_lex_hash.cc lex.h sql_yacc.cc: sql_yacc.yy sql_yacc.h: sql_yacc.yy -sql_yacc.o: sql_yacc.cc sql_yacc.h +sql_yacc.o: sql_yacc.cc sql_yacc.h $(noinst_HEADERS) @echo "Note: The following compile may take a long time." @echo "If it fails, re-run configure with --with-low-memory" $(CXXCOMPILE) $(LM_CFLAGS) -c $< From ea971987fcc8479fdd3fbf185efedd8ed7ccbfd6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:47:26 +0200 Subject: [PATCH 08/17] Replacing class Disable_binlog by macros. Patch already approved by Monty. sql/log.cc: removing unneeded class Disable_binlog sql/sql_class.h: removing unneeded class Disable_binlog sql/sql_table.cc: As discussed, class Disable_binlog is removed and replaced by macros. --- sql/log.cc | 16 ---------------- sql/sql_class.h | 21 --------------------- sql/sql_table.cc | 47 ++++++++++++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 56 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 55ef2e72960..a864943edf8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1682,22 +1682,6 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) } -Disable_binlog::Disable_binlog(THD *thd_arg) : - thd(thd_arg), - save_options(thd_arg->options), save_master_access(thd_arg->master_access) -{ - thd_arg->options&= ~OPTION_BIN_LOG; - thd_arg->master_access|= SUPER_ACL; // unneeded in 4.1 -}; - - -Disable_binlog::~Disable_binlog() -{ - thd->options= save_options; - thd->master_access= save_master_access; -} - - /* Check if a string is a valid number diff --git a/sql/sql_class.h b/sql/sql_class.h index 30947041b7d..d362a90b7df 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -638,27 +638,6 @@ public: #define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_SQL 4 -/* - Disables binary logging for one thread, and resets it back to what it was - before being disabled. - Some functions (like the internal mysql_create_table() when it's called by - mysql_alter_table()) must NOT write to the binlog (binlogging is done at the - at a later stage of the command already, and must be, for locking reasons); - so we internally disable it temporarily by creating the Disable_binlog - object and reset the state by destroying the object (don't forget that! or - write code so that the object gets automatically destroyed when leaving a - block, see example in sql_table.cc). -*/ -class Disable_binlog { -private: - THD *thd; - ulong save_options; - ulong save_master_access; -public: - Disable_binlog(THD *thd_arg); - ~Disable_binlog(); -}; - /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 96eebd98ac3..c712167bfc1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -30,6 +30,16 @@ #include #endif +#include "sql_acl.h" // for SUPER_ACL +# define tmp_disable_binlog(A) \ + ulong save_options= (A)->options, save_master_access= (A)->master_access; \ + (A)->options&= ~OPTION_BIN_LOG; \ + (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ + +#define reenable_binlog(A) \ + (A)->options= save_options; \ + (A)->master_access= save_master_access; + extern HASH open_cache; static const char *primary_key_name="PRIMARY"; @@ -840,9 +850,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, MYSQL_LOCK **lock) { TABLE tmp_table; // Used during 'create_field()' - TABLE *table; + TABLE *table= 0; tmp_table.table_name=0; - Disable_binlog disable_binlog(thd); DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -872,23 +881,25 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, extra_fields->push_back(cr_field); } /* create and lock table */ - /* QQ: This should be done atomic ! */ - /* We don't log the statement, it will be logged later */ - if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0)) - DBUG_RETURN(0); + /* QQ: create and open should be done atomic ! */ /* + We don't log the statement, it will be logged later. If this is a HEAP table, the automatic DELETE FROM which is written to the binlog when a HEAP table is opened for the first time since startup, must not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we don't want to delete from it) 2) it would be written before the CREATE - TABLE, which is a wrong order. So we keep binary logging disabled. + TABLE, which is a wrong order. So we keep binary logging disabled when we + open_table(). */ - if (!(table=open_table(thd,db,name,name,(bool*) 0))) + tmp_disable_binlog(thd); + if (!mysql_create_table(thd,db,name,create_info,*extra_fields,*keys,0)) { - quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); - DBUG_RETURN(0); + if (!(table=open_table(thd,db,name,name,(bool*) 0))) + quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); } + reenable_binlog(thd); + if (!table) + DBUG_RETURN(0); table->reginfo.lock_type=TL_WRITE; if (!((*lock)=mysql_lock_tables(thd,&table,1))) { @@ -1925,14 +1936,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, else create_info->data_file_name=create_info->index_file_name=0; { - /* - We don't log the statement, it will be logged later. Using a block so - that disable_binlog is deleted when we leave it in either way. - */ - Disable_binlog disable_binlog(thd); - if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1))) + /* We don't log the statement, it will be logged later. */ + tmp_disable_binlog(thd); + int error= mysql_create_table(thd, new_db, tmp_name, + create_info,create_list,key_list,1); + reenable_binlog(thd); + if (error) DBUG_RETURN(error); } if (table->tmp_table) From 21642fb5d733df8c2b699eea55b0151439e0eca6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 22:48:42 +0200 Subject: [PATCH 09/17] Bug #5413 mysqlcheck segfaults when user has to few permissions --- client/mysqlcheck.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1c5638f3c52..8764611adf4 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -413,18 +413,18 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (!(mysql_query(sock, "SHOW TABLES") || - (res = mysql_store_result(sock)))) + if (mysql_query(sock, "SHOW TABLES") || + !((res= mysql_store_result(sock)))) return 1; if (opt_all_in_1) { - /* + /* We need table list in form `a`, `b`, `c` that's why we need 4 more chars added to to each table name space is for more readable output in logs and in case of error */ - + char *tables, *end; uint tot_length = 0; From 6f46f997b19537e7805dcc618dea16f1bd05ce23 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Sep 2004 23:20:33 +0200 Subject: [PATCH 10/17] Fix of previous push. sql/sql_table.cc: stupid me. error already exists in the function. Using a local 'int error' resulted in global 'error' not being inited, which probably made next steps (those testing global error) go wrong! --- sql/sql_table.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c712167bfc1..e2e186abb0d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1938,8 +1938,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* We don't log the statement, it will be logged later. */ tmp_disable_binlog(thd); - int error= mysql_create_table(thd, new_db, tmp_name, - create_info,create_list,key_list,1); + error= mysql_create_table(thd, new_db, tmp_name, + create_info,create_list,key_list,1); reenable_binlog(thd); if (error) DBUG_RETURN(error); From 2b464cae9b25da31b5152e115ac0a477f98566c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 11:40:27 +0300 Subject: [PATCH 11/17] Fixed Bug#3645, "PROCEDURE ANALYSE() recommends illegal FLOAT columns". --- sql/sql_analyse.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 3847849d6a7..0723c274a17 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -810,6 +810,13 @@ void field_real::get_opt_type(String *answer, if (min_arg >= 0) answer->append(" UNSIGNED"); } + else if (item->decimals == NOT_FIXED_DEC) + { + if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX) + answer->append("FLOAT", 5); + else + answer->append("DOUBLE", 6); + } else { if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX) From 00080aa7c3d4e1216fad3de30723c2a018200855 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 11:15:23 +0200 Subject: [PATCH 12/17] A new test for the fix for BUG#4500 ("SET CHARACTER SET replicates incorrectly"). As I cannot be 100% sure that there won't be issues with some of our exotic platforms (who knows if the charset of will play fair?), I'll send an email to the build guys. Well, this holds if bk does not crash on binary chars of this cset. --- mysql-test/r/rpl_set_charset.result | 51 +++++++++++++++++++++++++++++ mysql-test/t/rpl_set_charset.test | 40 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 mysql-test/r/rpl_set_charset.result create mode 100644 mysql-test/t/rpl_set_charset.test diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result new file mode 100644 index 00000000000..b2bfa3678a9 --- /dev/null +++ b/mysql-test/r/rpl_set_charset.result @@ -0,0 +1,51 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +drop database if exists mysqltest1; +create database mysqltest1 /*!40100 character set latin2 */; +use mysqltest1; +drop table if exists t1; +create table t1 (a varchar(255) character set latin2, b varchar(4)); +SET CHARACTER SET cp1250_latin2; +INSERT INTO t1 VALUES ('','80'); +INSERT INTO t1 VALUES ('','90'); +INSERT INTO t1 VALUES ('','A0'); +INSERT INTO t1 VALUES ('','B0'); +INSERT INTO t1 VALUES ('','C0'); +INSERT INTO t1 VALUES ('','D0'); +INSERT INTO t1 VALUES ('','E0'); +INSERT INTO t1 VALUES ('','F0'); +select "--- on master ---"; +--- on master --- +--- on master --- +select hex(a),b from t1 order by b; +hex(a) b +A9A6ABAEAC 80 +B9B6BBBEBC 90 +A3A1AAAF A0 +B3B1BAA5B5BF B0 +C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0 +D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 +E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 +show binlog events from 1979; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.001 1979 Query 1 1979 use `mysqltest1`; SET CHARACTER SET DEFAULT +use mysqltest1; +select "--- on slave ---"; +--- on slave --- +--- on slave --- +select hex(a),b from t1 order by b; +hex(a) b +A9A6ABAEAC 80 +B9B6BBBEBC 90 +A3A1AAAF A0 +B3B1BAA5B5BF B0 +C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0 +D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 +E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 +F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 +drop table t1; diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test new file mode 100644 index 00000000000..6aa864b1008 --- /dev/null +++ b/mysql-test/t/rpl_set_charset.test @@ -0,0 +1,40 @@ +source include/master-slave.inc; +--disable_warnings +drop database if exists mysqltest1; +# 4.1 bases its conversion on the db's charset, +# while 4.0 uses the part of "SET CHARACTER SET" after "_". +# So for 4.1 we add a clause to CREATE DATABASE. +create database mysqltest1 /*!40100 character set latin2 */; +use mysqltest1; +drop table if exists t1; +--enable_warnings +create table t1 (a varchar(255) character set latin2, b varchar(4)); +SET CHARACTER SET cp1250_latin2; +INSERT INTO t1 VALUES ('','80'); +INSERT INTO t1 VALUES ('','90'); +INSERT INTO t1 VALUES ('','A0'); +INSERT INTO t1 VALUES ('','B0'); +INSERT INTO t1 VALUES ('','C0'); +INSERT INTO t1 VALUES ('','D0'); +INSERT INTO t1 VALUES ('','E0'); +INSERT INTO t1 VALUES ('','F0'); +select "--- on master ---"; +select hex(a),b from t1 order by b; +# It's complicated to verify that the charset is reset to default in +# the binlog after each query, except by checking the binlog. When you +# merge this into 4.1/5.0, the 1979 will have to be changed; all you have +# to do is read the var/log/master-bin.0*01 with mysqlbinlog, verify +# that a SET CHARACTER SET DEFAULT is just after the last INSERT, and +# replace 1979 by its position (the "# at" line above the SET). +show binlog events from 1979; +save_master_pos; +connection slave; +sync_with_master; +use mysqltest1; +select "--- on slave ---"; +select hex(a),b from t1 order by b; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; From ee511e55e7598767924d73e9fe08a480e1c2c72d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 14:24:47 +0500 Subject: [PATCH 13/17] A fix (Bug #5432: Is this a leak in mysql console client?) --- client/mysql.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 1858699e8da..3cc8b41af66 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2220,7 +2220,9 @@ com_use(String *buffer __attribute__((unused)), char *line) under our feet, for example if DROP DATABASE or RENAME DATABASE (latter one not yet available by the time the comment was written) */ - current_db= 0; // Let's reset current_db, assume it's gone + /* Let's reset current_db, assume it's gone */ + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= 0; /* We don't care about in case of an error below because current_db was just set to 0. @@ -2229,10 +2231,8 @@ com_use(String *buffer __attribute__((unused)), char *line) (res= mysql_use_result(&mysql))) { row= mysql_fetch_row(res); - if (row[0] && - (!current_db || cmp_database(current_db, row[0]))) + if (row[0]) { - my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); current_db= my_strdup(row[0], MYF(MY_WME)); } (void) mysql_fetch_row(res); // Read eof From e205392de7a201c2d912116f01067b3047f91811 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 13:36:27 +0200 Subject: [PATCH 14/17] cleanup --- mysql-test/r/rpl_set_charset.result | 1 + mysql-test/t/rpl_set_charset.test | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result index b2bfa3678a9..7297d80865b 100644 --- a/mysql-test/r/rpl_set_charset.result +++ b/mysql-test/r/rpl_set_charset.result @@ -49,3 +49,4 @@ D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 drop table t1; +drop database mysqltest1; diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test index 6aa864b1008..dcfc11bf25e 100644 --- a/mysql-test/t/rpl_set_charset.test +++ b/mysql-test/t/rpl_set_charset.test @@ -38,3 +38,5 @@ drop table t1; save_master_pos; connection slave; sync_with_master; +connection master; +drop database mysqltest1; From 6b1444d7ba70a286f3fc543ab5bc8927106f5638 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 13:48:38 +0200 Subject: [PATCH 15/17] better fix for bug#5001 --- scripts/mysqld_safe.sh | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 8ad2ee1df4d..b9e7ce21f79 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -322,36 +322,26 @@ do # but should work for the rest of the servers. # The only thing is ps x => redhat 5 gives warnings when using ps -x. # kill -9 is used or the process won't react on the kill. - if test -n "$mysql_tcp_port" - then - numofproces=`ps xa | grep -v "grep" | grep $ledir/$MYSQLD| grep -c "port=$mysql_tcp_port"` - else - numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD` - fi + numofproces=`ps xa | grep -v "grep" | grep "$ledir/$MYSQLD\>" | grep -c "pid-file=$pid_file"` echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log I=1 while test "$I" -le "$numofproces" do - if test -n "$mysql_tcp_port" - then - PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "port=$mysql_tcp_port" | sed -n '$p'` - else - PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | sed -n '$p'` - fi + PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "pid-file=$pid_file" | sed -n '$p'` - for T in $PROC - do - break - done - # echo "TEST $I - $T **" - if kill -9 $T - then - echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log - else - break - fi - I=`expr $I + 1` + for T in $PROC + do + break + done + # echo "TEST $I - $T **" + if kill -9 $T + then + echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log + else + break + fi + I=`expr $I + 1` done fi echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log @@ -359,3 +349,4 @@ done echo "`date +'%y%m%d %H:%M:%S'` mysqld ended" | tee -a $err_log echo "" | tee -a $err_log + From 3a476a6e91bcd8f219393b7ec670c4833f534ea3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 14:20:48 +0200 Subject: [PATCH 16/17] clean up at end of test (thanks serg) mysql-test/r/rpl_set_charset.result: result update mysql-test/t/rpl_set_charset.test: clean up on slave too. --- mysql-test/r/rpl_set_charset.result | 1 - mysql-test/t/rpl_set_charset.test | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result index 7297d80865b..9c7ea73c741 100644 --- a/mysql-test/r/rpl_set_charset.result +++ b/mysql-test/r/rpl_set_charset.result @@ -48,5 +48,4 @@ C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0 D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0 E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0 F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0 -drop table t1; drop database mysqltest1; diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test index dcfc11bf25e..bd68ce17bbc 100644 --- a/mysql-test/t/rpl_set_charset.test +++ b/mysql-test/t/rpl_set_charset.test @@ -34,9 +34,7 @@ use mysqltest1; select "--- on slave ---"; select hex(a),b from t1 order by b; connection master; -drop table t1; +drop database mysqltest1; save_master_pos; connection slave; sync_with_master; -connection master; -drop database mysqltest1; From 32db5b4c5eb4dddf6401f3a926645a1972fa5369 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 14:57:54 +0200 Subject: [PATCH 17/17] when we update thd->db in replication, it's safer to update thd->db_length too. This does not fix any known bug, but is still a good idea. sql/log_event.cc: when we update thd->db in replication, it's safer to update thd->db_length too. sql/slave.cc: when we update thd->db in replication, it's safer to update thd->db_length too. sql/sql_db.cc: comment --- sql/log_event.cc | 14 ++++++++++---- sql/slave.cc | 13 +++++++++---- sql/sql_db.cc | 9 +++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 5526795c9d1..f707eabebd5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1806,7 +1806,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) { int expected_error, actual_error= 0; init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size,0); - thd->db= (char*) rewrite_db(db); + thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed /* InnoDB internally stores the master log position it has processed so far; @@ -1836,6 +1836,11 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) { thd->set_time((time_t)when); thd->current_tablenr = 0; + /* + We cannot use db_len from event to fill thd->db_length, because + rewrite_db() may have changed db. + */ + thd->db_length= thd->db ? strlen(thd->db) : 0; thd->query_length= q_len; thd->query= (char *) query; VOID(pthread_mutex_lock(&LOCK_thread_count)); @@ -1930,7 +1935,7 @@ end: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; // prevent db from being freed thd->query= 0; // just to be sure - thd->query_length= 0; + thd->query_length= thd->db_length =0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); close_thread_tables(thd); free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); @@ -1968,7 +1973,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, { char *load_data_query= 0; init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size, 0); - thd->db= (char*) rewrite_db(db); + thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed DBUG_ASSERT(thd->query == 0); clear_all_errors(thd, rli); @@ -2001,6 +2006,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, { thd->set_time((time_t)when); thd->current_tablenr = 0; + thd->db_length= thd->db ? strlen(thd->db) : 0; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -2117,7 +2123,7 @@ Slave: load data infile on table '%s' at log position %s in log \ VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; thd->query= 0; - thd->query_length= 0; + thd->query_length= thd->db_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); close_thread_tables(thd); if (load_data_query) diff --git a/sql/slave.cc b/sql/slave.cc index 4416a2544ef..18e0ec5929f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1124,6 +1124,7 @@ slaves can't replicate a 5.0 or newer master."; Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it from the dump. Honours replication inclusion/exclusion rules. + db must be non-zero (guarded by assertion). RETURN VALUES 0 success @@ -1134,8 +1135,8 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name, bool overwrite) { ulong packet_len = my_net_read(net); // read create table statement - char *query; - char* save_db; + char *query, *save_db; + uint32 save_db_length; Vio* save_vio; HA_CHECK_OPT check_opt; TABLE_LIST tables; @@ -1193,9 +1194,13 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, thd->proc_info = "Creating table from master dump"; // save old db in case we are creating in a different database save_db = thd->db; + save_db_length= thd->db_length; thd->db = (char*)db; + DBUG_ASSERT(thd->db); + thd->db_length= strlen(thd->db); mysql_parse(thd, thd->query, packet_len); // run create table thd->db = save_db; // leave things the way the were before + thd->db_length= save_db_length; thd->options = save_options; if (thd->query_error) @@ -2689,7 +2694,7 @@ err: IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety - thd->query_length = 0; + thd->query_length= thd->db_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { @@ -2838,7 +2843,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ err: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety - thd->query_length = 0; + thd->query_length= thd->db_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 3d877403813..c8874701aa1 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -385,6 +385,15 @@ err: } +/* + Changes the current database. + + NOTES + Do as little as possible in this function, as it is not called for the + replication slave SQL thread (for that thread, setting of thd->db is done + in ::exec_event() methods of log_event.cc). +*/ + bool mysql_change_db(THD *thd,const char *name) { int length, db_length;