mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merge MySQL->MariaDB
* Finished Monty and Jani's merge * Some InnoDB tests still fail (because it's old xtradb code run against newer testsuite). They are expected to go after mergning with the latest xtradb.
This commit is contained in:
@@ -127,12 +127,12 @@ class Prepared_statement: public Statement
|
||||
public:
|
||||
enum flag_values
|
||||
{
|
||||
IS_IN_USE= 1
|
||||
IS_IN_USE= 1,
|
||||
IS_SQL_PREPARE= 2
|
||||
};
|
||||
|
||||
THD *thd;
|
||||
Select_fetch_protocol_binary result;
|
||||
Protocol *protocol;
|
||||
Item_param **param_array;
|
||||
uint param_count;
|
||||
uint last_errno;
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
List<LEX_STRING>& varnames,
|
||||
String *expanded_query);
|
||||
public:
|
||||
Prepared_statement(THD *thd_arg, Protocol *protocol_arg);
|
||||
Prepared_statement(THD *thd_arg);
|
||||
virtual ~Prepared_statement();
|
||||
void setup_set_params();
|
||||
virtual Query_arena::Type type() const;
|
||||
@@ -156,7 +156,8 @@ public:
|
||||
bool set_name(LEX_STRING *name);
|
||||
inline void close_cursor() { delete cursor; cursor= 0; }
|
||||
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
||||
inline bool is_protocol_text() const { return protocol == &thd->protocol_text; }
|
||||
inline bool is_sql_prepare() const { return flags & (uint) IS_SQL_PREPARE; }
|
||||
void set_sql_prepare() { flags|= (uint) IS_SQL_PREPARE; }
|
||||
bool prepare(const char *packet, uint packet_length);
|
||||
bool execute_loop(String *expanded_query,
|
||||
bool open_cursor,
|
||||
@@ -716,9 +717,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
||||
prepared statement, parameter markers are replaced with variable names.
|
||||
Example:
|
||||
@verbatim
|
||||
mysql_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
|
||||
mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?")
|
||||
--> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?"
|
||||
mysql_stmt_execute(stmt);
|
||||
mysqld_stmt_execute(stmt);
|
||||
--> general and binary logs get
|
||||
[Execute] UPDATE t1 SET a*1.25 WHERE a=1"
|
||||
@endverbatim
|
||||
@@ -1360,7 +1361,7 @@ static int mysql_test_select(Prepared_statement *stmt,
|
||||
*/
|
||||
if (unit->prepare(thd, 0, 0))
|
||||
goto error;
|
||||
if (!lex->describe && !stmt->is_protocol_text())
|
||||
if (!lex->describe && !stmt->is_sql_prepare())
|
||||
{
|
||||
/* Make copy of item list, as change_columns may change it */
|
||||
List<Item> fields(lex->select_lex.item_list);
|
||||
@@ -1992,7 +1993,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
DBUG_RETURN(stmt->is_protocol_text() ?
|
||||
DBUG_RETURN(stmt->is_sql_prepare() ?
|
||||
FALSE : (send_prep_stmt(stmt, 0) || thd->protocol->flush()));
|
||||
error:
|
||||
DBUG_RETURN(TRUE);
|
||||
@@ -2060,18 +2061,19 @@ static bool init_param_array(Prepared_statement *stmt)
|
||||
to the client, otherwise an error message is set in THD.
|
||||
*/
|
||||
|
||||
void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
||||
void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
||||
{
|
||||
Protocol *save_protocol= thd->protocol;
|
||||
Prepared_statement *stmt;
|
||||
bool error;
|
||||
DBUG_ENTER("mysql_stmt_prepare");
|
||||
DBUG_ENTER("mysqld_stmt_prepare");
|
||||
|
||||
DBUG_PRINT("prep_query", ("%s", packet));
|
||||
|
||||
/* First of all clear possible warnings from the previous command */
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
|
||||
if (! (stmt= new Prepared_statement(thd, &thd->protocol_binary)))
|
||||
if (! (stmt= new Prepared_statement(thd)))
|
||||
DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
|
||||
|
||||
if (thd->stmt_map.insert(thd, stmt))
|
||||
@@ -2088,6 +2090,8 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
||||
sp_cache_flush_obsolete(&thd->sp_proc_cache);
|
||||
sp_cache_flush_obsolete(&thd->sp_func_cache);
|
||||
|
||||
thd->protocol= &thd->protocol_binary;
|
||||
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
|
||||
|
||||
@@ -2101,6 +2105,9 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
|
||||
/* Statement map deletes statement on erase */
|
||||
thd->stmt_map.erase(stmt);
|
||||
}
|
||||
|
||||
thd->protocol= save_protocol;
|
||||
|
||||
/* check_prepared_statemnt sends the metadata packet in case of success */
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@@ -2231,10 +2238,8 @@ void mysql_sql_stmt_prepare(THD *thd)
|
||||
LEX_STRING *name= &lex->prepared_stmt_name;
|
||||
Prepared_statement *stmt;
|
||||
const char *query;
|
||||
uint query_len;
|
||||
uint query_len= 0;
|
||||
DBUG_ENTER("mysql_sql_stmt_prepare");
|
||||
LINT_INIT(query_len);
|
||||
DBUG_ASSERT(thd->protocol == &thd->protocol_text);
|
||||
|
||||
if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
|
||||
{
|
||||
@@ -2252,11 +2257,13 @@ void mysql_sql_stmt_prepare(THD *thd)
|
||||
}
|
||||
|
||||
if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
|
||||
! (stmt= new Prepared_statement(thd, &thd->protocol_text)))
|
||||
! (stmt= new Prepared_statement(thd)))
|
||||
{
|
||||
DBUG_VOID_RETURN; /* out of memory */
|
||||
}
|
||||
|
||||
stmt->set_sql_prepare();
|
||||
|
||||
/* Set the name first, insert should know that this statement has a name */
|
||||
if (stmt->set_name(name))
|
||||
{
|
||||
@@ -2427,7 +2434,7 @@ static void reset_stmt_params(Prepared_statement *stmt)
|
||||
client, otherwise an error message is set in THD.
|
||||
*/
|
||||
|
||||
void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
{
|
||||
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
@@ -2436,8 +2443,9 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
String expanded_query;
|
||||
uchar *packet_end= packet + packet_length;
|
||||
Prepared_statement *stmt;
|
||||
Protocol *save_protocol= thd->protocol;
|
||||
bool open_cursor;
|
||||
DBUG_ENTER("mysql_stmt_execute");
|
||||
DBUG_ENTER("mysqld_stmt_execute");
|
||||
|
||||
packet+= 9; /* stmt_id + 5 bytes of flags */
|
||||
|
||||
@@ -2448,7 +2456,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
{
|
||||
char llbuf[22];
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||
llstr(stmt_id, llbuf), "mysql_stmt_execute");
|
||||
llstr(stmt_id, llbuf), "mysqld_stmt_execute");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@@ -2463,7 +2471,12 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
|
||||
open_cursor= test(flags & (ulong) CURSOR_TYPE_READ_ONLY);
|
||||
|
||||
thd->protocol= &thd->protocol_binary;
|
||||
stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end);
|
||||
thd->protocol= save_protocol;
|
||||
|
||||
/* Close connection socket; for use with client testing (Bug#43560). */
|
||||
DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@@ -2525,7 +2538,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
||||
@param packet_length Length of packet
|
||||
*/
|
||||
|
||||
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
{
|
||||
/* assume there is always place for 8-16 bytes */
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
@@ -2533,7 +2546,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
Prepared_statement *stmt;
|
||||
Statement stmt_backup;
|
||||
Server_side_cursor *cursor;
|
||||
DBUG_ENTER("mysql_stmt_fetch");
|
||||
DBUG_ENTER("mysqld_stmt_fetch");
|
||||
|
||||
/* First of all clear possible warnings from the previous command */
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
@@ -2542,7 +2555,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
{
|
||||
char llbuf[22];
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||
llstr(stmt_id, llbuf), "mysql_stmt_fetch");
|
||||
llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@@ -2583,9 +2596,9 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
|
||||
This function resets statement to the state it was right after prepare.
|
||||
It can be used to:
|
||||
- clear an error happened during mysql_stmt_send_long_data
|
||||
- clear an error happened during mysqld_stmt_send_long_data
|
||||
- cancel long data stream for all placeholders without
|
||||
having to call mysql_stmt_execute.
|
||||
having to call mysqld_stmt_execute.
|
||||
- close an open cursor
|
||||
Sends 'OK' packet in case of success (statement was reset)
|
||||
or 'ERROR' packet (unrecoverable error/statement not found/etc).
|
||||
@@ -2594,12 +2607,12 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
|
||||
@param packet Packet with stmt id
|
||||
*/
|
||||
|
||||
void mysql_stmt_reset(THD *thd, char *packet)
|
||||
void mysqld_stmt_reset(THD *thd, char *packet)
|
||||
{
|
||||
/* There is always space for 4 bytes in buffer */
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
Prepared_statement *stmt;
|
||||
DBUG_ENTER("mysql_stmt_reset");
|
||||
DBUG_ENTER("mysqld_stmt_reset");
|
||||
|
||||
/* First of all clear possible warnings from the previous command */
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
@@ -2609,7 +2622,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
||||
{
|
||||
char llbuf[22];
|
||||
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
|
||||
llstr(stmt_id, llbuf), "mysql_stmt_reset");
|
||||
llstr(stmt_id, llbuf), "mysqld_stmt_reset");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@@ -2617,7 +2630,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
||||
|
||||
/*
|
||||
Clear parameters from data which could be set by
|
||||
mysql_stmt_send_long_data() call.
|
||||
mysqld_stmt_send_long_data() call.
|
||||
*/
|
||||
reset_stmt_params(stmt);
|
||||
|
||||
@@ -2638,12 +2651,12 @@ void mysql_stmt_reset(THD *thd, char *packet)
|
||||
we don't send any reply to this command.
|
||||
*/
|
||||
|
||||
void mysql_stmt_close(THD *thd, char *packet)
|
||||
void mysqld_stmt_close(THD *thd, char *packet)
|
||||
{
|
||||
/* There is always space for 4 bytes in packet buffer */
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
Prepared_statement *stmt;
|
||||
DBUG_ENTER("mysql_stmt_close");
|
||||
DBUG_ENTER("mysqld_stmt_close");
|
||||
|
||||
thd->main_da.disable_status();
|
||||
|
||||
@@ -2742,7 +2755,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
|
||||
stmt->state= Query_arena::ERROR;
|
||||
stmt->last_errno= ER_WRONG_ARGUMENTS;
|
||||
sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS),
|
||||
"mysql_stmt_send_long_data");
|
||||
"mysqld_stmt_send_long_data");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif
|
||||
@@ -2815,12 +2828,11 @@ Select_fetch_protocol_binary::send_data(List<Item> &fields)
|
||||
Prepared_statement
|
||||
****************************************************************************/
|
||||
|
||||
Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
|
||||
Prepared_statement::Prepared_statement(THD *thd_arg)
|
||||
:Statement(NULL, &main_mem_root,
|
||||
INITIALIZED, ++thd_arg->statement_id_counter),
|
||||
thd(thd_arg),
|
||||
result(thd_arg),
|
||||
protocol(protocol_arg),
|
||||
param_array(0),
|
||||
param_count(0),
|
||||
last_errno(0),
|
||||
@@ -3166,7 +3178,7 @@ Prepared_statement::set_parameters(String *expanded_query,
|
||||
if (res)
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0),
|
||||
is_sql_ps ? "EXECUTE" : "mysql_stmt_execute");
|
||||
is_sql_ps ? "EXECUTE" : "mysqld_stmt_execute");
|
||||
reset_stmt_params(this);
|
||||
}
|
||||
return res;
|
||||
@@ -3289,7 +3301,9 @@ Prepared_statement::reprepare()
|
||||
bool cur_db_changed;
|
||||
bool error;
|
||||
|
||||
Prepared_statement copy(thd, &thd->protocol_text);
|
||||
Prepared_statement copy(thd);
|
||||
|
||||
copy.set_sql_prepare(); /* To suppress sending metadata to the client. */
|
||||
|
||||
status_var_increment(thd->status_var.com_stmt_reprepare);
|
||||
|
||||
@@ -3347,7 +3361,7 @@ bool Prepared_statement::validate_metadata(Prepared_statement *copy)
|
||||
return FALSE -- the metadata of the original SELECT,
|
||||
if any, has not been sent to the client.
|
||||
*/
|
||||
if (is_protocol_text() || lex->describe)
|
||||
if (is_sql_prepare() || lex->describe)
|
||||
return FALSE;
|
||||
|
||||
if (lex->select_lex.item_list.elements !=
|
||||
@@ -3410,7 +3424,6 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
|
||||
DBUG_ASSERT(thd == copy->thd);
|
||||
last_error[0]= '\0';
|
||||
last_errno= 0;
|
||||
/* Do not swap protocols, the copy always has protocol_text */
|
||||
}
|
||||
|
||||
|
||||
@@ -3551,8 +3564,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
||||
thd->stmt_arena= this;
|
||||
reinit_stmt_before_use(thd, lex);
|
||||
|
||||
thd->protocol= protocol; /* activate stmt protocol */
|
||||
|
||||
/* Go! */
|
||||
|
||||
if (open_cursor)
|
||||
@@ -3583,8 +3594,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
||||
if (cur_db_changed)
|
||||
mysql_change_db(thd, &saved_cur_db_name, TRUE);
|
||||
|
||||
thd->protocol= &thd->protocol_text; /* use normal protocol */
|
||||
|
||||
/* Assert that if an error, no cursor is open */
|
||||
DBUG_ASSERT(! (error && cursor));
|
||||
|
||||
@@ -3621,11 +3630,11 @@ error:
|
||||
}
|
||||
|
||||
|
||||
/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
|
||||
/** Common part of DEALLOCATE PREPARE and mysqld_stmt_close. */
|
||||
|
||||
void Prepared_statement::deallocate()
|
||||
{
|
||||
/* We account deallocate in the same manner as mysql_stmt_close */
|
||||
/* We account deallocate in the same manner as mysqld_stmt_close */
|
||||
status_var_increment(thd->status_var.com_stmt_close);
|
||||
/* Statement map calls delete stmt on erase */
|
||||
thd->stmt_map.erase(this);
|
||||
|
||||
Reference in New Issue
Block a user