summaryrefslogtreecommitdiff
path: root/mysql-test/t/query_cache_merge.test
diff options
context:
space:
mode:
authorDavi Arnaut <davi@mysql.com>2008-06-03 10:59:46 -0300
committerDavi Arnaut <davi@mysql.com>2008-06-03 10:59:46 -0300
commit2100ec9ec91642e214cb043aac3a728a018d5b15 (patch)
tree5e4fb5dd04c964dcb1ed564b47919b829218e146 /mysql-test/t/query_cache_merge.test
parent8d7fcad1967a08a1d4dda5f6084f35c4f8ae2a93 (diff)
downloadmariadb-git-2100ec9ec91642e214cb043aac3a728a018d5b15.tar.gz
Bug#33362: Query cache invalidation (truncate) may hang
if cached query uses many tables The problem was that query cache would not properly cache queries which used 256 or more tables but yet would leave behind query cache blocks pointing to freed (destroyed) data. Later when invalidating (due to a truncate) query cache would attempt to grab a lock which resided in the freed data, leading to hangs or undefined behavior. This was happening due to a improper return value from the function responsible for registering the tables used in the query (so the cache can be invalidated later if one of the tables is modified). The function expected a return value of type boolean (char, 8 bits) indicating success (1) or failure (0) but the number of tables registered (unsigned int, 32 bits) was being returned instead. This caused the function to return failure for cases where it had actually succeed because when a type (unsigned int) is converted to a narrower type (char), the excess bits on the left are discarded. Thus if the 8 rightmost bits are zero, the return value will be 0 (failure). The solution is to simply return true (1) only if the number of registered table is greater than zero and false (0) otherwise. mysql-test/r/query_cache_merge.result: Add test case result for Bug#33362 mysql-test/t/query_cache_merge.test: Add test case for Bug#33362 sql/sql_cache.cc: Return 1 or 0 depending on the number of registered tables.
Diffstat (limited to 'mysql-test/t/query_cache_merge.test')
-rw-r--r--mysql-test/t/query_cache_merge.test58
1 files changed, 58 insertions, 0 deletions
diff --git a/mysql-test/t/query_cache_merge.test b/mysql-test/t/query_cache_merge.test
index 5247d29a83c..4e25bc3ed14 100644
--- a/mysql-test/t/query_cache_merge.test
+++ b/mysql-test/t/query_cache_merge.test
@@ -48,3 +48,61 @@ SET @@global.query_cache_size=0;
set @@global.table_definition_cache=@save_table_definition_cache;
# End of 4.1 tests
+
+#
+# Bug#33362: Query cache invalidation (truncate) may hang if cached query uses many tables
+#
+
+SET @save_table_definition_cache = @@global.table_definition_cache;
+SET @@global.table_definition_cache = 512;
+
+let $c= 255;
+
+while ($c)
+{
+ eval CREATE TABLE t$c (a INT);
+ eval INSERT INTO t$c VALUES ($c);
+ dec $c;
+}
+
+let $c= 254;
+let $str= t255;
+
+while ($c)
+{
+ let $str= t$c,$str;
+ dec $c;
+}
+
+eval CREATE TABLE t0 (a INT) ENGINE=MERGE UNION($str);
+SET GLOBAL query_cache_size = 1048576;
+FLUSH STATUS;
+SELECT a FROM t0 WHERE a = 1;
+SHOW STATUS LIKE "Qcache_queries_in_cache";
+
+let $c= 255;
+let $i= 1;
+
+while ($c)
+{
+ eval TRUNCATE TABLE t$c;
+ eval SELECT a FROM t$i;
+ dec $c;
+ inc $i;
+}
+
+SELECT a FROM t0;
+DROP TABLE t0;
+
+let $c= 255;
+
+while ($c)
+{
+ eval DROP TABLE t$c;
+ dec $c;
+}
+
+SET @@global.query_cache_size = 0;
+SET @@global.table_definition_cache = @save_table_definition_cache;
+
+--echo End of 5.1 tests