summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-10-12 18:16:38 +0400
committerAlexander Barkov <bar@mariadb.org>2017-04-05 15:02:53 +0400
commit6010662cb328c10b1ef92c3ed43b2b3858c49863 (patch)
treec0927233efb1168b4018f2a59d099caafc4343de
parentffca1e48301a30ae9c3e9c338293e31914182ed2 (diff)
downloadmariadb-git-6010662cb328c10b1ef92c3ed43b2b3858c49863.tar.gz
MDEV-11037 Diagnostics_area refactoring for user defined exceptions
-rw-r--r--sql/sp_pcontext.cc19
-rw-r--r--sql/sp_pcontext.h48
-rw-r--r--sql/sp_rcontext.cc12
-rw-r--r--sql/sp_rcontext.h17
-rw-r--r--sql/sql_error.cc83
-rw-r--r--sql/sql_error.h288
-rw-r--r--sql/sql_signal.cc70
-rw-r--r--sql/sql_signal.h21
8 files changed, 257 insertions, 301 deletions
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 87ec5f98557..0937dfdb081 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -36,10 +36,10 @@ bool sp_condition_value::equals(const sp_condition_value *cv) const
switch (type)
{
case sp_condition_value::ERROR_CODE:
- return (mysqlerr == cv->mysqlerr);
+ return (get_sql_errno() == cv->get_sql_errno());
case sp_condition_value::SQLSTATE:
- return (strcmp(sql_state, cv->sql_state) == 0);
+ return Sql_state::eq(cv);
default:
return true;
@@ -354,8 +354,7 @@ bool sp_pcontext::check_duplicate_handler(
sp_handler*
-sp_pcontext::find_handler(const char *sql_state,
- uint sql_errno,
+sp_pcontext::find_handler(const Sql_state_errno *value,
Sql_condition::enum_warning_level level) const
{
sp_handler *found_handler= NULL;
@@ -373,7 +372,7 @@ sp_pcontext::find_handler(const char *sql_state,
switch (cv->type)
{
case sp_condition_value::ERROR_CODE:
- if (sql_errno == cv->mysqlerr &&
+ if (value->get_sql_errno() == cv->get_sql_errno() &&
(!found_cv ||
found_cv->type > sp_condition_value::ERROR_CODE))
{
@@ -383,7 +382,7 @@ sp_pcontext::find_handler(const char *sql_state,
break;
case sp_condition_value::SQLSTATE:
- if (strcmp(sql_state, cv->sql_state) == 0 &&
+ if (cv->Sql_state::eq(value) &&
(!found_cv ||
found_cv->type > sp_condition_value::SQLSTATE))
{
@@ -393,7 +392,7 @@ sp_pcontext::find_handler(const char *sql_state,
break;
case sp_condition_value::WARNING:
- if ((is_sqlstate_warning(sql_state) ||
+ if ((value->Sql_state::is_warning() ||
level == Sql_condition::WARN_LEVEL_WARN) && !found_cv)
{
found_cv= cv;
@@ -402,7 +401,7 @@ sp_pcontext::find_handler(const char *sql_state,
break;
case sp_condition_value::NOT_FOUND:
- if (is_sqlstate_not_found(sql_state) && !found_cv)
+ if (value->Sql_state::is_not_found() && !found_cv)
{
found_cv= cv;
found_handler= h;
@@ -418,7 +417,7 @@ sp_pcontext::find_handler(const char *sql_state,
and it should be caught.
*/
if (((current_thd->variables.sql_mode & MODE_ORACLE) ||
- (is_sqlstate_exception(sql_state) &&
+ (value->Sql_state::is_exception() &&
level == Sql_condition::WARN_LEVEL_ERROR)) && !found_cv)
{
found_cv= cv;
@@ -467,7 +466,7 @@ sp_pcontext::find_handler(const char *sql_state,
if (!p || !p->m_parent)
return NULL;
- return p->m_parent->find_handler(sql_state, sql_errno, level);
+ return p->m_parent->find_handler(value, level);
}
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 4f4595899fb..d97643e5ade 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -127,12 +127,8 @@ public:
/// In some sense, this class is a union -- a set of filled attributes
/// depends on the sp_condition_value::type value.
-class sp_condition_value : public Sql_alloc
+class sp_condition_value : public Sql_alloc, public Sql_state_errno
{
- void init_sql_state()
- {
- sql_state[0]= '\0';
- }
public:
enum enum_type
{
@@ -146,44 +142,30 @@ public:
/// Type of the condition value.
enum_type type;
- /// SQLSTATE of the condition value.
- char sql_state[SQLSTATE_LENGTH+1];
-
- /// MySQL error code of the condition value.
- uint mysqlerr;
-
public:
sp_condition_value(uint _mysqlerr)
:Sql_alloc(),
- type(ERROR_CODE),
- mysqlerr(_mysqlerr)
- { init_sql_state(); }
+ Sql_state_errno(_mysqlerr),
+ type(ERROR_CODE)
+ { }
sp_condition_value(uint _mysqlerr, const char *_sql_state)
:Sql_alloc(),
- type(ERROR_CODE),
- mysqlerr(_mysqlerr)
- {
- memcpy(sql_state, _sql_state, SQLSTATE_LENGTH);
- sql_state[SQLSTATE_LENGTH]= 0;
- }
+ Sql_state_errno(_mysqlerr, _sql_state),
+ type(ERROR_CODE)
+ { }
sp_condition_value(const char *_sql_state)
:Sql_alloc(),
- type(SQLSTATE),
- mysqlerr(0)
- {
- memcpy(sql_state, _sql_state, SQLSTATE_LENGTH);
- sql_state[SQLSTATE_LENGTH]= 0;
- }
+ Sql_state_errno(0, _sql_state),
+ type(SQLSTATE)
+ { }
sp_condition_value(enum_type _type)
:Sql_alloc(),
- type(_type),
- mysqlerr(0)
+ type(_type)
{
DBUG_ASSERT(type != ERROR_CODE && type != SQLSTATE);
- init_sql_state();
}
/// Check if two instances of sp_condition_value are equal or not.
@@ -192,8 +174,6 @@ public:
///
/// @return true if the instances are equal, false otherwise.
bool equals(const sp_condition_value *cv) const;
-
- bool has_sql_state() const { return sql_state[0] != '\0'; }
};
///////////////////////////////////////////////////////////////////////////
@@ -532,13 +512,11 @@ public:
/// Find an SQL handler for the given SQL condition according to the
/// SQL-handler resolution rules. This function is used at runtime.
///
- /// @param sql_state The SQL condition state
- /// @param sql_errno The error code
+ /// @param value The error code and the SQL state
/// @param level The SQL condition level
///
/// @return a pointer to the found SQL-handler or NULL.
- sp_handler *find_handler(const char *sql_state,
- uint sql_errno,
+ sp_handler *find_handler(const Sql_state_errno *value,
Sql_condition::enum_warning_level level) const;
/////////////////////////////////////////////////////////////////////////
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index ff5ecc5e6c6..338fe51d251 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -228,9 +228,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd,
if (thd->is_error())
{
found_handler=
- cur_spi->m_ctx->find_handler(da->get_sqlstate(),
- da->sql_errno(),
- Sql_condition::WARN_LEVEL_ERROR);
+ cur_spi->m_ctx->find_handler(da, Sql_condition::WARN_LEVEL_ERROR);
if (found_handler)
found_condition= da->get_error_condition();
@@ -246,9 +244,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd,
{
Sql_condition *condition=
new (callers_arena->mem_root) Sql_condition(callers_arena->mem_root);
- condition->set(da->sql_errno(), da->get_sqlstate(),
- Sql_condition::WARN_LEVEL_ERROR,
- da->message());
+ condition->set(da, Sql_condition::WARN_LEVEL_ERROR, da->message());
found_condition= condition;
}
}
@@ -267,9 +263,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd,
c->get_level() == Sql_condition::WARN_LEVEL_NOTE)
{
const sp_handler *handler=
- cur_spi->m_ctx->find_handler(c->get_sqlstate(),
- c->get_sql_errno(),
- c->get_level());
+ cur_spi->m_ctx->find_handler(c, c->get_level());
if (handler)
{
found_handler= handler;
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index b6b0d4de0c3..d2e1f5fec58 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -120,18 +120,9 @@ public:
/// standard SQL-condition processing (Diagnostics_area should contain an
/// object for active SQL-condition, not just information stored in DA's
/// fields).
- class Sql_condition_info : public Sql_alloc
+ class Sql_condition_info : public Sql_alloc, public Sql_state_errno_level
{
public:
- /// SQL error code.
- uint sql_errno;
-
- /// Error level.
- Sql_condition::enum_warning_level level;
-
- /// SQLSTATE.
- char sql_state[SQLSTATE_LENGTH + 1];
-
/// Text message.
char *message;
@@ -141,12 +132,8 @@ public:
/// @param arena Query arena for SP
Sql_condition_info(const Sql_condition *_sql_condition,
Query_arena *arena)
- :sql_errno(_sql_condition->get_sql_errno()),
- level(_sql_condition->get_level())
+ :Sql_state_errno_level(*_sql_condition)
{
- memcpy(sql_state, _sql_condition->get_sqlstate(), SQLSTATE_LENGTH);
- sql_state[SQLSTATE_LENGTH]= '\0';
-
message= strdup_root(arena->mem_root, _sql_condition->get_message_text());
}
};
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index d14c7b83b77..a7de8a00009 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -185,11 +185,8 @@ Sql_condition::Sql_condition()
m_column_name((const char*) NULL, 0, & my_charset_utf8_bin),
m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
m_message_text(),
- m_sql_errno(0),
- m_level(Sql_condition::WARN_LEVEL_ERROR),
m_mem_root(NULL)
{
- memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate));
}
void Sql_condition::init(MEM_ROOT *mem_root)
@@ -229,12 +226,9 @@ Sql_condition::Sql_condition(MEM_ROOT *mem_root)
m_column_name((const char*) NULL, 0, & my_charset_utf8_bin),
m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
m_message_text(),
- m_sql_errno(0),
- m_level(Sql_condition::WARN_LEVEL_ERROR),
m_mem_root(mem_root)
{
DBUG_ASSERT(mem_root != NULL);
- memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate));
}
static void copy_string(MEM_ROOT *mem_root, String* dst, const String* src)
@@ -270,21 +264,6 @@ Sql_condition::copy_opt_attributes(const Sql_condition *cond)
copy_string(m_mem_root, & m_cursor_name, & cond->m_cursor_name);
}
-void
-Sql_condition::set(uint sql_errno, const char* sqlstate,
- Sql_condition::enum_warning_level level, const char* msg)
-{
- DBUG_ASSERT(sql_errno != 0);
- DBUG_ASSERT(sqlstate != NULL);
- DBUG_ASSERT(msg != NULL);
-
- m_sql_errno= sql_errno;
- memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
- m_returned_sqlstate[SQLSTATE_LENGTH]= '\0';
-
- set_builtin_message_text(msg);
- m_level= level;
-}
void
Sql_condition::set_builtin_message_text(const char* str)
@@ -312,13 +291,46 @@ Sql_condition::get_message_octet_length() const
return m_message_text.length();
}
-void
-Sql_condition::set_sqlstate(const char* sqlstate)
+
+void Sql_state_errno_level::assign_defaults(const Sql_state_errno *from)
+{
+ DBUG_ASSERT(from);
+ int sqlerrno= from->get_sql_errno();
+ /*
+ SIGNAL is restricted in sql_yacc.yy to only signal SQLSTATE conditions.
+ */
+ DBUG_ASSERT(from->has_sql_state());
+ set_sqlstate(from);
+ /* SQLSTATE class "00": illegal, rejected in the parser. */
+ DBUG_ASSERT(m_sqlstate[0] != '0' || get_sqlstate()[1] != '0');
+
+ if (Sql_state::is_warning()) /* SQLSTATE class "01": warning. */
+ {
+ m_level= Sql_condition::WARN_LEVEL_WARN;
+ m_sql_errno= sqlerrno ? sqlerrno : ER_SIGNAL_WARN;
+ }
+ else if (Sql_state::is_not_found()) /* SQLSTATE class "02": not found. */
+ {
+ m_level= Sql_condition::WARN_LEVEL_ERROR;
+ m_sql_errno= sqlerrno ? sqlerrno : ER_SIGNAL_NOT_FOUND;
+ }
+ else /* other SQLSTATE classes : error. */
+ {
+ m_level= Sql_condition::WARN_LEVEL_ERROR;
+ m_sql_errno= sqlerrno ? sqlerrno : ER_SIGNAL_EXCEPTION;
+ }
+}
+
+
+void Sql_condition::assign_defaults(THD *thd, const Sql_state_errno *from)
{
- memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
- m_returned_sqlstate[SQLSTATE_LENGTH]= '\0';
+ if (from)
+ Sql_state_errno_level::assign_defaults(from);
+ if (!get_message_text())
+ set_builtin_message_text(ER(get_sql_errno()));
}
+
Diagnostics_area::Diagnostics_area(bool initialize)
: is_bulk_execution(0), m_main_wi(0, false, initialize)
{
@@ -501,9 +513,7 @@ Diagnostics_area::set_error_status(uint sql_errno,
return;
#endif
- m_sql_errno= sql_errno;
- memcpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH);
- m_sqlstate[SQLSTATE_LENGTH]= '\0';
+ set_condition_value(sql_errno, sqlstate);
strmake_buf(m_message, message);
get_warning_info()->set_error_condition(error_condition);
@@ -695,8 +705,7 @@ void Warning_info::reserve_space(THD *thd, uint count)
}
Sql_condition *Warning_info::push_warning(THD *thd,
- uint sql_errno, const char* sqlstate,
- Sql_condition::enum_warning_level level,
+ const Sql_state_errno_level *value,
const char *msg)
{
Sql_condition *cond= NULL;
@@ -709,11 +718,11 @@ Sql_condition *Warning_info::push_warning(THD *thd,
cond= new (& m_warn_root) Sql_condition(& m_warn_root);
if (cond)
{
- cond->set(sql_errno, sqlstate, level, msg);
+ cond->set(value, msg);
m_warn_list.push_back(cond);
}
}
- m_warn_count[(uint) level]++;
+ m_warn_count[(uint) value->get_level()]++;
}
m_current_statement_warn_count++;
@@ -721,13 +730,11 @@ Sql_condition *Warning_info::push_warning(THD *thd,
}
-Sql_condition *Warning_info::push_warning(THD *thd, const Sql_condition *sql_condition)
+Sql_condition *Warning_info::push_warning(THD *thd,
+ const Sql_condition *sql_condition)
{
- Sql_condition *new_condition= push_warning(thd,
- sql_condition->get_sql_errno(),
- sql_condition->get_sqlstate(),
- sql_condition->get_level(),
- sql_condition->get_message_text());
+ Sql_condition *new_condition= push_warning(thd, sql_condition,
+ sql_condition->get_message_text());
if (new_condition)
new_condition->copy_opt_attributes(sql_condition);
diff --git a/sql/sql_error.h b/sql/sql_error.h
index 3aef5d38368..1fe6d6f1699 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -30,12 +30,119 @@ class my_decimal;
///////////////////////////////////////////////////////////////////////////
-/**
- Representation of a SQL condition.
- A SQL condition can be a completion condition (note, warning),
- or an exception condition (error, not found).
-*/
-class Sql_condition : public Sql_alloc
+class Sql_state
+{
+protected:
+ /**
+ This member is always NUL terminated.
+ */
+ char m_sqlstate[SQLSTATE_LENGTH + 1];
+public:
+ Sql_state()
+ {
+ memset(m_sqlstate, 0, sizeof(m_sqlstate));
+ }
+
+ Sql_state(const char *sqlstate)
+ {
+ set_sqlstate(sqlstate);
+ }
+
+ const char* get_sqlstate() const
+ { return m_sqlstate; }
+
+ void set_sqlstate(const Sql_state *other)
+ {
+ *this= *other;
+ }
+ void set_sqlstate(const char *sqlstate)
+ {
+ memcpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH);
+ m_sqlstate[SQLSTATE_LENGTH]= '\0';
+ }
+ bool eq(const Sql_state *other) const
+ {
+ return strcmp(m_sqlstate, other->m_sqlstate) == 0;
+ }
+
+ bool has_sql_state() const { return m_sqlstate[0] != '\0'; }
+
+ /**
+ Checks if this SQL state defines a WARNING condition.
+ Note: m_sqlstate must contain a valid SQL-state.
+
+ @retval true if this SQL state defines a WARNING condition.
+ @retval false otherwise.
+ */
+ inline bool is_warning() const
+ { return m_sqlstate[0] == '0' && m_sqlstate[1] == '1'; }
+
+
+ /**
+ Checks if this SQL state defines a NOT FOUND condition.
+ Note: m_sqlstate must contain a valid SQL-state.
+
+ @retval true if this SQL state defines a NOT FOUND condition.
+ @retval false otherwise.
+ */
+ inline bool is_not_found() const
+ { return m_sqlstate[0] == '0' && m_sqlstate[1] == '2'; }
+
+
+ /**
+ Checks if this SQL state defines an EXCEPTION condition.
+ Note: m_sqlstate must contain a valid SQL-state.
+
+ @retval true if this SQL state defines an EXCEPTION condition.
+ @retval false otherwise.
+ */
+ inline bool is_exception() const
+ { return m_sqlstate[0] != '0' || m_sqlstate[1] > '2'; }
+
+};
+
+
+class Sql_state_errno: public Sql_state
+{
+protected:
+ /**
+ MySQL extension, MYSQL_ERRNO condition item.
+ SQL error number. One of ER_ codes from share/errmsg.txt.
+ Set by set_error_status.
+ */
+ uint m_sql_errno;
+
+public:
+ Sql_state_errno()
+ :m_sql_errno(0)
+ { }
+ Sql_state_errno(uint sql_errno)
+ :m_sql_errno(sql_errno)
+ { }
+ Sql_state_errno(uint sql_errno, const char *sql_state)
+ :Sql_state(sql_state),
+ m_sql_errno(sql_errno)
+ { }
+ /**
+ Get the SQL_ERRNO of this condition.
+ @return the sql error number condition item.
+ */
+ uint get_sql_errno() const
+ { return m_sql_errno; }
+
+ void set_condition_value(uint sql_errno, const char *sqlstate)
+ {
+ m_sql_errno= sql_errno;
+ set_sqlstate(sqlstate);
+ }
+ void set_condition_value(const Sql_state_errno *other)
+ {
+ *this= *other;
+ }
+};
+
+
+class Sql_state_errno_level: public Sql_state_errno
{
public:
/*
@@ -47,6 +154,41 @@ public:
enum enum_warning_level
{ WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
+protected:
+ /** Severity (error, warning, note) of this condition. */
+ enum_warning_level m_level;
+
+ void assign_defaults(const Sql_state_errno *value);
+
+public:
+ /**
+ Get the error level of this condition.
+ @return the error level condition item.
+ */
+ enum_warning_level get_level() const
+ { return m_level; }
+
+ Sql_state_errno_level()
+ :m_level(WARN_LEVEL_ERROR)
+ { }
+
+ Sql_state_errno_level(uint sqlerrno, const char* sqlstate,
+ enum_warning_level level)
+ :Sql_state_errno(sqlerrno, sqlstate),
+ m_level(level)
+ { }
+};
+
+
+/**
+ Representation of a SQL condition.
+ A SQL condition can be a completion condition (note, warning),
+ or an exception condition (error, not found).
+*/
+class Sql_condition : public Sql_alloc, public Sql_state_errno_level
+{
+public:
+
/**
Convert a bitmask consisting of MYSQL_TIME_{NOTE|WARN}_XXX bits
to WARN_LEVEL_XXX
@@ -69,27 +211,6 @@ public:
*/
int get_message_octet_length() const;
- /**
- Get the SQLSTATE of this condition.
- @return the sql state.
- */
- const char* get_sqlstate() const
- { return m_returned_sqlstate; }
-
- /**
- Get the SQL_ERRNO of this condition.
- @return the sql error number condition item.
- */
- uint get_sql_errno() const
- { return m_sql_errno; }
-
- /**
- Get the error level of this condition.
- @return the error level condition item.
- */
- Sql_condition::enum_warning_level get_level() const
- { return m_level; }
-
private:
/*
The interface of Sql_condition is mostly private, by design,
@@ -144,15 +265,26 @@ private:
/**
Set this condition area with a fixed message text.
- @param thd the current thread.
- @param code the error number for this condition.
- @param str the message text for this condition.
- @param level the error level for this condition.
- @param MyFlags additional flags.
+ @param value - the error number and the sql state for this condition.
+ @param level - the error level for this condition.
+ @param msg - the message text for this condition.
*/
- void set(uint sql_errno, const char* sqlstate,
+ void set(const Sql_state_errno *value,
Sql_condition::enum_warning_level level,
- const char* msg);
+ const char* msg)
+ {
+ DBUG_ASSERT(value->get_sql_errno() != 0);
+ DBUG_ASSERT(value->get_sqlstate() != NULL);
+ DBUG_ASSERT(msg != NULL);
+ set_condition_value(value);
+ set_builtin_message_text(msg);
+ m_level= level;
+ }
+
+ void set(const Sql_state_errno_level *cond, const char* msg)
+ {
+ set(cond, cond->get_level(), msg);
+ }
/**
Set the condition message test.
@@ -161,9 +293,6 @@ private:
*/
void set_builtin_message_text(const char* str);
- /** Set the SQLSTATE of this condition. */
- void set_sqlstate(const char* sqlstate);
-
/** Set the CLASS_ORIGIN of this condition. */
void set_class_origin();
@@ -171,6 +300,14 @@ private:
void set_subclass_origin();
/**
+ Assign the condition items 'MYSQL_ERRNO', 'level' and 'MESSAGE_TEXT'
+ default values of a condition.
+ @param thd - current thread, to access to localized error messages
+ @param from - copy condition items from here (can be NULL)
+ */
+ void assign_defaults(THD *thd, const Sql_state_errno *from);
+
+ /**
Clear this SQL condition.
*/
void clear();
@@ -209,18 +346,6 @@ private:
/** Message text, expressed in the character set implied by --language. */
String m_message_text;
- /** MySQL extension, MYSQL_ERRNO condition item. */
- uint m_sql_errno;
-
- /**
- SQL RETURNED_SQLSTATE condition item.
- This member is always NUL terminated.
- */
- char m_returned_sqlstate[SQLSTATE_LENGTH+1];
-
- /** Severity (error, warning, note) of this condition. */
- Sql_condition::enum_warning_level m_level;
-
/** Pointers for participating in the list of conditions. */
Sql_condition *next_in_wi;
Sql_condition **prev_in_wi;
@@ -475,9 +600,7 @@ private:
@return a pointer to the added SQL-condition.
*/
Sql_condition *push_warning(THD *thd,
- uint sql_errno,
- const char* sqlstate,
- Sql_condition::enum_warning_level level,
+ const Sql_state_errno_level *value,
const char* msg);
/**
@@ -634,7 +757,7 @@ public:
Can not be assigned twice per statement.
*/
-class Diagnostics_area
+class Diagnostics_area: public Sql_state_errno
{
private:
/** The type of the counted and doubly linked list of conditions. */
@@ -722,10 +845,13 @@ public:
{ m_skip_flush= TRUE; }
uint sql_errno() const
- { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
+ {
+ DBUG_ASSERT(m_status == DA_ERROR);
+ return Sql_state_errno::get_sql_errno();
+ }
const char* get_sqlstate() const
- { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
+ { DBUG_ASSERT(m_status == DA_ERROR); return Sql_state::get_sqlstate(); }
ulonglong affected_rows() const
{
@@ -844,9 +970,8 @@ public:
Sql_condition::enum_warning_level level,
const char* msg)
{
- return get_warning_info()->push_warning(thd,
- sql_errno_arg, sqlstate, level,
- msg);
+ Sql_state_errno_level tmp(sql_errno_arg, sqlstate, level);
+ return get_warning_info()->push_warning(thd, &tmp, msg);
}
void mark_sql_conditions_for_removal()
@@ -888,14 +1013,6 @@ private:
char m_message[MYSQL_ERRMSG_SIZE];
/**
- SQL error number. One of ER_ codes from share/errmsg.txt.
- Set by set_error_status.
- */
- uint m_sql_errno;
-
- char m_sqlstate[SQLSTATE_LENGTH+1];
-
- /**
The number of rows affected by the last statement. This is
semantically close to thd->m_row_count_func, but has a different
life cycle. thd->m_row_count_func stores the value returned by
@@ -964,43 +1081,4 @@ inline bool is_sqlstate_completion(const char *s)
{ return s[0] == '0' && s[1] == '0'; }
-/**
- Checks if the specified SQL-state-string defines WARNING condition.
- This function assumes that the given string contains a valid SQL-state.
-
- @param s the condition SQLSTATE.
-
- @retval true if the given string defines WARNING condition.
- @retval false otherwise.
-*/
-inline bool is_sqlstate_warning(const char *s)
-{ return s[0] == '0' && s[1] == '1'; }
-
-
-/**
- Checks if the specified SQL-state-string defines NOT FOUND condition.
- This function assumes that the given string contains a valid SQL-state.
-
- @param s the condition SQLSTATE.
-
- @retval true if the given string defines NOT FOUND condition.
- @retval false otherwise.
-*/
-inline bool is_sqlstate_not_found(const char *s)
-{ return s[0] == '0' && s[1] == '2'; }
-
-
-/**
- Checks if the specified SQL-state-string defines EXCEPTION condition.
- This function assumes that the given string contains a valid SQL-state.
-
- @param s the condition SQLSTATE.
-
- @retval true if the given string defines EXCEPTION condition.
- @retval false otherwise.
-*/
-inline bool is_sqlstate_exception(const char *s)
-{ return s[0] != '0' || s[1] > '2'; }
-
-
#endif // SQL_ERROR_H
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 4765cebc355..86f3958d24d 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -75,69 +75,6 @@ void Set_signal_information::clear()
memset(m_item, 0, sizeof(m_item));
}
-void
-Sql_cmd_common_signal::assign_defaults(Sql_condition *cond,
- bool set_level_code,
- Sql_condition::enum_warning_level level,
- int sqlcode)
-{
- if (set_level_code)
- {
- cond->m_level= level;
- cond->m_sql_errno= sqlcode;
- }
- if (! cond->get_message_text())
- cond->set_builtin_message_text(ER(sqlcode));
-}
-
-void Sql_cmd_common_signal::eval_defaults(THD *thd, Sql_condition *cond)
-{
- DBUG_ASSERT(cond);
-
- const char* sqlstate;
- bool set_defaults= (m_cond != 0);
-
- if (set_defaults)
- {
- /*
- SIGNAL is restricted in sql_yacc.yy to only signal SQLSTATE conditions.
- */
- DBUG_ASSERT(m_cond->has_sql_state());
- sqlstate= m_cond->sql_state;
- cond->set_sqlstate(sqlstate);
- }
- else
- sqlstate= cond->get_sqlstate();
-
- DBUG_ASSERT(sqlstate);
- /* SQLSTATE class "00": illegal, rejected in the parser. */
- DBUG_ASSERT((sqlstate[0] != '0') || (sqlstate[1] != '0'));
-
- if ((sqlstate[0] == '0') && (sqlstate[1] == '1'))
- {
- /* SQLSTATE class "01": warning. */
- assign_defaults(cond, set_defaults,
- Sql_condition::WARN_LEVEL_WARN,
- m_cond && m_cond->mysqlerr ? m_cond->mysqlerr :
- ER_SIGNAL_WARN);
- }
- else if ((sqlstate[0] == '0') && (sqlstate[1] == '2'))
- {
- /* SQLSTATE class "02": not found. */
- assign_defaults(cond, set_defaults,
- Sql_condition::WARN_LEVEL_ERROR,
- m_cond && m_cond->mysqlerr ? m_cond->mysqlerr :
- ER_SIGNAL_NOT_FOUND);
- }
- else
- {
- /* other SQLSTATE classes : error. */
- assign_defaults(cond, set_defaults,
- Sql_condition::WARN_LEVEL_ERROR,
- m_cond && m_cond->mysqlerr ? m_cond->mysqlerr :
- ER_SIGNAL_EXCEPTION);
- }
-}
static bool assign_fixed_string(MEM_ROOT *mem_root,
CHARSET_INFO *dst_cs,
@@ -408,7 +345,7 @@ bool Sql_cmd_common_signal::raise_condition(THD *thd, Sql_condition *cond)
DBUG_ASSERT(thd->lex->query_tables == NULL);
- eval_defaults(thd, cond);
+ cond->assign_defaults(thd, m_cond);
if (eval_signal_informations(thd, cond))
DBUG_RETURN(result);
@@ -491,10 +428,7 @@ bool Sql_cmd_resignal::execute(THD *thd)
}
Sql_condition signaled_err(thd->mem_root);
- signaled_err.set(signaled->sql_errno,
- signaled->sql_state,
- signaled->level,
- signaled->message);
+ signaled_err.set(signaled, signaled->message);
if (m_cond)
{
diff --git a/sql/sql_signal.h b/sql/sql_signal.h
index 2a508eed5bf..4d4601a5ec1 100644
--- a/sql/sql_signal.h
+++ b/sql/sql_signal.h
@@ -40,27 +40,6 @@ protected:
{}
/**
- Assign the condition items 'MYSQL_ERRNO', 'level' and 'MESSAGE_TEXT'
- default values of a condition.
- @param cond the condition to update.
- @param set_level_code true if 'level' and 'MYSQL_ERRNO' needs to be overwritten
- @param level the level to assign
- @param sqlcode the sql code to assign
- */
- static void assign_defaults(Sql_condition *cond,
- bool set_level_code,
- Sql_condition::enum_warning_level level,
- int sqlcode);
-
- /**
- Evaluate the condition items 'SQLSTATE', 'MYSQL_ERRNO', 'level' and 'MESSAGE_TEXT'
- default values for this statement.
- @param thd the current thread.
- @param cond the condition to update.
- */
- void eval_defaults(THD *thd, Sql_condition *cond);
-
- /**
Evaluate each signal condition items for this statement.
@param thd the current thread.
@param cond the condition to update.