Skip to content

Commit

Permalink
MDEV-11037 Diagnostics_area refactoring for user defined exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Barkov committed Apr 5, 2017
1 parent ffca1e4 commit 6010662
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 301 deletions.
19 changes: 9 additions & 10 deletions sql/sp_pcontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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))
{
Expand All @@ -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))
{
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}


Expand Down
48 changes: 13 additions & 35 deletions sql/sp_pcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,8 @@ class sp_label : public Sql_alloc
/// 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
{
Expand All @@ -146,44 +142,30 @@ class sp_condition_value : public Sql_alloc
/// 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.
Expand All @@ -192,8 +174,6 @@ class sp_condition_value : public Sql_alloc
///
/// @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'; }
};

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -532,13 +512,11 @@ class sp_pcontext : public Sql_alloc
/// 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;

/////////////////////////////////////////////////////////////////////////
Expand Down
12 changes: 3 additions & 9 deletions sql/sp_rcontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
}
}
Expand All @@ -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;
Expand Down
17 changes: 2 additions & 15 deletions sql/sp_rcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,9 @@ class sp_rcontext : public Sql_alloc
/// 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;

Expand All @@ -141,12 +132,8 @@ class sp_rcontext : public Sql_alloc
/// @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());
}
};
Expand Down
83 changes: 45 additions & 38 deletions sql/sql_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -709,25 +718,23 @@ 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++;
return cond;
}


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);
Expand Down

0 comments on commit 6010662

Please sign in to comment.