Structure for storing parameters of query in query cache (asked by Bar)

parent d62eaa78
...@@ -322,6 +322,13 @@ typedef compare_func_creator (*chooser_compare_func_creator)(bool invert); ...@@ -322,6 +322,13 @@ typedef compare_func_creator (*chooser_compare_func_creator)(bool invert);
#include "opt_range.h" #include "opt_range.h"
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
struct Query_cache_query_flags
{
unsigned int client_long_flag:1;
uint charset_num;
ha_rows limit;
};
#define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags)
#include "sql_cache.h" #include "sql_cache.h"
#define query_cache_store_query(A, B) query_cache.store_query(A, B) #define query_cache_store_query(A, B) query_cache.store_query(A, B)
#define query_cache_destroy() query_cache.destroy() #define query_cache_destroy() query_cache.destroy()
...@@ -335,6 +342,7 @@ typedef compare_func_creator (*chooser_compare_func_creator)(bool invert); ...@@ -335,6 +342,7 @@ typedef compare_func_creator (*chooser_compare_func_creator)(bool invert);
#define query_cache_invalidate_by_MyISAM_filename_ref \ #define query_cache_invalidate_by_MyISAM_filename_ref \
&query_cache_invalidate_by_MyISAM_filename &query_cache_invalidate_by_MyISAM_filename
#else #else
#define QUERY_CACHE_FLAGS_SIZE 0
#define query_cache_store_query(A, B) #define query_cache_store_query(A, B)
#define query_cache_destroy() #define query_cache_destroy()
#define query_cache_result_size_limit(A) #define query_cache_result_size_limit(A)
......
...@@ -765,7 +765,13 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) ...@@ -765,7 +765,13 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
&tables_type))) &tables_type)))
{ {
NET *net= &thd->net; NET *net= &thd->net;
byte flags= (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0); Query_cache_query_flags flags;
// fill all gaps between fields with 0 to get repeatable key
bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ?
1 : 0);
flags.charset_num= thd->charset()->number;
flags.limit= thd->variables.select_limit;
STRUCT_LOCK(&structure_guard_mutex); STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size == 0) if (query_cache_size == 0)
...@@ -792,23 +798,19 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) ...@@ -792,23 +798,19 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
{ {
DBUG_PRINT("qcache", ("No active database")); DBUG_PRINT("qcache", ("No active database"));
} }
tot_length= thd->query_length + thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE;
/* /*
Prepare flags: We should only copy structure (don't use it location directly)
most significant bit - CLIENT_LONG_FLAG, because of alignment issue
other - charset number (0 no charset convertion)
*/ */
flags|= (byte) thd->charset()->number; memcpy((void *)(thd->query + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
DBUG_ASSERT(thd->charset()->number < 128); &flags, QUERY_CACHE_FLAGS_SIZE);
tot_length= thd->query_length+thd->db_length+2+sizeof(ha_rows);
thd->query[tot_length-1]= (char) flags;
memcpy((void *)(thd->query + (tot_length-sizeof(ha_rows)-1)),
(const void *)&thd->variables.select_limit, sizeof(ha_rows));
/* Check if another thread is processing the same query? */ /* Check if another thread is processing the same query? */
Query_cache_block *competitor = (Query_cache_block *) Query_cache_block *competitor = (Query_cache_block *)
hash_search(&queries, (byte*) thd->query, tot_length); hash_search(&queries, (byte*) thd->query, tot_length);
DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor, DBUG_PRINT("qcache", ("competitor 0x%lx", (ulong) competitor));
flags));
if (competitor == 0) if (competitor == 0)
{ {
/* Query is not in cache and no one is working with it; Store it */ /* Query is not in cache and no one is working with it; Store it */
...@@ -895,7 +897,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -895,7 +897,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_block *first_result_block, *result_block; Query_cache_block *first_result_block, *result_block;
Query_cache_block_table *block_table, *block_table_end; Query_cache_block_table *block_table, *block_table_end;
ulong tot_length; ulong tot_length;
byte flags; Query_cache_query_flags flags;
bool check_tables; bool check_tables;
DBUG_ENTER("Query_cache::send_result_to_client"); DBUG_ENTER("Query_cache::send_result_to_client");
...@@ -932,7 +934,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -932,7 +934,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
} }
Query_cache_block *query_block; Query_cache_block *query_block;
tot_length= query_length+thd->db_length+2+sizeof(ha_rows); tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
if (thd->db_length) if (thd->db_length)
{ {
memcpy(sql+query_length+1, thd->db, thd->db_length); memcpy(sql+query_length+1, thd->db, thd->db_length);
...@@ -943,17 +945,15 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -943,17 +945,15 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{ {
DBUG_PRINT("qcache", ("No active database")); DBUG_PRINT("qcache", ("No active database"));
} }
/*
prepare flags: // fill all gaps between fields with 0 to get repeatable key
Most significant bit - CLIENT_LONG_FLAG, bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
Other - charset number (0 no charset convertion) flags.client_long_flag= (thd->client_capabilities & CLIENT_LONG_FLAG ?
*/ 1 : 0);
flags= (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0); flags.charset_num= thd->charset()->number;
flags|= (byte) thd->charset()->number; flags.limit= thd->variables.select_limit;
DBUG_ASSERT(thd->charset()->number < 128); memcpy((void *)(sql + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
sql[tot_length-1]= (char) flags; &flags, QUERY_CACHE_FLAGS_SIZE);
memcpy((void *)(sql + (tot_length-sizeof(ha_rows)-1)),
(const void *)&thd->variables.select_limit, sizeof(ha_rows));
query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql, query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
tot_length); tot_length);
/* Quick abort on unlocked data */ /* Quick abort on unlocked data */
...@@ -3097,20 +3097,21 @@ void Query_cache::queries_dump() ...@@ -3097,20 +3097,21 @@ void Query_cache::queries_dump()
{ {
uint len; uint len;
char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0); char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0);
len--; // Point at flags len-= QUERY_CACHE_FLAGS_SIZE; // Point at flags
uint flags = (uint) (uchar) str[len]; Query_cache_query_flags flags;
str[len]=0; memcpy(&flags, str+len, QUERY_CACHE_FLAGS_SIZE);
DBUG_PRINT("qcache", ("%u (%u,%u) '%s' '%s'", str[len]= 0; // make zero ending DB name
((flags & QUERY_CACHE_CLIENT_LONG_FLAG_MASK)? 1:0), DBUG_PRINT("qcache", ("F:%u C:%u L:%lu (%u) '%s' '%s'",
(flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len, flags.client_long_flag,
str,strend(str)+1)); flags.charset_num, (ulong)flags.limit,
len, str, strend(str)+1));
DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block, DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block,
(ulong) block->next, (ulong) block->prev, (ulong) block->next, (ulong) block->prev,
(ulong)block->pnext, (ulong)block->pprev)); (ulong)block->pnext, (ulong)block->pprev));
str[len]=(char) flags; memcpy(str + len, &flags, QUERY_CACHE_FLAGS_SIZE); // restore flags
for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++) for (TABLE_COUNTER_TYPE t= 0; t < block->n_tables; t++)
{ {
Query_cache_table *table = block->table(t)->parent; Query_cache_table *table= block->table(t)->parent;
DBUG_PRINT("qcache", ("-t- '%s' '%s'", table->db(), table->table())); DBUG_PRINT("qcache", ("-t- '%s' '%s'", table->db(), table->table()));
} }
Query_cache_query *header = block->query(); Query_cache_query *header = block->query();
......
...@@ -1591,8 +1591,8 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) ...@@ -1591,8 +1591,8 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
/* We must allocate some extra memory for query cache */ /* We must allocate some extra memory for query cache */
if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
packet_length, packet_length,
thd->db_length+2+ thd->db_length+ 1 +
sizeof(ha_rows)))) QUERY_CACHE_FLAGS_SIZE)))
return 1; return 1;
thd->query[packet_length]=0; thd->query[packet_length]=0;
thd->query_length= packet_length; thd->query_length= packet_length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment