diff options
author | unknown <jimw@mysql.com> | 2005-03-31 19:17:45 -0800 |
---|---|---|
committer | unknown <jimw@mysql.com> | 2005-03-31 19:17:45 -0800 |
commit | e7332e64ca5ef7208846488935a2249285212f91 (patch) | |
tree | 046d9ad3bbf129292636ad08e19e842f8417d8a0 /libmysqld/emb_qcache.h | |
parent | ab77d7d7633a2cff057b17ec43233d4f0d0b0822 (diff) | |
download | mariadb-git-e7332e64ca5ef7208846488935a2249285212f91.tar.gz |
Fix crash in embedded server due to incorrect storage of results
in the query cache. (Bug #9549)
libmysqld/emb_qcache.h:
Fix Querycache_stream::use_next_block() to actually use the next
block and mark blocks as used when it writes to them.
mysql-test/r/query_cache.result:
Update results.
mysql-test/t/query_cache.test:
Add new regression test.
libmysqld/emb_qcache.cc:
Fix calls to use_next_block() to indicate whether we are writing
to the next block or not.
sql/sql_cache.cc:
Initialize the first block properly when storing a result in
the embedded server.
Diffstat (limited to 'libmysqld/emb_qcache.h')
-rw-r--r-- | libmysqld/emb_qcache.h | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h index 32ce19847ff..6201058ce56 100644 --- a/libmysqld/emb_qcache.h +++ b/libmysqld/emb_qcache.h @@ -22,22 +22,43 @@ class Querycache_stream uint headers_len; public: #ifndef DBUG_OFF + Query_cache_block *first_block; uint stored_size; #endif Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) : block(ini_block), headers_len(ini_headers_len) { - use_next_block(); + cur_data= ((byte*)block)+headers_len; + data_end= cur_data + (block->used-headers_len); #ifndef DBUG_OFF + first_block= ini_block; stored_size= 0; #endif } - void use_next_block() + void use_next_block(bool writing) { + /* + This shouldn't be called if there is only one block, or to loop + around to the first block again. That means we're trying to write + more data than we allocated space for. + */ + DBUG_ASSERT(block->next != block); + DBUG_ASSERT(block->next != first_block); + + block= block->next; + /* + While writing, update the type of each block as we write to it. + While reading, make sure that the block is of the expected type. + */ + if (writing) + block->type= Query_cache_block::RES_CONT; + else + DBUG_ASSERT(block->type == Query_cache_block::RES_CONT); + cur_data= ((byte*)block)+headers_len; data_end= cur_data + (block->used-headers_len); } - + void store_char(char c); void store_short(ushort s); void store_int(uint i); |