summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMattias Jonsson <mattiasj@mysql.com>2008-08-11 20:02:03 +0200
committerMattias Jonsson <mattiasj@mysql.com>2008-08-11 20:02:03 +0200
commit07e9a6dc2a4a6839c874204e660d4981a33bad85 (patch)
treec00c7e35f215af74686a611f330d4e857c28faad /sql
parent44a162597f8107974da7a0ebe33eaf9089fe1a2e (diff)
downloadmariadb-git-07e9a6dc2a4a6839c874204e660d4981a33bad85.tar.gz
Bug#20129: ALTER TABLE ... REPAIR PARTITION ... complains that
partition is corrupt The main problem was that ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION took another code path (over mysql_alter_table instead of mysql_admin_table) which differs in two ways: 1) alter table opens the tables in a different way than admin tables do resulting in returning with error before it tried the command 2) alter table does not start to send any diagnostic rows to the client which the lower admin functions continue to use -> resulting in assertion crash The fix: Remapped ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION to use the same code path as ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE t. Adding check in mysql_admin_table to setup the partition list for which partitions that should be used. Partitioned tables will still not work with REPAIR TABLE/PARTITION USE_FRM, since that requires moving partitions to tables, REPAIR TABLE t USE_FRM, and check that the data still fulfills the partitioning function and then move the table back to being a partition. NOTE: I have removed the following functions from the handler interface: analyze_partitions, check_partitions, optimize_partitions, repair_partitions Since they are not longer needed. THIS ALTERS THE STORAGE ENGINE API
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc233
-rw-r--r--sql/ha_partition.h4
-rw-r--r--sql/handler.cc60
-rw-r--r--sql/handler.h12
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/protocol.cc3
-rw-r--r--sql/sql_partition.cc96
-rw-r--r--sql/sql_table.cc55
-rw-r--r--sql/sql_yacc.yy8
9 files changed, 221 insertions, 252 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b06e2572f44..287f360fec6 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -841,6 +841,9 @@ int ha_partition::rename_partitions(const char *path)
#define CHECK_PARTS 3
#define REPAIR_PARTS 4
+static const char *opt_op_name[]= {NULL,
+ "optimize", "analyze", "check", "repair" };
+
/*
Optimize table
@@ -858,8 +861,10 @@ int ha_partition::optimize(THD *thd, HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("ha_partition::optimize");
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- OPTIMIZE_PARTS, TRUE));
+ DBUG_RETURN(handle_opt_partitions(thd, check_opt,
+ OPTIMIZE_PARTS,
+ thd->lex->alter_info.flags &
+ ALTER_OPTIMIZE_PARTITION ? FALSE : TRUE));
}
@@ -880,8 +885,10 @@ int ha_partition::analyze(THD *thd, HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("ha_partition::analyze");
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- ANALYZE_PARTS, TRUE));
+ DBUG_RETURN(handle_opt_partitions(thd, check_opt,
+ ANALYZE_PARTS,
+ thd->lex->alter_info.flags &
+ ALTER_ANALYZE_PARTITION ? FALSE : TRUE));
}
@@ -902,8 +909,10 @@ int ha_partition::check(THD *thd, HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("ha_partition::check");
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- CHECK_PARTS, TRUE));
+ DBUG_RETURN(handle_opt_partitions(thd, check_opt,
+ CHECK_PARTS,
+ thd->lex->alter_info.flags &
+ ALTER_CHECK_PARTITION ? FALSE : TRUE));
}
@@ -924,95 +933,12 @@ int ha_partition::repair(THD *thd, HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("ha_partition::repair");
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- REPAIR_PARTS, TRUE));
-}
-
-/*
- Optimize partitions
-
- SYNOPSIS
- optimize_partitions()
- thd Thread object
- RETURN VALUE
- >0 Failure
- 0 Success
- DESCRIPTION
- Call optimize on each partition marked with partition state PART_CHANGED
-*/
-
-int ha_partition::optimize_partitions(THD *thd)
-{
- DBUG_ENTER("ha_partition::optimize_partitions");
-
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- OPTIMIZE_PARTS, FALSE));
-}
-
-/*
- Analyze partitions
-
- SYNOPSIS
- analyze_partitions()
- thd Thread object
- RETURN VALUE
- >0 Failure
- 0 Success
- DESCRIPTION
- Call analyze on each partition marked with partition state PART_CHANGED
-*/
-
-int ha_partition::analyze_partitions(THD *thd)
-{
- DBUG_ENTER("ha_partition::analyze_partitions");
-
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- ANALYZE_PARTS, FALSE));
-}
-
-/*
- Check partitions
-
- SYNOPSIS
- check_partitions()
- thd Thread object
- RETURN VALUE
- >0 Failure
- 0 Success
- DESCRIPTION
- Call check on each partition marked with partition state PART_CHANGED
-*/
-
-int ha_partition::check_partitions(THD *thd)
-{
- DBUG_ENTER("ha_partition::check_partitions");
-
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- CHECK_PARTS, FALSE));
-}
-
-/*
- Repair partitions
-
- SYNOPSIS
- repair_partitions()
- thd Thread object
- RETURN VALUE
- >0 Failure
- 0 Success
- DESCRIPTION
- Call repair on each partition marked with partition state PART_CHANGED
-*/
-
-int ha_partition::repair_partitions(THD *thd)
-{
- DBUG_ENTER("ha_partition::repair_partitions");
-
- DBUG_RETURN(handle_opt_partitions(thd, &thd->lex->check_opt,
- REPAIR_PARTS, FALSE));
+ DBUG_RETURN(handle_opt_partitions(thd, check_opt,
+ REPAIR_PARTS,
+ thd->lex->alter_info.flags &
+ ALTER_REPAIR_PARTITION ? FALSE : TRUE));
}
-
/*
Handle optimize/analyze/check/repair of one partition
@@ -1028,7 +954,6 @@ int ha_partition::repair_partitions(THD *thd)
0 Success
*/
-#ifdef WL4176_IS_DONE
static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
handler *file, uint flag)
{
@@ -1036,12 +961,6 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
DBUG_ENTER("handle_opt_part");
DBUG_PRINT("enter", ("flag = %u", flag));
- /*
- TODO:
- Rewrite the code for ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION WL4176
- */
- DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
-
if (flag == OPTIMIZE_PARTS)
error= file->ha_optimize(thd, check_opt);
else if (flag == ANALYZE_PARTS)
@@ -1059,7 +978,59 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
error= 0;
DBUG_RETURN(error);
}
-#endif
+
+
+/*
+ print a message row formatted for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
+ (modelled after mi_check_print_msg)
+ TODO: move this into the handler, or rewrite mysql_admin_table.
+*/
+static bool print_admin_msg(THD* thd, const char* msg_type,
+ const char* db_name, const char* table_name,
+ const char* op_name, const char *fmt, ...)
+{
+ va_list args;
+ Protocol *protocol= thd->protocol;
+ uint length, msg_length;
+ char msgbuf[MI_MAX_MSG_BUF];
+ char name[NAME_LEN*2+2];
+
+ va_start(args, fmt);
+ msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
+ va_end(args);
+ msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
+
+
+ if (!thd->vio_ok())
+ {
+ sql_print_error(msgbuf);
+ return TRUE;
+ }
+
+ length=(uint) (strxmov(name, db_name, ".", table_name,NullS) - name);
+ /*
+ TODO: switch from protocol to push_warning here. The main reason we didn't
+ it yet is parallel repair. Due to following trace:
+ mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
+
+ Also we likely need to lock mutex here (in both cases with protocol and
+ push_warning).
+ */
+ DBUG_PRINT("info",("print_admin_msg: %s, %s, %s, %s", name, op_name,
+ msg_type, msgbuf));
+ protocol->prepare_for_resend();
+ protocol->store(name, length, system_charset_info);
+ protocol->store(op_name, system_charset_info);
+ protocol->store(msg_type, system_charset_info);
+ protocol->store(msgbuf, msg_length, system_charset_info);
+ if (protocol->write())
+ {
+ sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
+ msgbuf);
+ return TRUE;
+ }
+ return FALSE;
+}
/*
@@ -1080,55 +1051,89 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
uint flag, bool all_parts)
{
-#ifdef WL4176_IS_DONE
List_iterator<partition_element> part_it(m_part_info->partitions);
uint no_parts= m_part_info->no_parts;
uint no_subparts= m_part_info->no_subparts;
uint i= 0;
int error;
-#endif
DBUG_ENTER("ha_partition::handle_opt_partitions");
DBUG_PRINT("enter", ("all_parts %u, flag= %u", all_parts, flag));
- /*
- TODO:
- Rewrite the code for ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION WL4176
- */
- DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
-#ifdef WL4176_IS_DONE
do
{
partition_element *part_elem= part_it++;
- if (all_parts || part_elem->part_state == PART_CHANGED)
+ /*
+ when ALTER TABLE <CMD> PARTITION ...
+ it should only do named partitions, otherwise all partitions
+ */
+ if (all_parts ||
+ part_elem->part_state == PART_CHANGED)
{
if (m_is_sub_partitioned)
{
+ List_iterator<partition_element> subpart_it(part_elem->subpartitions);
+ partition_element *sub_elem;
uint j= 0, part;
do
{
+ sub_elem= subpart_it++;
part= i * no_subparts + j;
- DBUG_PRINT("info", ("Optimize subpartition %u",
- part));
+ DBUG_PRINT("info", ("Optimize subpartition %u (%s)",
+ part, sub_elem->partition_name));
+#ifdef NOT_USED
+ if (print_admin_msg(thd, "note", table_share->db.str, table->alias,
+ opt_op_name[flag],
+ "Start to operate on subpartition %s",
+ sub_elem->partition_name))
+ DBUG_RETURN(HA_ADMIN_INTERNAL_ERROR);
+#endif
if ((error= handle_opt_part(thd, check_opt, m_file[part], flag)))
{
+ /* print a line which partition the error belongs to */
+ if (error != HA_ADMIN_NOT_IMPLEMENTED &&
+ error != HA_ADMIN_ALREADY_DONE &&
+ error != HA_ADMIN_TRY_ALTER)
+ {
+ print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ opt_op_name[flag],
+ "Subpartition %s returned error",
+ sub_elem->partition_name);
+ }
DBUG_RETURN(error);
}
} while (++j < no_subparts);
}
else
{
- DBUG_PRINT("info", ("Optimize partition %u", i));
+ DBUG_PRINT("info", ("Optimize partition %u (%s)", i,
+ part_elem->partition_name));
+#ifdef NOT_USED
+ if (print_admin_msg(thd, "note", table_share->db.str, table->alias,
+ opt_op_name[flag],
+ "Start to operate on partition %s",
+ part_elem->partition_name))
+ DBUG_RETURN(HA_ADMIN_INTERNAL_ERROR);
+#endif
if ((error= handle_opt_part(thd, check_opt, m_file[i], flag)))
{
+ /* print a line which partition the error belongs to */
+ if (error != HA_ADMIN_NOT_IMPLEMENTED &&
+ error != HA_ADMIN_ALREADY_DONE &&
+ error != HA_ADMIN_TRY_ALTER)
+ {
+ print_admin_msg(thd, "error", table_share->db.str, table->alias,
+ opt_op_name[flag], "Partition %s returned error",
+ part_elem->partition_name);
+ }
DBUG_RETURN(error);
}
}
}
} while (++i < no_parts);
DBUG_RETURN(FALSE);
-#endif
}
+
/*
Prepare by creating a new partition
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 2ec700978bc..e86dc5fea1a 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -932,10 +932,6 @@ public:
virtual int analyze(THD* thd, HA_CHECK_OPT *check_opt);
virtual int check(THD* thd, HA_CHECK_OPT *check_opt);
virtual int repair(THD* thd, HA_CHECK_OPT *check_opt);
- virtual int optimize_partitions(THD *thd);
- virtual int analyze_partitions(THD *thd);
- virtual int check_partitions(THD *thd);
- virtual int repair_partitions(THD *thd);
private:
int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
diff --git a/sql/handler.cc b/sql/handler.cc
index fe4944ed836..e550295ebba 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3285,66 +3285,6 @@ handler::ha_rename_partitions(const char *path)
/**
- Optimize partitions: public interface.
-
- @sa handler::optimize_partitions()
-*/
-
-int
-handler::ha_optimize_partitions(THD *thd)
-{
- mark_trx_read_write();
-
- return optimize_partitions(thd);
-}
-
-
-/**
- Analyze partitions: public interface.
-
- @sa handler::analyze_partitions()
-*/
-
-int
-handler::ha_analyze_partitions(THD *thd)
-{
- mark_trx_read_write();
-
- return analyze_partitions(thd);
-}
-
-
-/**
- Check partitions: public interface.
-
- @sa handler::check_partitions()
-*/
-
-int
-handler::ha_check_partitions(THD *thd)
-{
- mark_trx_read_write();
-
- return check_partitions(thd);
-}
-
-
-/**
- Repair partitions: public interface.
-
- @sa handler::repair_partitions()
-*/
-
-int
-handler::ha_repair_partitions(THD *thd)
-{
- mark_trx_read_write();
-
- return repair_partitions(thd);
-}
-
-
-/**
Tell the storage engine that it is allowed to "disable transaction" in the
handler. It is a hint that ACID is not required - it is used in NDB for
ALTER TABLE, for example, when data are copied to temporary table.
diff --git a/sql/handler.h b/sql/handler.h
index d674c07a57d..df6157f80b4 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1247,10 +1247,6 @@ public:
size_t pack_frm_len);
int ha_drop_partitions(const char *path);
int ha_rename_partitions(const char *path);
- int ha_optimize_partitions(THD *thd);
- int ha_analyze_partitions(THD *thd);
- int ha_check_partitions(THD *thd);
- int ha_repair_partitions(THD *thd);
void adjust_next_insert_id_after_explicit_value(ulonglong nr);
int update_auto_increment();
@@ -1911,14 +1907,6 @@ private:
{ return HA_ERR_WRONG_COMMAND; }
virtual int rename_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
- virtual int optimize_partitions(THD *thd)
- { return HA_ERR_WRONG_COMMAND; }
- virtual int analyze_partitions(THD *thd)
- { return HA_ERR_WRONG_COMMAND; }
- virtual int check_partitions(THD *thd)
- { return HA_ERR_WRONG_COMMAND; }
- virtual int repair_partitions(THD *thd)
- { return HA_ERR_WRONG_COMMAND; }
};
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f6ba5fc9739..e9deb479c5e 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1571,6 +1571,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
char *db,
const char *table_name,
uint fast_alter_partition);
+uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
+ enum partition_state part_state);
uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
HA_CREATE_INFO *create_info,
handlerton *old_db_type,
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 5fe56724d08..4177cd0054d 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -788,6 +788,9 @@ bool Protocol_text::store(const char *from, size_t length,
{
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifndef DBUG_OFF
+ DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %s", field_pos,
+ field_count, from));
+ DBUG_ASSERT(field_pos < field_count);
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
field_types[field_pos] == MYSQL_TYPE_BIT ||
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 121ee3c22b4..6419d336b9f 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4080,6 +4080,38 @@ error:
/*
+ Sets which partitions to be used in the command
+*/
+uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
+ enum partition_state part_state)
+{
+ uint part_count= 0;
+ uint no_parts_found= 0;
+ List_iterator<partition_element> part_it(tab_part_info->partitions);
+
+ do
+ {
+ partition_element *part_elem= part_it++;
+ if ((alter_info->flags & ALTER_ALL_PARTITION) ||
+ (is_name_in_list(part_elem->partition_name,
+ alter_info->partition_names)))
+ {
+ /*
+ Mark the partition.
+ I.e mark the partition as a partition to be "changed" by
+ analyzing/optimizing/rebuilding/checking/repairing
+ */
+ no_parts_found++;
+ part_elem->part_state= part_state;
+ DBUG_PRINT("info", ("Setting part_state to %u for partition %s",
+ part_state, part_elem->partition_name));
+ }
+ } while (++part_count < tab_part_info->no_parts);
+ return no_parts_found;
+}
+
+
+/*
Prepare for ALTER TABLE of partition structure
SYNOPSIS
@@ -4534,26 +4566,9 @@ that are reorganised.
(alter_info->flags & ALTER_REPAIR_PARTITION) ||
(alter_info->flags & ALTER_REBUILD_PARTITION))
{
+ uint no_parts_found;
uint no_parts_opt= alter_info->partition_names.elements;
- uint part_count= 0;
- uint no_parts_found= 0;
- List_iterator<partition_element> part_it(tab_part_info->partitions);
-
- do
- {
- partition_element *part_elem= part_it++;
- if ((alter_info->flags & ALTER_ALL_PARTITION) ||
- (is_name_in_list(part_elem->partition_name,
- alter_info->partition_names)))
- {
- /*
- Mark the partition as a partition to be "changed" by
- analyzing/optimizing/rebuilding/checking/repairing
- */
- no_parts_found++;
- part_elem->part_state= PART_CHANGED;
- }
- } while (++part_count < tab_part_info->no_parts);
+ no_parts_found= set_part_state(alter_info, tab_part_info, PART_CHANGED);
if (no_parts_found != no_parts_opt &&
(!(alter_info->flags & ALTER_ALL_PARTITION)))
{
@@ -6026,48 +6041,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->pack_frm_len= 0;
thd->work_part_info= part_info;
- if (alter_info->flags & ALTER_OPTIMIZE_PARTITION ||
- alter_info->flags & ALTER_ANALYZE_PARTITION ||
- alter_info->flags & ALTER_CHECK_PARTITION ||
- alter_info->flags & ALTER_REPAIR_PARTITION)
- {
- /*
- In this case the user has specified that he wants a set of partitions
- to be optimised and the partition engine can handle optimising
- partitions natively without requiring a full rebuild of the
- partitions.
-
- In this case it is enough to call optimise_partitions, there is no
- need to change frm files or anything else.
- */
- int error;
- written_bin_log= FALSE;
- if (((alter_info->flags & ALTER_OPTIMIZE_PARTITION) &&
- (error= table->file->ha_optimize_partitions(thd))) ||
- ((alter_info->flags & ALTER_ANALYZE_PARTITION) &&
- (error= table->file->ha_analyze_partitions(thd))) ||
- ((alter_info->flags & ALTER_CHECK_PARTITION) &&
- (error= table->file->ha_check_partitions(thd))) ||
- ((alter_info->flags & ALTER_REPAIR_PARTITION) &&
- (error= table->file->ha_repair_partitions(thd))))
- {
- if (error == HA_ADMIN_NOT_IMPLEMENTED) {
- if (alter_info->flags & ALTER_OPTIMIZE_PARTITION)
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "optimize partition");
- else if (alter_info->flags & ALTER_ANALYZE_PARTITION)
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "analyze partition");
- else if (alter_info->flags & ALTER_CHECK_PARTITION)
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "check partition");
- else if (alter_info->flags & ALTER_REPAIR_PARTITION)
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "repair partition");
- else
- table->file->print_error(error, MYF(0));
- } else
- table->file->print_error(error, MYF(0));
- goto err;
- }
- }
- else if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
+ if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
{
/*
In the case where the engine supports one phase online partition
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2b3b5ef67d9..226facffe7c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4194,6 +4194,46 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
table->next_global= save_next_global;
table->next_local= save_next_local;
thd->open_options&= ~extra_open_options;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (table->table && table->table->part_info)
+ {
+ /*
+ Set up which partitions that should be processed
+ if ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION ..
+ */
+ Alter_info *alter_info= &lex->alter_info;
+
+ if (alter_info->flags & ALTER_ANALYZE_PARTITION ||
+ alter_info->flags & ALTER_CHECK_PARTITION ||
+ alter_info->flags & ALTER_OPTIMIZE_PARTITION ||
+ alter_info->flags & ALTER_REPAIR_PARTITION)
+ {
+ uint no_parts_found;
+ uint no_parts_opt= alter_info->partition_names.elements;
+ no_parts_found= set_part_state(alter_info, table->table->part_info,
+ PART_CHANGED);
+ if (no_parts_found != no_parts_opt &&
+ (!(alter_info->flags & ALTER_ALL_PARTITION)))
+ {
+ char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
+ uint length;
+ DBUG_PRINT("admin", ("sending non existent partition error"));
+ protocol->prepare_for_resend();
+ protocol->store(table_name, system_charset_info);
+ protocol->store(operator_name, system_charset_info);
+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
+ length= my_snprintf(buff, sizeof(buff),
+ ER(ER_DROP_PARTITION_NON_EXISTENT),
+ table_name);
+ protocol->store(buff, length, system_charset_info);
+ if(protocol->write())
+ goto err;
+ my_eof(thd);
+ goto err;
+ }
+ }
+ }
+#endif
}
DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
@@ -4428,9 +4468,17 @@ send_result_message:
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.
+ We have to end the row, so analyze could return more rows.
*/
+ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
+ protocol->store(STRING_WITH_LEN(
+ "Table does not support optimize, doing recreate + analyze instead"),
+ system_charset_info);
+ if (protocol->write())
+ goto err;
ha_autocommit_or_rollback(thd, 0);
close_thread_tables(thd);
+ DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
TABLE_LIST *save_next_local= table->next_local,
*save_next_global= table->next_global;
table->next_local= table->next_global= 0;
@@ -4453,6 +4501,10 @@ send_result_message:
((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
result_code= 0; // analyze went ok
}
+ /* Start a new row for the final status row */
+ protocol->prepare_for_resend();
+ protocol->store(table_name, system_charset_info);
+ protocol->store(operator_name, system_charset_info);
if (result_code) // either mysql_recreate_table or analyze failed
{
DBUG_ASSERT(thd->is_error());
@@ -4468,7 +4520,8 @@ send_result_message:
/* Hijack the row already in-progress. */
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
protocol->store(err_msg, system_charset_info);
- (void)protocol->write();
+ if (protocol->write())
+ goto err;
/* Start off another row for HA_ADMIN_FAILED */
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ccd64c24960..c3f691ef808 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5543,6 +5543,7 @@ alter_commands:
all_or_alt_part_name_list
{
LEX *lex= Lex;
+ lex->sql_command = SQLCOM_OPTIMIZE;
lex->alter_info.flags|= ALTER_OPTIMIZE_PARTITION;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -5552,6 +5553,7 @@ alter_commands:
all_or_alt_part_name_list
{
LEX *lex= Lex;
+ lex->sql_command = SQLCOM_ANALYZE;
lex->alter_info.flags|= ALTER_ANALYZE_PARTITION;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -5559,6 +5561,7 @@ alter_commands:
| CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
{
LEX *lex= Lex;
+ lex->sql_command = SQLCOM_CHECK;
lex->alter_info.flags|= ALTER_CHECK_PARTITION;
lex->check_opt.init();
}
@@ -5567,6 +5570,7 @@ alter_commands:
all_or_alt_part_name_list
{
LEX *lex= Lex;
+ lex->sql_command = SQLCOM_REPAIR;
lex->alter_info.flags|= ALTER_REPAIR_PARTITION;
lex->no_write_to_binlog= $3;
lex->check_opt.init();
@@ -6009,6 +6013,7 @@ repair:
lex->sql_command = SQLCOM_REPAIR;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
+ lex->alter_info.reset();
}
table_list opt_mi_repair_type
{}
@@ -6037,6 +6042,7 @@ analyze:
lex->sql_command = SQLCOM_ANALYZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
+ lex->alter_info.reset();
}
table_list
{}
@@ -6062,6 +6068,7 @@ check:
}
lex->sql_command = SQLCOM_CHECK;
lex->check_opt.init();
+ lex->alter_info.reset();
}
table_list opt_mi_check_type
{}
@@ -6093,6 +6100,7 @@ optimize:
lex->sql_command = SQLCOM_OPTIMIZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
+ lex->alter_info.reset();
}
table_list
{}