summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc99
1 files changed, 62 insertions, 37 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 24f3cc66c6b..d4c96ebc535 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -380,16 +380,18 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
XXX: fix this nasty upcast from List<Item_param> to List<Item>
*/
error= my_net_write(net, buff, sizeof(buff));
- if (stmt->param_count && ! error)
+ if (stmt->param_count && likely(!error))
{
error= thd->protocol_text.send_result_set_metadata((List<Item> *)
&stmt->lex->param_list,
Protocol::SEND_EOF);
}
- if (!error)
+ if (likely(!error))
+ {
/* Flag that a response has already been sent */
thd->get_stmt_da()->disable_status();
+ }
DBUG_RETURN(error);
}
@@ -427,7 +429,7 @@ static bool send_prep_stmt(Prepared_statement *stmt,
static ulong get_param_length(uchar **packet, ulong len)
{
- reg1 uchar *pos= *packet;
+ uchar *pos= *packet;
if (len < 1)
return 0;
if (*pos < 251)
@@ -1528,7 +1530,7 @@ static int mysql_test_select(Prepared_statement *stmt,
It is not SELECT COMMAND for sure, so setup_tables will be called as
usual, and we pass 0 as setup_tables_done_option
*/
- if (unit->prepare(thd, 0, 0))
+ if (unit->prepare(unit->derived, 0, 0))
goto error;
if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare())
{
@@ -1699,7 +1701,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
thd->lex->used_tables= 0; // Updated by setup_fields
/* Calls JOIN::prepare */
- DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));
+ DBUG_RETURN(lex->unit.prepare(lex->unit.derived, 0, setup_tables_done_option));
}
/**
@@ -2202,6 +2204,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode,
lex->ident.str,
lex->insert_list,
+ lex->ha_rkey_mode,
lex->select_lex.where)))
DBUG_RETURN(1);
@@ -2500,8 +2503,28 @@ static bool check_prepared_statement(Prepared_statement *stmt)
break;
}
if (res == 0)
- DBUG_RETURN(stmt->is_sql_prepare() ?
- FALSE : (send_prep_stmt(stmt, 0) || thd->protocol->flush()));
+ {
+ if (!stmt->is_sql_prepare())
+ {
+ if (lex->describe || lex->analyze_stmt)
+ {
+ if (!lex->result &&
+ !(lex->result= new (stmt->mem_root) select_send(thd)))
+ DBUG_RETURN(TRUE);
+ List<Item> field_list;
+ thd->prepare_explain_fields(lex->result, &field_list,
+ lex->describe, lex->analyze_stmt);
+ res= send_prep_stmt(stmt, lex->result->field_count(field_list)) ||
+ lex->result->send_result_set_metadata(field_list,
+ Protocol::SEND_EOF);
+ }
+ else
+ res= send_prep_stmt(stmt, 0);
+ if (!res)
+ thd->protocol->flush();
+ }
+ DBUG_RETURN(FALSE);
+ }
error:
DBUG_RETURN(TRUE);
}
@@ -3530,7 +3553,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
#else
param->set_longdata(thd->extra_data, thd->extra_length);
#endif
- if (thd->get_stmt_da()->is_error())
+ if (unlikely(thd->get_stmt_da()->is_error()))
{
stmt->state= Query_arena::STMT_ERROR;
stmt->last_errno= thd->get_stmt_da()->sql_errno();
@@ -3576,7 +3599,7 @@ bool Select_fetch_protocol_binary::send_eof()
Don't send EOF if we're in error condition (which implies we've already
sent or are sending an error)
*/
- if (thd->is_error())
+ if (unlikely(thd->is_error()))
return true;
::my_eof(thd);
@@ -3662,7 +3685,7 @@ Execute_sql_statement::execute_server_code(THD *thd)
error= parse_sql(thd, &parser_state, NULL) || thd->is_error();
- if (error)
+ if (unlikely(error))
goto end;
thd->lex->set_trg_event_type_for_tables();
@@ -3673,7 +3696,7 @@ Execute_sql_statement::execute_server_code(THD *thd)
thd->m_statement_psi= parent_locker;
/* report error issued during command execution */
- if (error == 0 && thd->spcont == NULL)
+ if (likely(error == 0) && thd->spcont == NULL)
general_log_write(thd, COM_STMT_EXECUTE,
thd->query(), thd->query_length());
@@ -3888,7 +3911,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (! (lex= new (mem_root) st_lex_local))
DBUG_RETURN(TRUE);
- stmt_lex= lex;
+ lex->stmt_lex= lex;
if (set_db(&thd->db))
DBUG_RETURN(TRUE);
@@ -3925,9 +3948,9 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex_start(thd);
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE;
- error= parse_sql(thd, & parser_state, NULL) ||
- thd->is_error() ||
- init_param_array(this);
+ error= (parse_sql(thd, & parser_state, NULL) ||
+ thd->is_error() ||
+ init_param_array(this));
lex->set_trg_event_type_for_tables();
@@ -3959,10 +3982,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
Item_null objects.
*/
- if (error == 0)
+ if (likely(error == 0))
error= check_prepared_statement(this);
- if (error)
+ if (unlikely(error))
{
/*
let the following code know we're not in PS anymore,
@@ -4001,7 +4024,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
- if (error == 0)
+ if (likely(error == 0))
{
setup_set_params();
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
@@ -4131,7 +4154,7 @@ Prepared_statement::execute_loop(String *expanded_query,
DBUG_ASSERT(thd->free_list == NULL);
/* Check if we got an error when sending long data */
- if (state == Query_arena::STMT_ERROR)
+ if (unlikely(state == Query_arena::STMT_ERROR))
{
my_message(last_errno, last_error, MYF(0));
return TRUE;
@@ -4174,7 +4197,7 @@ reexecute:
if (WSREP_ON)
{
- mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+ mysql_mutex_lock(&thd->LOCK_thd_data);
switch (thd->wsrep_conflict_state)
{
case CERT_FAILURE:
@@ -4191,12 +4214,13 @@ reexecute:
default:
break;
}
- mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
}
#endif /* WITH_WSREP */
- if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
- error && !thd->is_fatal_error && !thd->killed &&
+ if (unlikely(error) &&
+ (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
+ !thd->is_fatal_error && !thd->killed &&
reprepare_observer.is_invalidated() &&
reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
{
@@ -4205,7 +4229,7 @@ reexecute:
error= reprepare();
- if (! error) /* Success */
+ if (likely(!error)) /* Success */
goto reexecute;
}
reset_stmt_params(this);
@@ -4218,7 +4242,7 @@ my_bool bulk_parameters_set(THD *thd)
DBUG_ENTER("bulk_parameters_set");
Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param;
- if (stmt && stmt->set_bulk_parameters(FALSE))
+ if (stmt && unlikely(stmt->set_bulk_parameters(FALSE)))
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
@@ -4369,7 +4393,7 @@ reexecute:
if (WSREP_ON)
{
- mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+ mysql_mutex_lock(&thd->LOCK_thd_data);
switch (thd->wsrep_conflict_state)
{
case CERT_FAILURE:
@@ -4386,12 +4410,13 @@ reexecute:
default:
break;
}
- mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
}
#endif /* WITH_WSREP */
- if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
- error && !thd->is_fatal_error && !thd->killed &&
+ if (unlikely(error) &&
+ (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
+ !thd->is_fatal_error && !thd->killed &&
reprepare_observer.is_invalidated() &&
reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
{
@@ -4400,7 +4425,7 @@ reexecute:
error= reprepare();
- if (! error) /* Success */
+ if (likely(!error)) /* Success */
goto reexecute;
}
}
@@ -4475,8 +4500,8 @@ Prepared_statement::reprepare()
status_var_increment(thd->status_var.com_stmt_reprepare);
- if (mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name, TRUE,
- &cur_db_changed))
+ if (unlikely(mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name,
+ TRUE, &cur_db_changed)))
return TRUE;
sql_mode_t save_sql_mode= thd->variables.sql_mode;
@@ -4489,7 +4514,7 @@ Prepared_statement::reprepare()
if (cur_db_changed)
mysql_change_db(thd, (LEX_CSTRING*) &saved_cur_db_name, TRUE);
- if (! error)
+ if (likely(!error))
{
swap_prepared_statement(&copy);
swap_parameter_array(param_array, copy.param_array, param_count);
@@ -4788,7 +4813,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (state == Query_arena::STMT_PREPARED && !qc_executed)
state= Query_arena::STMT_EXECUTED;
- if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
+ if (likely(error == 0) && this->lex->sql_command == SQLCOM_CALL)
{
if (is_sql_prepare())
{
@@ -4823,7 +4848,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
sub-statements inside stored procedures are not logged into
the general log.
*/
- if (error == 0 && thd->spcont == NULL)
+ if (likely(error == 0 && thd->spcont == NULL))
general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
error:
@@ -4851,7 +4876,7 @@ bool Prepared_statement::execute_immediate(const char *query, uint query_len)
set_sql_prepare();
name= execute_immediate_stmt_name; // for DBUG_PRINT etc
- if (prepare(query, query_len))
+ if (unlikely(prepare(query, query_len)))
DBUG_RETURN(true);
if (param_count != thd->lex->prepared_stmt_params.elements)
@@ -5224,7 +5249,7 @@ Protocol_local::store_string(const char *str, size_t length,
src_cs != &my_charset_bin &&
dst_cs != &my_charset_bin)
{
- if (convert->copy(str, length, src_cs, dst_cs, &error_unused))
+ if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused)))
return TRUE;
str= convert->ptr();
length= convert->length();