diff options
-rw-r--r-- | plugin/qc_info/qc_info.cc | 39 | ||||
-rw-r--r-- | sql/sql_cache.cc | 3 | ||||
-rw-r--r-- | sql/sql_cache.h | 9 |
3 files changed, 42 insertions, 9 deletions
diff --git a/plugin/qc_info/qc_info.cc b/plugin/qc_info/qc_info.cc index 4ccfdc8f8c2..1dcef004447 100644 --- a/plugin/qc_info/qc_info.cc +++ b/plugin/qc_info/qc_info.cc @@ -106,6 +106,9 @@ static ST_FIELD_INFO qc_info_fields[]= {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; + +static const char unknown[]= "#UNKNOWN#"; + static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { @@ -146,7 +149,8 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, query_cache_block_raw = my_hash_element(queries, i); query_cache_block = (Query_cache_block*)query_cache_block_raw; - if (query_cache_block->type != Query_cache_block::QUERY) + if (unlikely(!query_cache_block || + query_cache_block->type != Query_cache_block::QUERY)) continue; query_cache_query = query_cache_block->query(); @@ -169,14 +173,33 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, table->field[COLUMN_GROUP_CONCAT_MAX_LENGTH]->store(flags.group_concat_max_len, 0); cs_client= get_charset(flags.character_set_client_num, MYF(MY_WME)); - table->field[COLUMN_CHARACTER_SET_CLIENT]->store(cs_client->csname, strlen(cs_client->csname), scs); + if (likely(cs_client)) + table->field[COLUMN_CHARACTER_SET_CLIENT]-> + store(cs_client->csname, strlen(cs_client->csname), scs); + else + table->field[COLUMN_CHARACTER_SET_CLIENT]-> + store(STRING_WITH_LEN(unknown), scs); + cs_result= get_charset(flags.character_set_results_num, MYF(MY_WME)); - table->field[COLUMN_CHARACTER_SET_RESULT]->store(cs_result->csname, strlen(cs_result->csname), scs); + if (likely(cs_result)) + table->field[COLUMN_CHARACTER_SET_RESULT]-> + store(cs_result->csname, strlen(cs_result->csname), scs); + else + table->field[COLUMN_CHARACTER_SET_RESULT]-> + store(STRING_WITH_LEN(unknown), scs); + collation= get_charset(flags.collation_connection_num, MYF(MY_WME)); - table->field[COLUMN_COLLATION]->store(collation->name, strlen(collation->name), scs); + if (likely(collation)) + table->field[COLUMN_COLLATION]-> + store(collation->name, strlen(collation->name), scs); + else + table->field[COLUMN_COLLATION]-> store(STRING_WITH_LEN(unknown), scs); tz= flags.time_zone->get_name(); - table->field[COLUMN_TIMEZONE]->store(tz->ptr(), tz->length(), scs); + if (likely(tz)) + table->field[COLUMN_TIMEZONE]->store(tz->ptr(), tz->length(), scs); + else + table->field[COLUMN_TIMEZONE]-> store(STRING_WITH_LEN(unknown), scs); table->field[COLUMN_DEFAULT_WEEK_FORMAT]->store(flags.default_week_format, 0); table->field[COLUMN_DIV_PRECISION_INCREMENT]->store(flags.div_precision_increment, 0); @@ -204,7 +227,8 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, /* If we have result blocks, process them */ first_result_block= query_cache_query->result(); - if(first_result_block) + if(query_cache_query->is_results_ready() && + first_result_block) { /* initialize so we can loop over the result blocks*/ result_block= first_result_block; @@ -231,7 +255,8 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, } table->field[COLUMN_RESULT_BLOCKS_COUNT]->store(result_blocks_count, 0); table->field[COLUMN_RESULT_BLOCKS_SIZE]->store(result_blocks_size, 0); - table->field[COLUMN_RESULT_BLOCKS_SIZE_USED]->store(result_blocks_size_used, 0); + table->field[COLUMN_RESULT_BLOCKS_SIZE_USED]-> + store(result_blocks_size_used, 0); if (schema_table_store_record(thd, table)) goto cleanup; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 91dd8ad7325..c69303c5273 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -961,7 +961,7 @@ inline void Query_cache_query::unlock_reading() void Query_cache_query::init_n_lock() { DBUG_ENTER("Query_cache_query::init_n_lock"); - res=0; wri = 0; len = 0; + res=0; wri = 0; len = 0; ready= 0; mysql_rwlock_init(key_rwlock_query_cache_query_lock, &lock); lock_writing(); DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx", @@ -1226,6 +1226,7 @@ void Query_cache::end_of_result(THD *thd) query_cache.split_block(last_result_block,len); header->found_rows(limit_found_rows); + header->set_results_ready(); // signal for plugin header->result()->type= Query_cache_block::RESULT; /* Drop the writer. */ diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 00ba9bf59d8..657caf4a5bc 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -156,8 +156,9 @@ struct Query_cache_query Query_cache_block *res; Query_cache_tls *wri; ulong len; - uint8 tbls_type; unsigned int last_pkt_nr; + uint8 tbls_type; + uint8 ready; Query_cache_query() {} /* Remove gcc warning */ inline void init_n_lock(); @@ -177,6 +178,12 @@ struct Query_cache_query { return (((uchar*)this) + ALIGN_SIZE(sizeof(Query_cache_query))); } + /** + following used to check if result ready in plugin without + locking rw_lock of the query. + */ + inline void set_results_ready() { ready= 1; } + inline bool is_results_ready() { return ready; } void lock_writing(); void lock_reading(); bool try_lock_writing(); |