summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc85
1 files changed, 81 insertions, 4 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 49cd948791b..892757d77fe 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -91,6 +91,69 @@ bool No_such_table_error_handler::safely_trapped_errors()
return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
}
+
+/**
+ This internal handler is used to trap ER_NO_SUCH_TABLE and
+ ER_WRONG_MRG_TABLE errors during CHECK/REPAIR TABLE for MERGE
+ tables.
+*/
+
+class Repair_mrg_table_error_handler : public Internal_error_handler
+{
+public:
+ Repair_mrg_table_error_handler()
+ : m_handled_errors(false), m_unhandled_errors(false)
+ {}
+
+ bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sqlstate,
+ MYSQL_ERROR::enum_warning_level level,
+ const char* msg,
+ MYSQL_ERROR ** cond_hdl);
+
+ /**
+ Returns TRUE if there were ER_NO_SUCH_/WRONG_MRG_TABLE and there
+ were no unhandled errors. FALSE otherwise.
+ */
+ bool safely_trapped_errors()
+ {
+ /*
+ Check for m_handled_errors is here for extra safety.
+ It can be useful in situation when call to open_table()
+ fails because some error which was suppressed by another
+ error handler (e.g. in case of MDL deadlock which we
+ decided to solve by back-off and retry).
+ */
+ return (m_handled_errors && (! m_unhandled_errors));
+ }
+
+private:
+ bool m_handled_errors;
+ bool m_unhandled_errors;
+};
+
+
+bool
+Repair_mrg_table_error_handler::handle_condition(THD *,
+ uint sql_errno,
+ const char*,
+ MYSQL_ERROR::enum_warning_level level,
+ const char*,
+ MYSQL_ERROR ** cond_hdl)
+{
+ *cond_hdl= NULL;
+ if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_WRONG_MRG_TABLE)
+ {
+ m_handled_errors= true;
+ return TRUE;
+ }
+
+ m_unhandled_errors= true;
+ return FALSE;
+}
+
+
/**
@defgroup Data_Dictionary Data Dictionary
@{
@@ -4410,6 +4473,20 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
thd->pop_internal_handler();
safe_to_ignore_table= no_such_table_handler.safely_trapped_errors();
}
+ else if (tables->parent_l && (thd->open_options & HA_OPEN_FOR_REPAIR))
+ {
+ /*
+ Also fail silently for underlying tables of a MERGE table if this
+ table is opened for CHECK/REPAIR TABLE statement. This is needed
+ to provide complete list of problematic underlying tables in
+ CHECK/REPAIR TABLE output.
+ */
+ Repair_mrg_table_error_handler repair_mrg_table_handler;
+ thd->push_internal_handler(&repair_mrg_table_handler);
+ error= open_table(thd, tables, new_frm_mem, ot_ctx);
+ thd->pop_internal_handler();
+ safe_to_ignore_table= repair_mrg_table_handler.safely_trapped_errors();
+ }
else
error= open_table(thd, tables, new_frm_mem, ot_ctx);
@@ -7875,7 +7952,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
sum_func_list)
item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
- thd->used_tables|= item->used_tables();
+ thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->cur_pos_in_select_list++;
}
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
@@ -8293,7 +8370,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
views and natural joins this update is performed inside the loop below.
*/
if (table)
- thd->used_tables|= table->map;
+ thd->lex->used_tables|= table->map;
/*
Initialize a generic field iterator for the current table reference.
@@ -8384,7 +8461,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
field_table= nj_col->table_ref->table;
if (field_table)
{
- thd->used_tables|= field_table->map;
+ thd->lex->used_tables|= field_table->map;
field_table->covering_keys.intersect(field->part_of_key);
field_table->merge_keys.merge(field->part_of_key);
field_table->used_fields++;
@@ -8392,7 +8469,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
}
else
- thd->used_tables|= item->used_tables();
+ thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->cur_pos_in_select_list++;
}
/*