2778 Konstantin Osipov 2008-11-27
WL#4264, review comments, implement Server_runnable.
modified:
sql/mysql_priv.h
sql/protocol.h
sql/si_objects.cc
sql/sql_prepare.cc
2777 Alexander Nozdrin 2008-11-27 [merge]
Pull from 6.0-runtime
modified:
mysql-test/r/auto_commit_basic.result
mysql-test/r/automatic_sp_privileges_basic.result
mysql-test/r/big_tables_basic.result
mysql-test/r/engine_condition_pushdown_basic.result
mysql-test/r/flush_basic.result
mysql-test/r/foreign_key_checks_basic.result
mysql-test/r/func_math.result
mysql-test/r/func_str.result
mysql-test/r/general_log_basic.result
mysql-test/r/innodb_checksums_basic.result
mysql-test/r/innodb_doublewrite_basic.result
mysql-test/r/innodb_file_per_table_basic.result
mysql-test/r/innodb_locks_unsafe_for_binlog_basic.result
mysql-test/r/innodb_rollback_on_timeout_basic.result
mysql-test/r/innodb_support_xa_basic.result
mysql-test/r/innodb_table_locks_basic.result
mysql-test/r/keep_files_on_create_basic.result
mysql-test/r/local_infile_basic.result
mysql-test/r/log_bin_trust_function_creators_basic.result
mysql-test/r/log_queries_not_using_indexes_basic.result
mysql-test/r/low_priority_updates_basic.result
mysql-test/r/myisam_use_mmap_basic.result
mysql-test/r/new_basic.result
mysql-test/r/old_passwords_basic.result
mysql-test/r/profiling.result
mysql-test/r/ps_1general.result
mysql-test/r/query_cache_wlock_invalidate_basic.result
mysql-test/r/read_only_basic.result
mysql-test/r/relay_log_purge_basic.result
mysql-test/r/rpl_slave_allow_batching_basic.result
mysql-test/r/rpl_slave_compressed_protocol_basic.result
mysql-test/r/secure_auth_basic.result
mysql-test/r/slow_query_log_basic.result
mysql-test/r/sp-vars.result
mysql-test/r/sql_auto_is_null_basic.result
mysql-test/r/sql_big_selects_basic.result
mysql-test/r/sql_big_tables_basic.result
mysql-test/r/sql_buffer_result_basic.result
mysql-test/r/sql_log_bin_basic.result
mysql-test/r/sql_log_off_basic.result
mysql-test/r/sql_low_priority_updates_basic.result
mysql-test/r/sql_notes_basic.result
mysql-test/r/sql_quote_show_create_basic.result
mysql-test/r/sql_safe_updates_basic.result
mysql-test/r/sql_warnings_basic.result
mysql-test/r/sync_frm_basic.result
mysql-test/r/timed_mutexes_basic.result
mysql-test/r/type_varchar.result
mysql-test/r/unique_checks_basic.result
mysql-test/suite/falcon/r/falcon_bugs.result
mysql-test/suite/falcon/t/falcon_bugs.test
mysql-test/suite/funcs_1/r/falcon_func_view.result
mysql-test/suite/funcs_1/r/falcon_views.result
mysql-test/suite/funcs_1/r/innodb_func_view.result
mysql-test/suite/funcs_1/r/innodb_views.result
mysql-test/suite/funcs_1/r/memory_func_view.result
mysql-test/suite/funcs_1/r/memory_views.result
mysql-test/suite/funcs_1/r/myisam_func_view.result
mysql-test/suite/funcs_1/r/myisam_views.result
mysql-test/suite/funcs_1/r/ndb_func_view.result
mysql-test/suite/funcs_1/r/ndb_views.result
mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test
mysql-test/t/auto_commit_basic.test
mysql-test/t/automatic_sp_privileges_basic.test
mysql-test/t/big_tables_basic.test
mysql-test/t/engine_condition_pushdown_basic.test
mysql-test/t/flush_basic.test
mysql-test/t/foreign_key_checks_basic.test
mysql-test/t/general_log_basic.test
mysql-test/t/innodb_checksums_basic.test
mysql-test/t/innodb_doublewrite_basic.test
mysql-test/t/innodb_file_per_table_basic.test
mysql-test/t/innodb_locks_unsafe_for_binlog_basic.test
mysql-test/t/innodb_rollback_on_timeout_basic.test
mysql-test/t/innodb_support_xa_basic.test
mysql-test/t/innodb_table_locks_basic.test
mysql-test/t/keep_files_on_create_basic.test
mysql-test/t/local_infile_basic.test
mysql-test/t/log_bin_trust_function_creators_basic.test
mysql-test/t/log_queries_not_using_indexes_basic.test
mysql-test/t/low_priority_updates_basic.test
mysql-test/t/myisam_use_mmap_basic.test
mysql-test/t/new_basic.test
mysql-test/t/old_passwords_basic.test
mysql-test/t/query_cache_wlock_invalidate_basic.test
mysql-test/t/read_only_basic.test
mysql-test/t/relay_log_purge_basic.test
mysql-test/t/rpl_slave_allow_batching_basic.test
mysql-test/t/rpl_slave_compressed_protocol_basic.test
mysql-test/t/secure_auth_basic.test
mysql-test/t/slow_query_log_basic.test
mysql-test/t/sp-vars.test
mysql-test/t/sql_auto_is_null_basic.test
mysql-test/t/sql_big_selects_basic.test
mysql-test/t/sql_big_tables_basic.test
mysql-test/t/sql_buffer_result_basic.test
mysql-test/t/sql_log_bin_basic.test
mysql-test/t/sql_log_off_basic.test
mysql-test/t/sql_low_priority_updates_basic.test
mysql-test/t/sql_notes_basic.test
mysql-test/t/sql_quote_show_create_basic.test
mysql-test/t/sql_safe_updates_basic.test
mysql-test/t/sql_warnings_basic.test
mysql-test/t/sync_frm_basic.test
mysql-test/t/timed_mutexes_basic.test
mysql-test/t/type_varchar.test
mysql-test/t/unique_checks_basic.test
sql/event_scheduler.cc
sql/events.cc
sql/field.cc
sql/sp_head.cc
sql/sql_acl.cc
sql/sql_base.cc
sql/sql_connect.cc
sql/sql_db.cc
sql/sql_parse.cc
sql/sql_plugin.cc
sql/sql_servers.cc
sql/sql_udf.cc
sql/table.cc
sql/tztime.cc
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-11-24 23:00:01 +0000
+++ b/sql/mysql_priv.h 2008-11-27 18:31:59 +0000
@@ -1138,8 +1138,24 @@ pthread_handler_t handle_bootstrap(void
int mysql_execute_command(THD *thd);
class Ed_result;
+/**
+ Execute a fragment of server code in an isolated context, so that
+ it doesn't leave any effect on THD. THD must have no open tables.
+ The code must not leave any open tables around.
+ The result of execution (if any) is stored in Ed_result.
+*/
+
+class Server_runnable
+{
+public:
+ virtual bool execute_server_code(THD *thd)= 0;
+ virtual LEX_STRING get_slow_log_info();
+ virtual ~Server_runnable();
+};
bool mysql_execute_direct(THD *thd, LEX_STRING query, Ed_result *result);
+bool mysql_execute_direct(THD *thd, Server_runnable *ed_runnable,
+ Ed_result *result);
bool do_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
=== modified file 'sql/protocol.h'
--- a/sql/protocol.h 2008-11-24 23:00:01 +0000
+++ b/sql/protocol.h 2008-11-27 18:31:59 +0000
@@ -266,6 +266,7 @@ private:
Ed_column -- a class representing a column data in a row. Used with
Ed_row and Protocol_local.
*/
+
class Ed_column : public LEX_STRING, public Sql_alloc
{
public:
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2008-11-26 13:46:42 +0000
+++ b/sql/si_objects.cc 2008-11-27 18:31:59 +0000
@@ -98,54 +98,52 @@ run_service_interface_sql(THD *thd, cons
struct Table_name_key
{
-public:
- static uchar *get_key(const uchar *record,
- size_t *key_length,
- my_bool not_used __attribute__((unused)));
-
- static void delete_key(void *data);
-
-public:
- Table_name_key(const char *db_name_str,
- uint db_name_length,
- const char *table_name_str,
- uint table_name_length)
- {
- db_name.copy(db_name_str, db_name_length, system_charset_info);
- table_name.copy(table_name_str, table_name_length, system_charset_info);
+ LEX_STRING db_name;
+ LEX_STRING table_name;
+ LEX_STRING key;
+ void init_from_mdl_key(const char *key_arg, size_t key_length_arg,
+ char *key_buff_arg);
+};
- key.length(0);
- key.append(db_name);
- key.append(".");
- key.append(table_name);
- }
-public:
- String db_name;
- String table_name;
+void
+Table_name_key::init_from_mdl_key(const char *key_arg, size_t key_length_arg,
+ char *key_buff_arg)
+{
+ key.str= key_buff_arg;
+ key.length= key_length_arg - 4; /* Skip MDL object type */
+ memcpy(key.str, key_arg + 4, key.length);
- String key;
-};
+ db_name.str= key.str;
+ db_name.length= strlen(db_name.str);
+ table_name.str= db_name.str + db_name.length + 1; /* Skip \0 */
+ table_name.length= strlen(table_name.str);
+}
///////////////////////////////////////////////////////////////////////////
+extern "C" {
-uchar *Table_name_key::get_key(const uchar *record,
- size_t *key_length,
- my_bool not_used __attribute__((unused)))
+uchar *
+get_table_name_key(const uchar *record,
+ size_t *key_length,
+ my_bool not_used __attribute__((unused)))
{
- Table_name_key *tnk= (Table_name_key *) record;
- *key_length= tnk->key.length();
- return (uchar *) tnk->key.c_ptr_safe();
+ Table_name_key *table_name_key= (Table_name_key *) record;
+ *key_length= table_name_key->key.length;
+ return (uchar *) table_name_key->key.str;
}
///////////////////////////////////////////////////////////////////////////
-void Table_name_key::delete_key(void *data)
+static void
+free_table_name_key(void *data)
{
- Table_name_key *tnk= (Table_name_key *) data;
- delete tnk;
+ Table_name_key *table_name_key= (Table_name_key *) data;
+ my_free(table_name_key, MYF(0));
}
+} // end of extern "C"
+
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
@@ -1261,6 +1259,10 @@ public:
public:
virtual Obj *next();
+ enum enum_base_obj_kind { BASE_TABLE= 0, VIEW };
+
+ virtual enum_base_obj_kind get_base_obj_kind() const= 0;
+
protected:
template <typename Iterator>
static Iterator *create(THD *thd,
@@ -1269,11 +1271,11 @@ protected:
protected:
bool init(THD *thd, const String *db_name, const String *view_name);
- virtual bool is_obj_accepted(TABLE_LIST *obj)= 0;
- virtual Obj *create_obj(const String *db_name, const String *obj_name)= 0;
+ virtual Obj *create_obj(const LEX_STRING *db_name,
+ const LEX_STRING *obj_name)= 0;
private:
- HASH *m_table_names;
+ HASH m_table_names;
uint m_cur_idx;
};
@@ -1297,92 +1299,138 @@ Iterator *View_base_obj_iterator::create
///////////////////////////////////////////////////////////////////////////
-View_base_obj_iterator::View_base_obj_iterator() :
- m_table_names(NULL),
- m_cur_idx(0)
+View_base_obj_iterator::View_base_obj_iterator()
+ :m_cur_idx(0)
{
+ hash_init(&m_table_names, system_charset_info, 16, 0, 0,
+ get_table_name_key, free_table_name_key,
+ MYF(0));
+
}
///////////////////////////////////////////////////////////////////////////
View_base_obj_iterator::~View_base_obj_iterator()
{
- if (!m_table_names)
- return;
-
- hash_free(m_table_names);
- delete m_table_names;
+ hash_free(&m_table_names);
}
-///////////////////////////////////////////////////////////////////////////
-bool View_base_obj_iterator::init(THD *thd,
- const String *db_name,
- const String *view_name)
+/**
+ Find all base tables or views of a view.
+*/
+
+class Find_view_underlying_tables: public Server_runnable
{
- /* Ensure that init() will not be run twice. */
- DBUG_ASSERT(!m_table_names);
+public:
+ Find_view_underlying_tables(const View_base_obj_iterator *base_obj_it,
+ HASH *table_names,
+ const String *db_name,
+ const String *view_name);
- uint not_used; /* Passed to open_tables(). Not used. */
- THD *my_thd= new THD();
+ bool execute_server_code(THD *thd);
+private:
+ /* Store the resulting unique here */
+ const View_base_obj_iterator *m_base_obj_it;
+ HASH *m_table_names;
+ const String *m_db_name;
+ const String *m_view_name;
+};
- my_thd->security_ctx= thd->security_ctx;
- my_thd->thread_stack= (char*) &my_thd;
- my_thd->store_globals();
- lex_start(my_thd);
-
- TABLE_LIST *tl =
- sp_add_to_query_tables(my_thd,
- my_thd->lex,
- ((String *) db_name)->c_ptr_safe(),
- ((String *) view_name)->c_ptr_safe(),
- TL_READ);
-
- if (open_tables(my_thd, &tl, ¬_used, MYSQL_OPEN_SKIP_TEMPORARY))
- {
- close_thread_tables(my_thd);
- delete my_thd;
- thd->store_globals();
+Find_view_underlying_tables::
+Find_view_underlying_tables(const View_base_obj_iterator *base_obj_it,
+ HASH *table_names,
+ const String *db_name,
+ const String *view_name)
+ :m_base_obj_it(base_obj_it),
+ m_table_names(table_names),
+ m_db_name(db_name),
+ m_view_name(view_name)
+{
+}
- return TRUE;
- }
- m_table_names = new HASH();
+bool
+Find_view_underlying_tables::execute_server_code(THD *thd)
+{
+ bool res= TRUE;
+ uint counter_not_used; /* Passed to open_tables(). Not used. */
- hash_init(m_table_names, system_charset_info, 16, 0, 0,
- Table_name_key::get_key,
- Table_name_key::delete_key,
- MYF(0));
+ TABLE_LIST *table_list;
+
+ DBUG_ENTER("Find_view_underlying_tables::execute_server_code");
+
+ table_list= sp_add_to_query_tables(thd, thd->lex,
+ ((String *) m_db_name)->c_ptr_safe(),
+ ((String *) m_view_name)->c_ptr_safe(),
+ TL_READ);
- if (tl->view_tables)
+ if (table_list == NULL) /* out of memory, reported */
+ DBUG_RETURN(TRUE);
+
+ if (open_tables(thd, &table_list, &counter_not_used,
+ MYSQL_OPEN_SKIP_TEMPORARY))
+ goto end;
+
+ if (table_list->view_tables)
{
- List_iterator_fast<TABLE_LIST> it(*tl->view_tables);
- TABLE_LIST *tl2;
+ TABLE_LIST *table;
+ List_iterator_fast<TABLE_LIST> it(*table_list->view_tables);
- while ((tl2 = it++))
+ /*
+ Iterate over immediate underlying tables.
+ The list doesn't include views or tables referenced indirectly,
+ through other views, or stored functions or triggers.
+ */
+ while ((table= it++))
{
- Table_name_key *tnk=
- new Table_name_key(tl2->db, tl2->db_length,
- tl2->table_name, tl2->table_name_length);
-
- if (!is_obj_accepted(tl2) ||
- hash_search(m_table_names,
- (uchar *) tnk->key.c_ptr_safe(),
- tnk->key.length()))
- {
- delete tnk;
+ Table_name_key *table_name_key;
+ char *key_buff;
+
+ /* If we expect a view, and it's a table, or vice versa, continue */
+ if ((int) m_base_obj_it->get_base_obj_kind() != test(table->view))
continue;
- }
- my_hash_insert(m_table_names, (uchar *) tnk);
+ if (! my_multi_malloc(MYF(MY_WME),
+ &table_name_key, sizeof(*table_name_key),
+ &key_buff, table->mdl_lock_data->key_length,
+ NullS))
+ goto end;
+
+ table_name_key->init_from_mdl_key(table->mdl_lock_data->key,
+ table->mdl_lock_data->key_length,
+ key_buff);
+
+ if (my_hash_insert(m_table_names, (uchar*) table_name_key))
+ {
+ my_free(table_name_key, MYF(0));
+ goto end;
+ }
}
}
+ res= FALSE;
+ my_ok(thd);
+
+end:
+ close_thread_tables(thd);
+ DBUG_RETURN(res);
+}
+
+///////////////////////////////////////////////////////////////////////////
- close_thread_tables(my_thd);
- delete my_thd;
+bool View_base_obj_iterator::init(THD *thd,
+ const String *db_name,
+ const String *view_name)
+{
+ Find_view_underlying_tables find_tables(this, &m_table_names,
+ db_name, view_name);
+ Ed_result ed_result; /* Just to grab OK or ERROR */
+
+ if (mysql_execute_direct(thd, &find_tables, &ed_result))
+ return TRUE;
- thd->store_globals();
+ /* The table list is filled with unique underlying table names. */
return FALSE;
}
@@ -1391,15 +1439,15 @@ bool View_base_obj_iterator::init(THD *t
Obj *View_base_obj_iterator::next()
{
- if (m_cur_idx >= m_table_names->records)
+ if (m_cur_idx >= m_table_names.records)
return NULL;
- Table_name_key *tnk=
- (Table_name_key *) hash_element(m_table_names, m_cur_idx);
+ Table_name_key *table_name_key=
+ (Table_name_key *) hash_element(&m_table_names, m_cur_idx);
++m_cur_idx;
- return create_obj(&tnk->db_name, &tnk->table_name);
+ return create_obj(&table_name_key->db_name, &table_name_key->table_name);
}
///////////////////////////////////////////////////////////////////////////
@@ -1416,12 +1464,12 @@ public:
}
protected:
- virtual bool is_obj_accepted(TABLE_LIST *obj)
- { return !obj->view; }
+ virtual enum_base_obj_kind get_base_obj_kind() const { return BASE_TABLE; }
- virtual Obj *create_obj(const String *db_name, const String *obj_name)
+ virtual Obj *create_obj(const LEX_STRING *db_name,
+ const LEX_STRING *obj_name)
{
- return new Table_obj(db_name->lex_string(), obj_name->lex_string());
+ return new Table_obj(*db_name, *obj_name);
}
};
@@ -1447,12 +1495,12 @@ public:
}
protected:
- virtual bool is_obj_accepted(TABLE_LIST *obj)
- { return obj->view; }
+ virtual enum_base_obj_kind get_base_obj_kind() const { return VIEW; }
- virtual Obj *create_obj(const String *db_name, const String *obj_name)
+ virtual Obj *create_obj(const LEX_STRING *db_name,
+ const LEX_STRING *obj_name)
{
- return new View_obj(db_name->lex_string(), obj_name->lex_string());
+ return new View_obj(*db_name, *obj_name);
}
};
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2008-11-24 23:00:01 +0000
+++ b/sql/sql_prepare.cc 2008-11-27 18:31:59 +0000
@@ -162,7 +162,7 @@ public:
bool execute_loop(String *expanded_query,
bool open_cursor,
uchar *packet_arg, uchar *packet_end_arg);
- bool execute_immediate(const char *stmt, uint length);
+ bool execute_server_runnable(Server_runnable *server_runnable);
/* Destroy this statement */
void deallocate();
private:
@@ -184,6 +184,20 @@ private:
};
+/**
+*/
+
+class Execute_sql_statement: public Server_runnable
+{
+public:
+ Execute_sql_statement(LEX_STRING sql_text);
+ virtual bool execute_server_code(THD *thd);
+ virtual LEX_STRING get_slow_log_info();
+private:
+ LEX_STRING m_sql_text;
+ LEX_STRING m_slow_log_info;
+};
+
/******************************************************************************
Implementation
******************************************************************************/
@@ -2764,6 +2778,54 @@ void mysql_stmt_get_longdata(THD *thd, c
}
+bool
+mysql_execute_direct(THD *thd, LEX_STRING query, Ed_result *ed_result)
+{
+ Execute_sql_statement execute_sql_statement(query);
+
+ return mysql_execute_direct(thd, &execute_sql_statement, ed_result);
+}
+
+
+/**
+ Execute a fragment of server functionality without an effect on
+ thd, and store results in Ed_result.
+
+ @param thd Thread handle.
+ @param server_runnable A code fragment to execute.
+ @param ed_result Result interceptor
+*/
+
+bool
+mysql_execute_direct(THD *thd, Server_runnable *server_runnable,
+ Ed_result *ed_result)
+{
+ Protocol_local protocol_local(thd, ed_result);
+ Prepared_statement stmt(thd);
+
+ DBUG_ENTER("mysql_execute_direct");
+
+ DBUG_ASSERT(ed_result);
+
+ Protocol *protocol_saved= thd->protocol;
+
+ thd->protocol= &protocol_local;
+
+ ed_result->begin_statement(thd);
+ bool rc= stmt.execute_server_runnable(server_runnable);
+ ed_result->end_statement(thd);
+
+ thd->protocol->end_statement();
+
+ thd->protocol= protocol_saved;
+
+ thd->main_da.reset_diagnostics_area();
+
+ DBUG_RETURN(rc);
+}
+
+
+
/***************************************************************************
Select_fetch_protocol_binary
****************************************************************************/
@@ -2809,6 +2871,78 @@ Select_fetch_protocol_binary::send_data(
return rc;
}
+/*******************************************************************
+*
+*******************************************************************/
+
+Server_runnable::~Server_runnable()
+{
+}
+
+
+LEX_STRING
+Server_runnable::get_slow_log_info()
+{
+ return null_lex_str;
+}
+///////////////////////////////////////////////////////////////////////////
+
+Execute_sql_statement::
+Execute_sql_statement(LEX_STRING sql_text)
+ :m_sql_text(sql_text)
+{}
+
+LEX_STRING
+Execute_sql_statement::get_slow_log_info()
+{
+ return m_slow_log_info;
+}
+
+
+/**
+ Parse and execute a statement. Does not prepare the query.
+
+ Allows to execute a statement from within another statement.
+ The main property of the implementation is that it does not
+ affect the environment -- i.e. you can run many
+ executions without having to cleanup/reset THD in between.
+*/
+
+bool
+Execute_sql_statement::execute_server_code(THD *thd)
+{
+ bool error;
+
+ if (alloc_query(thd, m_sql_text.str, m_sql_text.length))
+ return TRUE;
+
+ m_slow_log_info.str= thd->query;
+ m_slow_log_info.length= thd->query_length;
+
+ Parser_state parser_state(thd, thd->query, thd->query_length);
+
+ parser_state.m_lip.multi_statements= FALSE;
+ lex_start(thd);
+
+ error= parse_sql(thd, &parser_state, NULL) || thd->is_error();
+
+ if (error)
+ goto end;
+
+ thd->lex->set_trg_event_type_for_tables();
+
+ error= mysql_execute_command(thd);
+
+ if (error == 0 && thd->spcont == NULL)
+ general_log_write(thd, COM_STMT_EXECUTE,
+ thd->query, thd->query_length);
+
+end:
+ lex_end(thd->lex);
+
+ return error;
+}
+
/***************************************************************************
Prepared_statement
****************************************************************************/
@@ -3258,123 +3392,34 @@ reexecute:
return error;
}
-/**
- Execute one SQL statement.
-
- @param thd Thread handle.
- @param query Query to execute.
-*/
bool
-mysql_execute_direct(THD *thd, LEX_STRING query, Ed_result *result)
-{
- Protocol_local protocol_local(thd, result);
-
- DBUG_ENTER("mysql_execute_direct");
-
- DBUG_ASSERT(result);
-
- Prepared_statement *stmt= new Prepared_statement(thd);
-
- if (!stmt)
- DBUG_RETURN(TRUE);
-
- Protocol *protocol_saved= thd->protocol;
-
- thd->protocol= &protocol_local;
-
- result->begin_statement(thd);
- bool rc= stmt->execute_immediate(query.str, query.length);
- result->end_statement(thd);
-
- thd->protocol->end_statement();
-
- thd->protocol= protocol_saved;
-
- delete stmt;
-
- thd->main_da.reset_diagnostics_area();
-
- DBUG_RETURN(rc);
-}
-
-
-/**
- Parse and execute a query string. Does not prepare the query.
-
- An implementation of "EXECUTE IMMEDIATE" syntax of Dynamic SQL.
- Allows to execute a statement from within another statement.
- The main property of the implementation is that it does not
- affect the environment -- i.e. you can run many
- ::execute_immediate() without having to cleanup/reset THD in
- between.
-*/
-
-bool
-Prepared_statement::execute_immediate(const char *query, uint length)
+Prepared_statement::execute_server_runnable(Server_runnable *server_runnable)
{
+ LEX_STRING slow_log_stmt;
Statement stmt_backup;
bool error;
state= CONVENTIONAL_EXECUTION;
- if (!(lex = new (mem_root) st_lex_local))
+ if (!(lex= new (mem_root) st_lex_local))
return TRUE;
thd->set_n_backup_statement(this, &stmt_backup);
- if (alloc_query(thd, query, length))
- {
- thd->set_statement(&stmt_backup);
- return TRUE;
- }
- /*
- Expanded query is needed for slow logging, so we want thd->query
- to point at it even after we restore from backup. This is ok, as
- expanded query was allocated in thd->mem_root.
- */
- stmt_backup.query= thd->query;
- stmt_backup.query_length= thd->query_length;
-
- Parser_state parser_state(thd, thd->query, thd->query_length);
-
- parser_state.m_lip.multi_statements= FALSE;
- lex_start(thd);
-
- error= parse_sql(thd, &parser_state, NULL) || thd->is_error();
+ error= server_runnable->execute_server_code(thd);
+ cleanup_stmt();
- if (lex->sql_command == SQLCOM_PREPARE ||
- lex->sql_command == SQLCOM_EXECUTE ||
- (lex->sql_command == SQLCOM_CHANGE_DB && is_sql_prepare()))
- {
- my_error(ER_PS_NO_RECURSION, MYF(0));
- error= 1;
- }
-
- if (error)
- {
- thd->set_statement(&stmt_backup);
- return TRUE;
- }
-
- lex->set_trg_event_type_for_tables();
-
- if (query_cache_send_result_to_client(thd, thd->query,
- thd->query_length) <= 0)
+ slow_log_stmt= server_runnable->get_slow_log_info();
+ if (slow_log_stmt.str)
{
- error= mysql_execute_command(thd);
+ stmt_backup.query= slow_log_stmt.str;
+ stmt_backup.query_length= slow_log_stmt.length;
}
- cleanup_stmt();
- lex_end(thd->lex);
-
thd->set_statement(&stmt_backup);
- if (error == 0 && thd->spcont == NULL)
- general_log_write(thd, COM_STMT_EXECUTE,
- thd->query, thd->query_length);
-
return error;
}
| Thread |
|---|
| • bzr push into mysql-6.0-runtime branch (kostja:2777 to 2778) WL#4264 | Konstantin Osipov | 27 Nov |