diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 155 |
1 files changed, 131 insertions, 24 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f59a848a242..b68a532a2dc 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -351,6 +351,124 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, return thd->strmake(str.ptr(), str.length()); } +/** + Clear this diagnostics area. + + Normally called at the end of a statement. +*/ + +void +Diagnostics_area::reset_diagnostics_area() +{ +#ifdef DBUG_OFF + can_overwrite_status= FALSE; + /** Don't take chances in production */ + m_message[0]= '\0'; + m_sql_errno= 0; + m_server_status= 0; + m_affected_rows= 0; + m_last_insert_id= 0; + m_total_warn_count= 0; +#endif + is_sent= FALSE; + /** Tiny reset in debug mode to see garbage right away */ + m_status= DA_EMPTY; +} + + +/** + Set OK status -- ends commands that do not return a + result set, e.g. INSERT/UPDATE/DELETE. +*/ + +void +Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg, + ulong last_insert_id_arg, + const char *message_arg) +{ + DBUG_ASSERT(! is_set()); +#ifdef DBUG_OFF + /* In production, refuse to overwrite an error with an OK packet. */ + if (is_error()) + return; +#endif + /** Only allowed to report success if has not yet reported an error */ + + m_server_status= thd->server_status; + m_total_warn_count= thd->total_warn_count; + m_affected_rows= affected_rows_arg; + m_last_insert_id= last_insert_id_arg; + if (message_arg) + strmake(m_message, message_arg, sizeof(m_message)); + else + m_message[0]= '\0'; + m_status= DA_OK; +} + + +/** + Set EOF status. +*/ + +void +Diagnostics_area::set_eof_status(THD *thd) +{ + /** Only allowed to report eof if has not yet reported an error */ + + DBUG_ASSERT(! is_set()); +#ifdef DBUG_OFF + /* In production, refuse to overwrite an error with an EOF packet. */ + if (is_error()) + return; +#endif + + m_server_status= thd->server_status; + /* + If inside a stored procedure, do not return the total + number of warnings, since they are not available to the client + anyway. + */ + m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count; + + m_status= DA_EOF; +} + +/** + Set ERROR status. +*/ + +void +Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, + const char *message_arg) +{ + /* + Only allowed to report error if has not yet reported a success + The only exception is when we flush the message to the client, + an error can happen during the flush. + */ + DBUG_ASSERT(! is_set() || can_overwrite_status); + + m_sql_errno= sql_errno_arg; + strmake(m_message, message_arg, sizeof(m_message)); + + m_status= DA_ERROR; +} + + +/** + Mark the diagnostics area as 'DISABLED'. + + This is used in rare cases when the COM_ command at hand sends a response + in a custom format. One example is the query cache, another is + COM_STMT_PREPARE. +*/ + +void +Diagnostics_area::disable_status() +{ + DBUG_ASSERT(! is_set()); + m_status= DA_DISABLED; +} THD::THD() @@ -431,7 +549,6 @@ THD::THD() net.vio=0; #endif client_capabilities= 0; // minimalistic client - net.last_error[0]=0; // If error on boot #ifdef HAVE_QUERY_CACHE query_cache_init_query(&net); // If error on boot #endif @@ -1324,12 +1441,12 @@ void select_send::abort() { DBUG_ENTER("select_send::abort"); if (is_result_set_started && thd->spcont && - thd->spcont->find_handler(thd, thd->net.last_errno, + thd->spcont->find_handler(thd, thd->main_da.sql_errno(), MYSQL_ERROR::WARN_LEVEL_ERROR)) { /* We're executing a stored procedure, have an open result - set, an SQL exception conditiona and a handler for it. + set, an SQL exception condition and a handler for it. In this situation we must abort the current statement, silence the error and start executing the continue/exit handler. @@ -1337,9 +1454,7 @@ void select_send::abort() otherwise the client will hang due to the violation of the client/server protocol. */ - thd->net.report_error= 0; - send_eof(); - thd->net.report_error= 1; // Abort SP + thd->protocol->end_partial_result_set(thd); } DBUG_VOID_RETURN; } @@ -1391,12 +1506,14 @@ bool select_send::send_data(List<Item> &items) } } thd->sent_row_count++; - if (!thd->vio_ok()) - DBUG_RETURN(0); - if (! thd->is_error()) + if (thd->is_error()) + { + protocol->remove_last_row(); + DBUG_RETURN(1); + } + if (thd->vio_ok()) DBUG_RETURN(protocol->write()); - protocol->remove_last_row(); - DBUG_RETURN(1); + DBUG_RETURN(0); } bool select_send::send_eof() @@ -1414,14 +1531,9 @@ bool select_send::send_eof() mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - if (! thd->is_error()) - { - ::send_eof(thd); - is_result_set_started= 0; - return 0; - } - else - return 1; + ::send_eof(thd); + is_result_set_started= 0; + return FALSE; } @@ -2701,7 +2813,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, { backup->options= options; backup->in_sub_stmt= in_sub_stmt; - backup->no_send_ok= net.no_send_ok; backup->enable_slow_log= enable_slow_log; backup->limit_found_rows= limit_found_rows; backup->examined_row_count= examined_row_count; @@ -2732,9 +2843,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, cuted_fields= 0; transaction.savepoints= 0; first_successful_insert_id_in_cur_stmt= 0; - - /* Surpress OK packets in case if we will execute statements */ - net.no_send_ok= TRUE; } @@ -2757,7 +2865,6 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup) transaction.savepoints= backup->savepoints; options= backup->options; in_sub_stmt= backup->in_sub_stmt; - net.no_send_ok= backup->no_send_ok; enable_slow_log= backup->enable_slow_log; first_successful_insert_id_in_prev_stmt= backup->first_successful_insert_id_in_prev_stmt; |