Loading sql/ChangeLog +4 −0 Original line number Diff line number Diff line 2000-08-21 Michael Widenius <monty@mysql.com> * Added RENAME TABLE. 2000-08-20 Michael Widenius <monty@mysql.com> * Added memory as inline functions to THD to get them a bit faster Loading sql/mysql_priv.h +12 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); int quick_rm_table(enum db_type base,const char *db, const char *table_name); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_change_db(THD *thd,const char *name); void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_init_select(LEX *lex); Loading Loading @@ -293,6 +294,11 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Alter_column> &alter_list, bool drop_primary, enum enum_duplicates handle_duplicates); bool mysql_rename_table(enum db_type base, const char *old_db, const char * old_name, const char *new_db, const char * new_name); bool close_cached_table(THD *thd,TABLE *table); int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); int mysql_drop_index(THD *thd, TABLE_LIST *table_list, Loading @@ -316,6 +322,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh); void close_old_data_files(THD *thd, TABLE *table, bool abort_locks); bool close_data_tables(THD *thd,const char *db, const char *table_name); bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table); bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables); Loading Loading @@ -488,6 +495,11 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); /* Lock based on name */ int lock_table_name(THD *thd, TABLE_LIST *table_list); void unlock_table_name(THD *thd, TABLE_LIST *table_list); bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list); extern int flush_master_info(MASTER_INFO* mi); /* old unireg functions */ Loading sql/sql_parse.cc +60 −59 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ extern "C" int gethostname(char *name, int namelen); #endif static bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables); static bool check_lock_tables(THD *thd,TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_dup(THD *thd,const char *db,const char *name, TABLE_LIST *tables); static void mysql_init_query(THD *thd); Loading Loading @@ -387,7 +387,6 @@ pthread_handler_decl(handle_one_connection,arg) goto end_thread; } thd->alloc.free=thd->alloc.used=0; if (thd->max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) Loading @@ -395,7 +394,7 @@ pthread_handler_decl(handle_one_connection,arg) if (thd->options & OPTION_ANSI_MODE) thd->client_capabilities|=CLIENT_IGNORE_SPACE; thd->proc_info=0; thd->proc_info=0; // Remove 'login' thd->version=refresh_version; thd->set_time(); while (!net->error && net->vio != 0 && !thd->killed) Loading Loading @@ -436,7 +435,7 @@ int handle_bootstrap(THD *thd,FILE *file) if (init_thr_lock() || my_pthread_setspecific_ptr(THR_THD, thd) || my_pthread_setspecific_ptr(THR_MALLOC, &thd->alloc) || my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root) || my_pthread_setspecific_ptr(THR_NET, &thd->net)) { close_connection(&thd->net,ER_OUT_OF_RESOURCES); Loading @@ -450,7 +449,6 @@ int handle_bootstrap(THD *thd,FILE *file) VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); #endif thd->alloc.free=thd->alloc.used=0; if (thd->max_join_size == (ulong) ~0L) thd->options |= OPTION_BIG_SELECTS; Loading @@ -464,9 +462,9 @@ int handle_bootstrap(THD *thd,FILE *file) while (length && (isspace(buff[length-1]) || buff[length-1] == ';')) length--; buff[length]=0; init_sql_alloc(&thd->alloc,8192); init_sql_alloc(&thd->mem_root,8192); thd->current_tablenr=0; thd->query= sql_memdup(buff,length+1); thd->query= thd->memdup(buff,length+1); thd->query_id=query_id++; mysql_parse(thd,thd->query,length); close_thread_tables(thd); // Free tables Loading @@ -474,7 +472,7 @@ int handle_bootstrap(THD *thd,FILE *file) { DBUG_RETURN(-1); } free_root(&thd->alloc); free_root(&thd->mem_root); } DBUG_RETURN(0); } Loading Loading @@ -542,7 +540,7 @@ bool do_command(THD *thd) enum enum_server_command command; DBUG_ENTER("do_command"); init_sql_alloc(&thd->alloc,8192); init_sql_alloc(&thd->mem_root,8192); net= &thd->net; thd->current_tablenr=0; Loading Loading @@ -642,7 +640,7 @@ bool do_command(THD *thd) packet_length--; } *pos=0; if (!(thd->query= (char*) sql_memdup((gptr) (packet+1),packet_length))) if (!(thd->query= (char*) thd->memdup((gptr) (packet+1),packet_length))) break; thd->packet.shrink(net_buffer_length); // Reclaim some memory if (!(specialflag & SPECIAL_NO_PRIOR)) Loading Loading @@ -670,8 +668,8 @@ bool do_command(THD *thd) break; } thd->free_list=0; table_list.name=table_list.real_name=sql_strdup(packet+1); thd->query=fields=sql_strdup(strend(packet+1)+1); table_list.name=table_list.real_name=thd->strdup(packet+1); thd->query=fields=thd->strdup(strend(packet+1)+1); mysql_log.write(command,"%s %s",table_list.real_name,fields); remove_escape(table_list.real_name); // This can't have wildcards Loading @@ -693,7 +691,7 @@ bool do_command(THD *thd) case COM_CREATE_DB: { char *db=sql_strdup(packet+1); char *db=thd->strdup(packet+1); if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(command,packet+1); Loading @@ -702,7 +700,7 @@ bool do_command(THD *thd) } case COM_DROP_DB: { char *db=sql_strdup(packet+1); char *db=thd->strdup(packet+1); if (check_access(thd,DROP_ACL,db,0,1)) break; mysql_log.write(command,db); Loading @@ -719,7 +717,7 @@ bool do_command(THD *thd) ushort flags; pos = uint4korr(packet + 1); flags = uint2korr(packet + 5); mysql_binlog_send(thd, sql_strdup(packet + 7), pos, flags); mysql_binlog_send(thd, thd->strdup(packet + 7), pos, flags); break; } case COM_REFRESH: Loading @@ -746,7 +744,7 @@ bool do_command(THD *thd) send_eof(net); // This is for 'quit request' close_connection(net); close_thread_tables(thd); // Free before kill free_root(&thd->alloc); free_root(&thd->mem_root); kill_mysql(); error=TRUE; break; Loading Loading @@ -827,7 +825,7 @@ bool do_command(THD *thd) thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(net_buffer_length); // Reclaim some memory free_root(&thd->alloc); free_root(&thd->mem_root); DBUG_RETURN(error); } Loading Loading @@ -1132,51 +1130,49 @@ mysql_execute_command(void) break; } #endif case SQLCOM_RENAME_TABLE: if (check_db_used(thd,tables) || check_table_access(thd,ALTER_ACL,tables)) goto error; if (mysql_rename_tables(thd,tables)) res= -1; break; case SQLCOM_SHOW_CREATE: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { if(! tables->db) tables->db = thd->db; if (!tables->db) { send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } if (check_db_used(thd, tables) || check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db, &tables->grant.privilege)) goto error; res = mysqld_show_create(thd, tables); break; } #endif case SQLCOM_REPAIR: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL | INSERT_ACL,tables->db, &tables->grant.privilege)) if (check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL,tables)) goto error; res = mysql_repair_table(thd, tables, &lex->check_opt); break; } case SQLCOM_CHECK: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL,tables->db, &tables->grant.privilege)) if (check_db_used(thd,tables) || check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL,tables)) goto error; res = mysql_check_table(thd, tables, &lex->check_opt); break; } case SQLCOM_ANALYZE: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL|INSERT_ACL,tables->db, &tables->grant.privilege)) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL|INSERT_ACL,tables)) goto error; res = mysql_analyze_table(thd, tables); break; } Loading Loading @@ -1515,7 +1511,7 @@ mysql_execute_command(void) thd->locked_tables=0; // Will be automaticly closed close_thread_tables(thd); } if (check_lock_tables(thd,tables)) if (check_db_used(thd,tables)) goto error; thd->in_lock_tables=1; if (!(res=open_and_lock_tables(thd,tables))) Loading Loading @@ -1749,7 +1745,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) { if ((thd->master_access & want_access) == want_access && thd->db) tables->grant.privilege= want_access; else if (tables->db) else if (tables->db && tables->db == thd->db) { if (found && !grant_option) // db already checked tables->grant.privilege=found_access; Loading @@ -1758,6 +1754,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) return TRUE; // Access denied found_access=tables->grant.privilege; found=1; } } else if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) Loading @@ -1769,7 +1766,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) } static bool check_lock_tables(THD *thd,TABLE_LIST *tables) static bool check_db_used(THD *thd,TABLE_LIST *tables) { for (; tables ; tables=tables->next) { Loading Loading @@ -2274,21 +2271,24 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, if (lower_case_table_names) casedn_str(table->table.str); #endif if (!(ptr = (TABLE_LIST *) sql_calloc(sizeof(TABLE_LIST)))) if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(0); /* purecov: inspected */ ptr->db= table->db.str; ptr->real_name=table->table.str; ptr->name=alias_str; ptr->lock_type=flags; if (use_index) ptr->use_index=(List<String> *) sql_memdup((gptr) use_index, ptr->use_index=(List<String> *) thd->memdup((gptr) use_index, sizeof(*use_index)); if (ignore_index) ptr->ignore_index=(List<String> *) sql_memdup((gptr) ignore_index, ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index, sizeof(*ignore_index)); /* check that used name is unique */ current_db=thd->db ? thd->db : ""; if (flags != TL_IGNORE) { for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.table_list.first ; tables ; tables=tables->next) { Loading @@ -2300,6 +2300,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, DBUG_RETURN(0); /* purecov: tested */ } } } link_in_list(&thd->lex.table_list,(byte*) ptr,(byte**) &ptr->next); DBUG_RETURN(ptr); } Loading sql/sql_rename.cc 0 → 100644 +132 −0 Original line number Diff line number Diff line /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...] */ #include "mysql_priv.h" static TABLE_LIST *mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); /* Every second entry in the table_list is the original name and every second entry is the new name. */ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) { bool error=1,got_all_locks=1; db_type table_type; TABLE_LIST *lock_table,*ren_table=0,*new_table; DBUG_ENTER("mysql_rename_tables"); /* Avoid problems with a rename on a table that we have locked or if the user is trying to to do this in a transcation context */ if (thd->locked_tables || thd->active_transaction()) { my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); DBUG_RETURN(1); } VOID(pthread_mutex_lock(&LOCK_open)); for (lock_table=table_list ; lock_table ; lock_table=lock_table->next) { int got_lock; if ((got_lock=lock_table_name(thd,lock_table)) < 0) goto end; if (got_lock) got_all_locks=0; } if (!got_all_locks && wait_for_locked_table_names(thd,table_list)) goto end; if (!(ren_table=mysql_rename_tables(thd,table_list,0))) error=0; end: if (ren_table) { /* Rename didn't succeed; rename back the tables in reverse order */ TABLE_LIST *prev=0,*table; /* Reverse the table list ; Note that we need to handle the case that every second entry must stay in place in respect to the previous */ while (table_list) { TABLE_LIST *next=table_list->next->next; table_list->next->next=prev; prev=table_list; table_list=next; } table_list=prev; /* Find the last renamed table */ for (table=table_list ; table->next != ren_table ; table=table->next->next) ; table=table->next->next; // Skipp error table /* Revert to old names */ mysql_rename_tables(thd, table, 1); /* Note that lock_table == 0 here, so the unlock loop will work */ } if (!error) { mysql_update_log.write(thd->query,thd->query_length); Query_log_event qinfo(thd, thd->query); mysql_bin_log.write(&qinfo); } for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next) unlock_table_name(thd,table); pthread_cond_broadcast(&COND_refresh); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(error); } /* Rename all tables in list; Return pointer to wrong entry if something goes wrong. */ static TABLE_LIST * mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { TABLE_LIST *ren_table; for (ren_table=table_list ; ren_table ; ren_table=ren_table->next) { db_type table_type; char name[FN_REFLEN]; TABLE_LIST *new_table=ren_table->next; sprintf(name,"%s/%s/%s%s",mysql_data_home, ren_table->db,ren_table->name, reg_ext); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN || mysql_rename_table(table_type, ren_table->db, ren_table->name, new_table->db, new_table->name)) { if (!skip_error) return ren_table; } } return 0; } Loading
sql/ChangeLog +4 −0 Original line number Diff line number Diff line 2000-08-21 Michael Widenius <monty@mysql.com> * Added RENAME TABLE. 2000-08-20 Michael Widenius <monty@mysql.com> * Added memory as inline functions to THD to get them a bit faster Loading
sql/mysql_priv.h +12 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); int quick_rm_table(enum db_type base,const char *db, const char *table_name); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_change_db(THD *thd,const char *name); void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_init_select(LEX *lex); Loading Loading @@ -293,6 +294,11 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Alter_column> &alter_list, bool drop_primary, enum enum_duplicates handle_duplicates); bool mysql_rename_table(enum db_type base, const char *old_db, const char * old_name, const char *new_db, const char * new_name); bool close_cached_table(THD *thd,TABLE *table); int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); int mysql_drop_index(THD *thd, TABLE_LIST *table_list, Loading @@ -316,6 +322,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh); void close_old_data_files(THD *thd, TABLE *table, bool abort_locks); bool close_data_tables(THD *thd,const char *db, const char *table_name); bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table); bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables); Loading Loading @@ -488,6 +495,11 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); /* Lock based on name */ int lock_table_name(THD *thd, TABLE_LIST *table_list); void unlock_table_name(THD *thd, TABLE_LIST *table_list); bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list); extern int flush_master_info(MASTER_INFO* mi); /* old unireg functions */ Loading
sql/sql_parse.cc +60 −59 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ extern "C" int gethostname(char *name, int namelen); #endif static bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables); static bool check_lock_tables(THD *thd,TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_dup(THD *thd,const char *db,const char *name, TABLE_LIST *tables); static void mysql_init_query(THD *thd); Loading Loading @@ -387,7 +387,6 @@ pthread_handler_decl(handle_one_connection,arg) goto end_thread; } thd->alloc.free=thd->alloc.used=0; if (thd->max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) Loading @@ -395,7 +394,7 @@ pthread_handler_decl(handle_one_connection,arg) if (thd->options & OPTION_ANSI_MODE) thd->client_capabilities|=CLIENT_IGNORE_SPACE; thd->proc_info=0; thd->proc_info=0; // Remove 'login' thd->version=refresh_version; thd->set_time(); while (!net->error && net->vio != 0 && !thd->killed) Loading Loading @@ -436,7 +435,7 @@ int handle_bootstrap(THD *thd,FILE *file) if (init_thr_lock() || my_pthread_setspecific_ptr(THR_THD, thd) || my_pthread_setspecific_ptr(THR_MALLOC, &thd->alloc) || my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root) || my_pthread_setspecific_ptr(THR_NET, &thd->net)) { close_connection(&thd->net,ER_OUT_OF_RESOURCES); Loading @@ -450,7 +449,6 @@ int handle_bootstrap(THD *thd,FILE *file) VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); #endif thd->alloc.free=thd->alloc.used=0; if (thd->max_join_size == (ulong) ~0L) thd->options |= OPTION_BIG_SELECTS; Loading @@ -464,9 +462,9 @@ int handle_bootstrap(THD *thd,FILE *file) while (length && (isspace(buff[length-1]) || buff[length-1] == ';')) length--; buff[length]=0; init_sql_alloc(&thd->alloc,8192); init_sql_alloc(&thd->mem_root,8192); thd->current_tablenr=0; thd->query= sql_memdup(buff,length+1); thd->query= thd->memdup(buff,length+1); thd->query_id=query_id++; mysql_parse(thd,thd->query,length); close_thread_tables(thd); // Free tables Loading @@ -474,7 +472,7 @@ int handle_bootstrap(THD *thd,FILE *file) { DBUG_RETURN(-1); } free_root(&thd->alloc); free_root(&thd->mem_root); } DBUG_RETURN(0); } Loading Loading @@ -542,7 +540,7 @@ bool do_command(THD *thd) enum enum_server_command command; DBUG_ENTER("do_command"); init_sql_alloc(&thd->alloc,8192); init_sql_alloc(&thd->mem_root,8192); net= &thd->net; thd->current_tablenr=0; Loading Loading @@ -642,7 +640,7 @@ bool do_command(THD *thd) packet_length--; } *pos=0; if (!(thd->query= (char*) sql_memdup((gptr) (packet+1),packet_length))) if (!(thd->query= (char*) thd->memdup((gptr) (packet+1),packet_length))) break; thd->packet.shrink(net_buffer_length); // Reclaim some memory if (!(specialflag & SPECIAL_NO_PRIOR)) Loading Loading @@ -670,8 +668,8 @@ bool do_command(THD *thd) break; } thd->free_list=0; table_list.name=table_list.real_name=sql_strdup(packet+1); thd->query=fields=sql_strdup(strend(packet+1)+1); table_list.name=table_list.real_name=thd->strdup(packet+1); thd->query=fields=thd->strdup(strend(packet+1)+1); mysql_log.write(command,"%s %s",table_list.real_name,fields); remove_escape(table_list.real_name); // This can't have wildcards Loading @@ -693,7 +691,7 @@ bool do_command(THD *thd) case COM_CREATE_DB: { char *db=sql_strdup(packet+1); char *db=thd->strdup(packet+1); if (check_access(thd,CREATE_ACL,db,0,1)) break; mysql_log.write(command,packet+1); Loading @@ -702,7 +700,7 @@ bool do_command(THD *thd) } case COM_DROP_DB: { char *db=sql_strdup(packet+1); char *db=thd->strdup(packet+1); if (check_access(thd,DROP_ACL,db,0,1)) break; mysql_log.write(command,db); Loading @@ -719,7 +717,7 @@ bool do_command(THD *thd) ushort flags; pos = uint4korr(packet + 1); flags = uint2korr(packet + 5); mysql_binlog_send(thd, sql_strdup(packet + 7), pos, flags); mysql_binlog_send(thd, thd->strdup(packet + 7), pos, flags); break; } case COM_REFRESH: Loading @@ -746,7 +744,7 @@ bool do_command(THD *thd) send_eof(net); // This is for 'quit request' close_connection(net); close_thread_tables(thd); // Free before kill free_root(&thd->alloc); free_root(&thd->mem_root); kill_mysql(); error=TRUE; break; Loading Loading @@ -827,7 +825,7 @@ bool do_command(THD *thd) thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(net_buffer_length); // Reclaim some memory free_root(&thd->alloc); free_root(&thd->mem_root); DBUG_RETURN(error); } Loading Loading @@ -1132,51 +1130,49 @@ mysql_execute_command(void) break; } #endif case SQLCOM_RENAME_TABLE: if (check_db_used(thd,tables) || check_table_access(thd,ALTER_ACL,tables)) goto error; if (mysql_rename_tables(thd,tables)) res= -1; break; case SQLCOM_SHOW_CREATE: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ DBUG_VOID_RETURN; #else { if(! tables->db) tables->db = thd->db; if (!tables->db) { send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } if (check_db_used(thd, tables) || check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db, &tables->grant.privilege)) goto error; res = mysqld_show_create(thd, tables); break; } #endif case SQLCOM_REPAIR: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL | INSERT_ACL,tables->db, &tables->grant.privilege)) if (check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL,tables)) goto error; res = mysql_repair_table(thd, tables, &lex->check_opt); break; } case SQLCOM_CHECK: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL,tables->db, &tables->grant.privilege)) if (check_db_used(thd,tables) || check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL,tables)) goto error; res = mysql_check_table(thd, tables, &lex->check_opt); break; } case SQLCOM_ANALYZE: { if (!tables->db) tables->db=thd->db; if (check_access(thd,SELECT_ACL|INSERT_ACL,tables->db, &tables->grant.privilege)) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ if (grant_option && check_grant(thd,SELECT_ACL|INSERT_ACL,tables)) goto error; res = mysql_analyze_table(thd, tables); break; } Loading Loading @@ -1515,7 +1511,7 @@ mysql_execute_command(void) thd->locked_tables=0; // Will be automaticly closed close_thread_tables(thd); } if (check_lock_tables(thd,tables)) if (check_db_used(thd,tables)) goto error; thd->in_lock_tables=1; if (!(res=open_and_lock_tables(thd,tables))) Loading Loading @@ -1749,7 +1745,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) { if ((thd->master_access & want_access) == want_access && thd->db) tables->grant.privilege= want_access; else if (tables->db) else if (tables->db && tables->db == thd->db) { if (found && !grant_option) // db already checked tables->grant.privilege=found_access; Loading @@ -1758,6 +1754,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) return TRUE; // Access denied found_access=tables->grant.privilege; found=1; } } else if (check_access(thd,want_access,tables->db,&tables->grant.privilege)) Loading @@ -1769,7 +1766,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) } static bool check_lock_tables(THD *thd,TABLE_LIST *tables) static bool check_db_used(THD *thd,TABLE_LIST *tables) { for (; tables ; tables=tables->next) { Loading Loading @@ -2274,21 +2271,24 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, if (lower_case_table_names) casedn_str(table->table.str); #endif if (!(ptr = (TABLE_LIST *) sql_calloc(sizeof(TABLE_LIST)))) if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(0); /* purecov: inspected */ ptr->db= table->db.str; ptr->real_name=table->table.str; ptr->name=alias_str; ptr->lock_type=flags; if (use_index) ptr->use_index=(List<String> *) sql_memdup((gptr) use_index, ptr->use_index=(List<String> *) thd->memdup((gptr) use_index, sizeof(*use_index)); if (ignore_index) ptr->ignore_index=(List<String> *) sql_memdup((gptr) ignore_index, ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index, sizeof(*ignore_index)); /* check that used name is unique */ current_db=thd->db ? thd->db : ""; if (flags != TL_IGNORE) { for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.table_list.first ; tables ; tables=tables->next) { Loading @@ -2300,6 +2300,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, DBUG_RETURN(0); /* purecov: tested */ } } } link_in_list(&thd->lex.table_list,(byte*) ptr,(byte**) &ptr->next); DBUG_RETURN(ptr); } Loading
sql/sql_rename.cc 0 → 100644 +132 −0 Original line number Diff line number Diff line /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...] */ #include "mysql_priv.h" static TABLE_LIST *mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); /* Every second entry in the table_list is the original name and every second entry is the new name. */ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) { bool error=1,got_all_locks=1; db_type table_type; TABLE_LIST *lock_table,*ren_table=0,*new_table; DBUG_ENTER("mysql_rename_tables"); /* Avoid problems with a rename on a table that we have locked or if the user is trying to to do this in a transcation context */ if (thd->locked_tables || thd->active_transaction()) { my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); DBUG_RETURN(1); } VOID(pthread_mutex_lock(&LOCK_open)); for (lock_table=table_list ; lock_table ; lock_table=lock_table->next) { int got_lock; if ((got_lock=lock_table_name(thd,lock_table)) < 0) goto end; if (got_lock) got_all_locks=0; } if (!got_all_locks && wait_for_locked_table_names(thd,table_list)) goto end; if (!(ren_table=mysql_rename_tables(thd,table_list,0))) error=0; end: if (ren_table) { /* Rename didn't succeed; rename back the tables in reverse order */ TABLE_LIST *prev=0,*table; /* Reverse the table list ; Note that we need to handle the case that every second entry must stay in place in respect to the previous */ while (table_list) { TABLE_LIST *next=table_list->next->next; table_list->next->next=prev; prev=table_list; table_list=next; } table_list=prev; /* Find the last renamed table */ for (table=table_list ; table->next != ren_table ; table=table->next->next) ; table=table->next->next; // Skipp error table /* Revert to old names */ mysql_rename_tables(thd, table, 1); /* Note that lock_table == 0 here, so the unlock loop will work */ } if (!error) { mysql_update_log.write(thd->query,thd->query_length); Query_log_event qinfo(thd, thd->query); mysql_bin_log.write(&qinfo); } for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next) unlock_table_name(thd,table); pthread_cond_broadcast(&COND_refresh); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(error); } /* Rename all tables in list; Return pointer to wrong entry if something goes wrong. */ static TABLE_LIST * mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { TABLE_LIST *ren_table; for (ren_table=table_list ; ren_table ; ren_table=ren_table->next) { db_type table_type; char name[FN_REFLEN]; TABLE_LIST *new_table=ren_table->next; sprintf(name,"%s/%s/%s%s",mysql_data_home, ren_table->db,ren_table->name, reg_ext); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN || mysql_rename_table(table_type, ren_table->db, ren_table->name, new_table->db, new_table->name)) { if (!skip_error) return ren_table; } } return 0; }