diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index caec049c244..55c3b766d80 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -48,6 +48,9 @@ "FUNCTION" : "PROCEDURE") static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); +static bool execute_show_status(THD *thd, TABLE_LIST *all_tables); +static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, + TABLE_LIST *all_tables); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); const char *any_db="*any*"; // Special symbol for check_access @@ -1125,7 +1128,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Cast *passwd to an unsigned char, so that it doesn't extend the sign for *passwd > 127 and become 2**32-127 after casting to uint. */ - char db_buff[SAFE_NAME_LEN*2+1]; // buffer to store db in utf8 + char db_buff[SAFE_NAME_LEN+1]; // buffer to store db in utf8 char *db= passwd; char *save_db; /* @@ -1556,7 +1559,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_STATISTICS: { - STATUS_VAR current_global_status_var; + STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack ulong uptime; #if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY) uint length; @@ -1565,9 +1568,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char buff[250]; uint buff_len= sizeof(buff); + if (!(current_global_status_var= (STATUS_VAR*) + thd->alloc(sizeof(STATUS_VAR)))) + break; general_log_print(thd, command, NullS); status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]); - calc_sum_of_all_status(¤t_global_status_var); + calc_sum_of_all_status(current_global_status_var); if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; else @@ -1582,8 +1588,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, "Open tables: %u Queries per second avg: %u.%u", uptime, (int) thread_count, (ulong) thd->query_id, - current_global_status_var.long_query_count, - current_global_status_var.opened_tables, + current_global_status_var->long_query_count, + current_global_status_var->opened_tables, refresh_version, cached_open_tables(), (uint) (queries_per_second1000 / 1000), @@ -2285,22 +2291,7 @@ mysql_execute_command(THD *thd) break; case SQLCOM_SHOW_STATUS: { - system_status_var old_status_var= thd->status_var; - thd->initial_status_var= &old_status_var; - if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))) - res= execute_sqlcom_select(thd, all_tables); - /* Don't log SHOW STATUS commands to slow query log */ - thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | - SERVER_QUERY_NO_GOOD_INDEX_USED); - /* - restore status variables, as we don't want 'show status' to cause - changes - */ - pthread_mutex_lock(&LOCK_status); - add_diff_to_status(&global_status_var, &thd->status_var, - &old_status_var); - thd->status_var= old_status_var; - pthread_mutex_unlock(&LOCK_status); + execute_show_status(thd, all_tables); break; } case SQLCOM_SHOW_DATABASES: @@ -3005,31 +2996,7 @@ end_with_restore_list: } case SQLCOM_RENAME_TABLE: { - DBUG_ASSERT(first_table == all_tables && first_table != 0); - TABLE_LIST *table; - for (table= first_table; table; table= table->next_local->next_local) - { - if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, - &table->grant.privilege,0,0, test(table->schema_table)) || - check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, - &table->next_local->grant.privilege, 0, 0, - test(table->next_local->schema_table))) - goto error; - TABLE_LIST old_list, new_list; - /* - we do not need initialize old_list and new_list because we will - come table[0] and table->next[0] there - */ - old_list= table[0]; - new_list= table->next_local[0]; - if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || - (!test_all_bits(table->next_local->grant.privilege, - INSERT_ACL | CREATE_ACL) && - check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) - goto error; - } - - if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) + if (execute_rename_table(thd, first_table, all_tables)) goto error; break; } @@ -5172,6 +5139,62 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) } +static bool execute_show_status(THD *thd, TABLE_LIST *all_tables) +{ + bool res; + system_status_var old_status_var= thd->status_var; + thd->initial_status_var= &old_status_var; + if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))) + res= execute_sqlcom_select(thd, all_tables); + /* Don't log SHOW STATUS commands to slow query log */ + thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | + SERVER_QUERY_NO_GOOD_INDEX_USED); + /* + restore status variables, as we don't want 'show status' to cause + changes + */ + pthread_mutex_lock(&LOCK_status); + add_diff_to_status(&global_status_var, &thd->status_var, + &old_status_var); + thd->status_var= old_status_var; + pthread_mutex_unlock(&LOCK_status); + return res; +} + + +static bool execute_rename_table(THD *thd, TABLE_LIST *first_table, + TABLE_LIST *all_tables) +{ + DBUG_ASSERT(first_table == all_tables && first_table != 0); + TABLE_LIST *table; + for (table= first_table; table; table= table->next_local->next_local) + { + if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, + &table->grant.privilege,0,0, test(table->schema_table)) || + check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, + &table->next_local->grant.privilege, 0, 0, + test(table->next_local->schema_table))) + return 1; + TABLE_LIST old_list, new_list; + /* + we do not need initialize old_list and new_list because we will + come table[0] and table->next[0] there + */ + old_list= table[0]; + new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || + (!test_all_bits(table->next_local->grant.privilege, + INSERT_ACL | CREATE_ACL) && + check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) + return 1; + } + + if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) + return 1; + return 0; +} + + #ifndef NO_EMBEDDED_ACCESS_CHECKS /** Check grants for commands which work only with one table. diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 0a14891c591..7447736c48a 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1043,14 +1043,14 @@ int ha_maria::write_row(uchar * buf) int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) { - if (!file) - return HA_ADMIN_INTERNAL_ERROR; int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MARIA_SHARE *share= file->s; const char *old_proc_info= thd_proc_info(thd, "Checking table"); TRN *old_trn= file->trn; + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "check"; @@ -1144,9 +1144,12 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt) { int error= 0; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MARIA_SHARE *share= file->s; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "analyze"; @@ -1281,7 +1284,10 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "backup"; @@ -1297,10 +1303,10 @@ err: int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); ha_rows start_records; - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; maria_chk_init(¶m); @@ -1352,11 +1358,11 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); TRN *old_trn; MARIA_SHARE *share= file->s; - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; old_trn= file->trn; @@ -1382,9 +1388,9 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); - if (!file) + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; maria_chk_init(¶m); @@ -1623,7 +1629,10 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt) if (error != HA_ADMIN_OK) { /* Send error to user */ - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "assign_to_keycache"; @@ -1684,7 +1693,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt) errmsg= buf; } - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + maria_chk_init(¶m); param.thd= thd; param.op_name= "preload_keys"; @@ -1792,8 +1804,12 @@ int ha_maria::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd= current_thd; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + const char *save_proc_info= thd_proc_info(thd, "Creating index"); + maria_chk_init(¶m); param.op_name= "recreating_index"; param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK | diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 3e49088c368..f0702d95554 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -4409,8 +4409,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, goto err; } } - share->state.state.data_file_length= share->state.state.data_file_length= - sort_param->filepos; + share->state.state.data_file_length= sort_param->filepos; /* Only whole records */ share->state.version= (ulong) time((time_t*) 0); /* diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5f807be2374..ae4c9131c42 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -799,10 +799,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { if (!file) return HA_ADMIN_INTERNAL_ERROR; int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; const char *old_proc_info=thd->proc_info; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Checking table"); myisamchk_init(¶m); param.thd = thd; @@ -891,9 +894,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) { int error=0; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); MYISAM_SHARE* share = file->s; + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd = thd; param.op_name= "analyze"; @@ -1021,7 +1027,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd= thd; param.op_name= "backup"; @@ -1037,10 +1045,10 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { int error; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); ha_rows start_records; - if (!file) return HA_ADMIN_INTERNAL_ERROR; + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -1088,8 +1096,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) { int error; - if (!file) return HA_ADMIN_INTERNAL_ERROR; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + + if (!file || !¶m) return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd = thd; @@ -1283,7 +1292,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) if (error != HA_ADMIN_OK) { /* Send error to user */ - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + myisamchk_init(¶m); param.thd= thd; param.op_name= "assign_to_keycache"; @@ -1347,7 +1359,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) err: { - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; myisamchk_init(¶m); param.thd= thd; param.op_name= "preload_keys"; @@ -1457,8 +1471,12 @@ int ha_myisam::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd=current_thd; - HA_CHECK param; + HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); const char *save_proc_info=thd->proc_info; + + if (!¶m) + return HA_ADMIN_INTERNAL_ERROR; + thd_proc_info(thd, "Creating index"); myisamchk_init(¶m); param.op_name= "recreating_index";