mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MWL#182: Explain running statements: merge with 5.3-main
This commit is contained in:
131
sql/sql_class.cc
131
sql/sql_class.cc
@ -965,6 +965,7 @@ void THD::init(void)
|
||||
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
|
||||
debug_sync_init_thread(this);
|
||||
#endif /* defined(ENABLED_DEBUG_SYNC) */
|
||||
apc_target.init();
|
||||
}
|
||||
|
||||
|
||||
@ -1128,7 +1129,8 @@ void THD::cleanup(void)
|
||||
pthread_mutex_unlock(&LOCK_user_locks);
|
||||
ull= NULL;
|
||||
}
|
||||
|
||||
|
||||
apc_target.destroy();
|
||||
cleanup_done=1;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -1732,6 +1734,19 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
|
||||
int THD::send_explain_fields(select_result *result)
|
||||
{
|
||||
List<Item> field_list;
|
||||
make_explain_field_list(field_list);
|
||||
return (result->send_fields(field_list,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Populate the provided field_list with EXPLAIN output columns.
|
||||
this->lex->describe has the EXPLAIN flags
|
||||
*/
|
||||
|
||||
void THD::make_explain_field_list(List<Item> &field_list)
|
||||
{
|
||||
Item *item;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
|
||||
@ -1769,10 +1784,9 @@ int THD::send_explain_fields(select_result *result)
|
||||
}
|
||||
item->maybe_null= 1;
|
||||
field_list.push_back(new Item_empty_string("Extra", 255, cs));
|
||||
return (result->send_fields(field_list,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
|
||||
}
|
||||
|
||||
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
void THD::close_active_vio()
|
||||
{
|
||||
@ -1876,6 +1890,21 @@ void THD::rollback_item_tree_changes()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if the thread has been killed, and also process "APC requests"
|
||||
|
||||
@retval true The thread is killed, execution should be interrupted
|
||||
@retval false Not killed, continue execution
|
||||
*/
|
||||
|
||||
bool THD::check_killed()
|
||||
{
|
||||
if (killed)
|
||||
return TRUE;
|
||||
apc_target.process_apc_requests();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Functions to provide a interface to select results
|
||||
*****************************************************************************/
|
||||
@ -2016,6 +2045,68 @@ int select_send::send_data(List<Item> &items)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int select_result_explain_buffer::send_data(List<Item> &items)
|
||||
{
|
||||
List_iterator_fast<Item> li(items);
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String buffer(buff, sizeof(buff), &my_charset_bin);
|
||||
DBUG_ENTER("select_send::send_data");
|
||||
|
||||
protocol->prepare_for_resend();
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->send(protocol, &buffer))
|
||||
{
|
||||
protocol->free(); // Free used buffer
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
break;
|
||||
}
|
||||
/*
|
||||
Reset buffer to its original state, as it may have been altered in
|
||||
Item::send().
|
||||
*/
|
||||
buffer.set(buff, sizeof(buff), &my_charset_bin);
|
||||
}
|
||||
//TODO: do we need the following:
|
||||
if (thd->is_error())
|
||||
{
|
||||
protocol->remove_last_row();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
/* psergey-TODO: instead of protocol->write(), steal the packet here */
|
||||
const char *packet_data;
|
||||
size_t len;
|
||||
protocol->get_packet(&packet_data, &len);
|
||||
|
||||
String *s= new (thd->mem_root) String;
|
||||
s->append(packet_data, len);
|
||||
data_rows.push_back(s);
|
||||
protocol->remove_last_row(); // <-- this does nothing. Do we need it?
|
||||
// prepare_for_resend() will wipe out the packet
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void select_result_explain_buffer::flush_data()
|
||||
{
|
||||
List_iterator<String> it(data_rows);
|
||||
String *str;
|
||||
while ((str= it++))
|
||||
{
|
||||
/* TODO: write out the lines. */
|
||||
protocol->set_packet(str->ptr(), str->length());
|
||||
protocol->write();
|
||||
delete str;
|
||||
}
|
||||
data_rows.empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
bool select_send::send_eof()
|
||||
{
|
||||
/*
|
||||
@ -2889,6 +2980,10 @@ void THD::end_statement()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Start using arena specified by @set. Current arena data will be saved to
|
||||
*backup.
|
||||
*/
|
||||
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
|
||||
{
|
||||
DBUG_ENTER("THD::set_n_backup_active_arena");
|
||||
@ -2903,6 +2998,12 @@ void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Stop using the temporary arena, and start again using the arena that is
|
||||
specified in *backup.
|
||||
The temporary arena is returned back into *set.
|
||||
*/
|
||||
|
||||
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
|
||||
{
|
||||
DBUG_ENTER("THD::restore_active_arena");
|
||||
@ -2915,6 +3016,30 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Produce EXPLAIN data.
|
||||
|
||||
This function is APC-scheduled to be run in the context of the thread that
|
||||
we're producing EXPLAIN for.
|
||||
*/
|
||||
|
||||
void Show_explain_request::get_explain_data(void *arg)
|
||||
{
|
||||
Show_explain_request *req= (Show_explain_request*)arg;
|
||||
//TODO: change mem_root to point to request_thd->mem_root.
|
||||
// Actually, change the ARENA, because we're going to allocate items!
|
||||
Query_arena backup_arena;
|
||||
req->target_thd->set_n_backup_active_arena((Query_arena*)req->request_thd,
|
||||
&backup_arena);
|
||||
|
||||
req->target_thd->lex->unit.print_explain(req->explain_buf);
|
||||
|
||||
req->target_thd->restore_active_arena((Query_arena*)req->request_thd,
|
||||
&backup_arena);
|
||||
}
|
||||
|
||||
|
||||
Statement::~Statement()
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user