diff options
author | Michael Widenius <monty@askmonty.org> | 2009-10-14 15:58:53 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2009-10-14 15:58:53 +0300 |
commit | daccf1748344e011267ad3f0f093c49c6530d050 (patch) | |
tree | ce464eb370e989b1ba3c6edc2dfc96444791fc13 /sql/sql_prepare.cc | |
parent | 115f4b275a640fc46dd295cc8654e995a91a3885 (diff) | |
parent | 75a949fb414f8b3ed851a466d84788085c9dbe42 (diff) | |
download | mariadb-git-daccf1748344e011267ad3f0f093c49c6530d050.tar.gz |
Merge with 5.1
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 427402133d2..5fee201dcd2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -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); |