#At file:///home/alik/MySQL/bzr/00/bug55843/2011.05.19/mysql-5.5/ based on revid:alexander.nozdrin@stripped
3390 Alexander Nozdrin 2011-05-19
Pre-requisite patch for Bug#11763162 (55843 - Handled condition
appears as not handled).
The patch introduces Diagnostics_area::m_error_condition and
adds the code to set it properly.
Diagnostics_area::m_error_condition is intended to store a pointer
to a MYSQL_ERROR object corresponding to the error state of
Diagnostics_area.
modified:
sql/sql_class.cc
sql/sql_error.cc
sql/sql_error.h
sql/sql_insert.cc
sql/sql_prepare.cc
sql/thr_malloc.cc
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2011-05-19 10:12:31 +0000
+++ b/sql/sql_class.cc 2011-05-19 11:53:50 +0000
@@ -823,6 +823,12 @@ MYSQL_ERROR* THD::raise_condition(uint s
if (handle_condition(sql_errno, sqlstate, level, msg, &cond))
DBUG_RETURN(cond);
+ /* When simulating OOM, skip writing to error log to avoid mtr errors. */
+ cond= DBUG_EVALUATE_IF(
+ "simulate_out_of_memory",
+ NULL,
+ get_warning_info()->push_warning(this, sql_errno, sqlstate, level, msg));
+
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
{
is_slave_error= 1; // needed to catch query errors during replication
@@ -846,17 +852,13 @@ MYSQL_ERROR* THD::raise_condition(uint s
if (! m_stmt_da->is_error())
{
set_row_count_func(-1);
- m_stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
+ m_stmt_da->set_error_status(this, sql_errno, msg, sqlstate, cond);
}
}
}
query_cache_abort(&query_cache_tls);
- /* When simulating OOM, skip writing to error log to avoid mtr errors */
- DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL););
-
- cond= get_warning_info()->push_warning(this, sql_errno, sqlstate, level, msg);
DBUG_RETURN(cond);
}
=== modified file 'sql/sql_error.cc'
--- a/sql/sql_error.cc 2011-05-19 10:10:49 +0000
+++ b/sql/sql_error.cc 2011-05-19 11:53:50 +0000
@@ -337,6 +337,7 @@ Diagnostics_area::reset_diagnostics_area
m_last_insert_id= 0;
m_statement_warn_count= 0;
#endif
+ m_current_wi->clear_error_condition();
is_sent= FALSE;
/** Tiny reset in debug mode to see garbage right away */
m_status= DA_EMPTY;
@@ -406,12 +407,16 @@ Diagnostics_area::set_eof_status(THD *th
/**
Set ERROR status.
+
+ Note, that error_condition may be NULL. It happens if a) OOM error is
+ being reported; or b) when Warning_info is full.
*/
void
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
const char *message_arg,
- const char *sqlstate)
+ const char *sqlstate,
+ MYSQL_ERROR *error_condition)
{
DBUG_ENTER("set_error_status");
/*
@@ -437,6 +442,8 @@ Diagnostics_area::set_error_status(THD *
m_sqlstate[SQLSTATE_LENGTH]= '\0';
strmake(m_message, message_arg, sizeof(m_message)-1);
+ m_current_wi->set_error_condition(error_condition);
+
m_status= DA_ERROR;
DBUG_VOID_RETURN;
}
@@ -461,6 +468,7 @@ Warning_info::Warning_info(ulonglong war
:m_statement_warn_count(0),
m_current_row_for_warning(1),
m_warn_id(warn_id_arg),
+ m_error_condition(NULL),
m_allow_unlimited_warnings(allow_unlimited_warnings),
m_read_only(FALSE)
{
@@ -489,8 +497,30 @@ void Warning_info::clear_warning_info(ul
m_warn_list.empty();
m_statement_warn_count= 0;
m_current_row_for_warning= 1; /* Start counting from the first row */
+ clear_error_condition();
+}
+
+
+void Warning_info::append_warning_info(THD *thd, Warning_info *source)
+{
+ MYSQL_ERROR *err;
+ List_iterator_fast<MYSQL_ERROR> it(source->warn_list());
+ MYSQL_ERROR *src_error_condition= source->get_error_condition();
+
+ /*
+ Don't use ::push_warning() to avoid invocation of condition
+ handlers or escalation of warnings to errors.
+ */
+ while ((err= it++))
+ {
+ MYSQL_ERROR *new_error= Warning_info::push_warning(thd, err);
+
+ if (src_error_condition && src_error_condition == err)
+ set_error_condition(new_error);
+ }
}
+
/**
Append warnings only if the original contents of the routine
warning info was replaced.
=== modified file 'sql/sql_error.h'
--- a/sql/sql_error.h 2011-05-19 10:12:31 +0000
+++ b/sql/sql_error.h 2011-05-19 11:53:50 +0000
@@ -56,7 +56,8 @@ public:
const char *message);
void set_eof_status(THD *thd);
void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg,
- const char *sqlstate);
+ const char *sqlstate,
+ class MYSQL_ERROR *error_condition);
void disable_status();
@@ -362,6 +363,7 @@ class Warning_info
/** Used to optionally clear warnings only once per statement. */
ulonglong m_warn_id;
+ MYSQL_ERROR * m_error_condition;
/** Indicates if push_warning() allows unlimited number of warnings. */
bool m_allow_unlimited_warnings;
@@ -396,26 +398,11 @@ public:
clear_warning_info(query_id);
}
- void append_warning_info(THD *thd, Warning_info *source)
- {
- append_warnings(thd, & source->warn_list());
- }
-
/**
Concatenate the list of warnings.
It's considered tolerable to lose a warning.
*/
- void append_warnings(THD *thd, List<MYSQL_ERROR> *src)
- {
- MYSQL_ERROR *err;
- List_iterator_fast<MYSQL_ERROR> it(*src);
- /*
- Don't use ::push_warning() to avoid invocation of condition
- handlers or escalation of warnings to errors.
- */
- while ((err= it++))
- Warning_info::push_warning(thd, err);
- }
+ void append_warning_info(THD *thd, Warning_info *source);
/**
Conditional merge of related warning information areas.
@@ -504,6 +491,15 @@ public:
bool is_read_only() const
{ return m_read_only; }
+ MYSQL_ERROR *get_error_condition()
+ { return m_error_condition; }
+
+ void set_error_condition(MYSQL_ERROR *error_condition)
+ { m_error_condition= error_condition; }
+
+ void clear_error_condition()
+ { m_error_condition= NULL; }
+
private:
/** Read only status. */
bool m_read_only;
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2011-05-19 10:10:49 +0000
+++ b/sql/sql_insert.cc 2011-05-19 11:53:50 +0000
@@ -2615,7 +2615,7 @@ pthread_handler_t handle_delayed_insert(
{
/* Can't use my_error since store_globals has not yet been called */
thd->get_stmt_da()->set_error_status(thd, ER_OUT_OF_RESOURCES,
- ER(ER_OUT_OF_RESOURCES), NULL);
+ ER(ER_OUT_OF_RESOURCES), NULL, NULL);
di->handler_thread_initialized= TRUE;
}
else
@@ -2626,7 +2626,7 @@ pthread_handler_t handle_delayed_insert(
{
/* Can't use my_error since store_globals has perhaps failed */
thd->get_stmt_da()->set_error_status(thd, ER_OUT_OF_RESOURCES,
- ER(ER_OUT_OF_RESOURCES), NULL);
+ ER(ER_OUT_OF_RESOURCES), NULL, NULL);
di->handler_thread_initialized= TRUE;
thd->fatal_error();
goto err;
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2011-05-19 10:12:31 +0000
+++ b/sql/sql_prepare.cc 2011-05-19 11:53:50 +0000
@@ -2935,7 +2935,7 @@ Reprepare_observer::report_error(THD *th
backtracking all the way to Prepared_statement::execute_loop().
*/
thd->get_stmt_da()->set_error_status(thd, ER_NEED_REPREPARE,
- ER(ER_NEED_REPREPARE), "HY000");
+ ER(ER_NEED_REPREPARE), "HY000", NULL);
m_invalidated= TRUE;
return TRUE;
=== modified file 'sql/thr_malloc.cc'
--- a/sql/thr_malloc.cc 2011-05-19 10:10:49 +0000
+++ b/sql/thr_malloc.cc 2011-05-19 11:53:50 +0000
@@ -48,7 +48,7 @@ extern "C" {
thd->get_stmt_da()->set_error_status(thd,
ER_OUT_OF_RESOURCES,
ER(ER_OUT_OF_RESOURCES),
- NULL);
+ NULL, NULL);
}
}
Attachment: [text/bzr-bundle] bzr/alexander.nozdrin@oracle.com-20110519115350-f2uxdqn91ecjqty4.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5 branch (alexander.nozdrin:3390) Bug#11763162 | Alexander Nozdrin | 19 May |