Loading sql/ha_innodb.cc +3 −4 Original line number Diff line number Diff line Loading @@ -4331,9 +4331,8 @@ ha_innobase::analyze( } /************************************************************************** This is currently mapped to ::analyze. A better option would be to map this to "ALTER TABLE tablename TYPE=InnoDB", which seems to rebuild the table in MySQL. */ This is mapped to "ALTER TABLE tablename TYPE=InnoDB", which rebuilds the table in MySQL. */ int ha_innobase::optimize( Loading @@ -4341,7 +4340,7 @@ ha_innobase::optimize( THD* thd, /* in: connection thread handle */ HA_CHECK_OPT* check_opt) /* in: currently ignored */ { return(ha_innobase::analyze(thd, check_opt)); return(HA_ADMIN_TRY_ALTER); } /*********************************************************************** Loading sql/handler.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #define HA_ADMIN_INTERNAL_ERROR -4 #define HA_ADMIN_INVALID -5 #define HA_ADMIN_REJECT -6 #define HA_ADMIN_TRY_ALTER -7 /* Bits in table_flags() to show what database can do */ #define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record Loading sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -531,7 +531,8 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Key> &keys, uint order_num, ORDER *order, enum enum_duplicates handle_duplicates, ALTER_INFO *alter_info); ALTER_INFO *alter_info, bool do_send_ok=1); int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, Table_ident *src_table); Loading sql/sql_parse.cc +3 −18 Original line number Diff line number Diff line Loading @@ -2598,24 +2598,9 @@ mysql_execute_command(THD *thd) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) { /* Use ALTER TABLE */ lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); lex->alter_info.reset(); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; create_info.default_table_charset=default_charset_info; res= mysql_alter_table(thd, NullS, NullS, &create_info, tables, lex->create_list, lex->key_list, 0, (ORDER *) 0, DUP_ERROR, &lex->alter_info); } else res = mysql_optimize_table(thd, tables, &lex->check_opt); res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? mysql_recreate_table(thd, tables, 1) : mysql_optimize_table(thd, tables, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { Loading sql/sql_table.cc +63 −3 Original line number Diff line number Diff line Loading @@ -1804,6 +1804,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); send_result_message: DBUG_PRINT("info", ("result_code: %d", result_code)); switch (result_code) { case HA_ADMIN_NOT_IMPLEMENTED: { Loading Loading @@ -1847,6 +1850,28 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store("Invalid argument",16, system_charset_info); break; case HA_ADMIN_TRY_ALTER: { /* This is currently used only by InnoDB. ha_innobase::optimize() answers "try with alter", so here we close the table, do an ALTER TABLE, reopen the table and do ha_innobase::analyze() on it. */ close_thread_tables(thd); TABLE_LIST *save_next= table->next; table->next= 0; result_code= mysql_recreate_table(thd, table, 0); if (!result_code) // recreation went ok { if ((table->table= open_ltable(thd, table, lock_type)) && ((result_code= table->table->file->analyze(thd, check_opt)) > 0)) result_code= 0; // analyze went ok } result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK; table->next= save_next; goto send_result_message; } default: // Probably HA_ADMIN_INTERNAL_ERROR protocol->store("error", 5, system_charset_info); protocol->store("Unknown - internal error during operation", 41 Loading Loading @@ -2476,7 +2501,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List<create_field> &fields, List<Key> &keys, uint order_num, ORDER *order, enum enum_duplicates handle_duplicates, ALTER_INFO *alter_info) ALTER_INFO *alter_info, bool do_send_ok) { TABLE *table,*new_table; int error; Loading Loading @@ -2633,6 +2658,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); } if (do_send_ok) send_ok(thd); } else Loading Loading @@ -3196,6 +3222,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), (ulong) deleted, (ulong) thd->cuted_fields); if (do_send_ok) send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(0); Loading Loading @@ -3346,6 +3373,39 @@ copy_data_between_tables(TABLE *from,TABLE *to, } /* Recreates tables by calling mysql_alter_table(). SYNOPSIS mysql_recreate_table() thd Thread handler tables Tables to recreate do_send_ok If we should send_ok() or leave it to caller RETURN Like mysql_alter_table(). */ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok) { DBUG_ENTER("mysql_recreate_table"); LEX *lex= thd->lex; HA_CREATE_INFO create_info; lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); lex->alter_info.reset(); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; create_info.default_table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, table_list, lex->create_list, lex->key_list, 0, (ORDER *) 0, DUP_ERROR, &lex->alter_info, do_send_ok)); } int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { TABLE_LIST *table; Loading Loading
sql/ha_innodb.cc +3 −4 Original line number Diff line number Diff line Loading @@ -4331,9 +4331,8 @@ ha_innobase::analyze( } /************************************************************************** This is currently mapped to ::analyze. A better option would be to map this to "ALTER TABLE tablename TYPE=InnoDB", which seems to rebuild the table in MySQL. */ This is mapped to "ALTER TABLE tablename TYPE=InnoDB", which rebuilds the table in MySQL. */ int ha_innobase::optimize( Loading @@ -4341,7 +4340,7 @@ ha_innobase::optimize( THD* thd, /* in: connection thread handle */ HA_CHECK_OPT* check_opt) /* in: currently ignored */ { return(ha_innobase::analyze(thd, check_opt)); return(HA_ADMIN_TRY_ALTER); } /*********************************************************************** Loading
sql/handler.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #define HA_ADMIN_INTERNAL_ERROR -4 #define HA_ADMIN_INVALID -5 #define HA_ADMIN_REJECT -6 #define HA_ADMIN_TRY_ALTER -7 /* Bits in table_flags() to show what database can do */ #define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record Loading
sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -531,7 +531,8 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Key> &keys, uint order_num, ORDER *order, enum enum_duplicates handle_duplicates, ALTER_INFO *alter_info); ALTER_INFO *alter_info, bool do_send_ok=1); int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, Table_ident *src_table); Loading
sql/sql_parse.cc +3 −18 Original line number Diff line number Diff line Loading @@ -2598,24 +2598,9 @@ mysql_execute_command(THD *thd) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) { /* Use ALTER TABLE */ lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); lex->alter_info.reset(); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; create_info.default_table_charset=default_charset_info; res= mysql_alter_table(thd, NullS, NullS, &create_info, tables, lex->create_list, lex->key_list, 0, (ORDER *) 0, DUP_ERROR, &lex->alter_info); } else res = mysql_optimize_table(thd, tables, &lex->check_opt); res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? mysql_recreate_table(thd, tables, 1) : mysql_optimize_table(thd, tables, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { Loading
sql/sql_table.cc +63 −3 Original line number Diff line number Diff line Loading @@ -1804,6 +1804,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); send_result_message: DBUG_PRINT("info", ("result_code: %d", result_code)); switch (result_code) { case HA_ADMIN_NOT_IMPLEMENTED: { Loading Loading @@ -1847,6 +1850,28 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store("Invalid argument",16, system_charset_info); break; case HA_ADMIN_TRY_ALTER: { /* This is currently used only by InnoDB. ha_innobase::optimize() answers "try with alter", so here we close the table, do an ALTER TABLE, reopen the table and do ha_innobase::analyze() on it. */ close_thread_tables(thd); TABLE_LIST *save_next= table->next; table->next= 0; result_code= mysql_recreate_table(thd, table, 0); if (!result_code) // recreation went ok { if ((table->table= open_ltable(thd, table, lock_type)) && ((result_code= table->table->file->analyze(thd, check_opt)) > 0)) result_code= 0; // analyze went ok } result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK; table->next= save_next; goto send_result_message; } default: // Probably HA_ADMIN_INTERNAL_ERROR protocol->store("error", 5, system_charset_info); protocol->store("Unknown - internal error during operation", 41 Loading Loading @@ -2476,7 +2501,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List<create_field> &fields, List<Key> &keys, uint order_num, ORDER *order, enum enum_duplicates handle_duplicates, ALTER_INFO *alter_info) ALTER_INFO *alter_info, bool do_send_ok) { TABLE *table,*new_table; int error; Loading Loading @@ -2633,6 +2658,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); } if (do_send_ok) send_ok(thd); } else Loading Loading @@ -3196,6 +3222,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), (ulong) deleted, (ulong) thd->cuted_fields); if (do_send_ok) send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(0); Loading Loading @@ -3346,6 +3373,39 @@ copy_data_between_tables(TABLE *from,TABLE *to, } /* Recreates tables by calling mysql_alter_table(). SYNOPSIS mysql_recreate_table() thd Thread handler tables Tables to recreate do_send_ok If we should send_ok() or leave it to caller RETURN Like mysql_alter_table(). */ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok) { DBUG_ENTER("mysql_recreate_table"); LEX *lex= thd->lex; HA_CREATE_INFO create_info; lex->create_list.empty(); lex->key_list.empty(); lex->col_list.empty(); lex->alter_info.reset(); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; create_info.default_table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, table_list, lex->create_list, lex->key_list, 0, (ORDER *) 0, DUP_ERROR, &lex->alter_info, do_send_ok)); } int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { TABLE_LIST *table; Loading