summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-10-21 23:56:12 +0300
committerunknown <bell@sanja.is.com.ua>2004-10-21 23:56:12 +0300
commitb50b1dd3a4b9cf5e4e9a6c33961b007becbda6bc (patch)
treeadba151b89c3f3b0d8b6812947bd34aa47f36a7d
parent0a505ccc080eca79903103d081da8214bcd51d47 (diff)
downloadmariadb-git-b50b1dd3a4b9cf5e4e9a6c33961b007becbda6bc.tar.gz
Check of temporary tables hiding for query fetched from QC (BUG#6084)
mysql-test/r/query_cache.result: hiding real table stored in query cache by temporary table mysql-test/t/query_cache.test: hiding real table stored in query cache by temporary table sql/sql_cache.cc: Check of temporary tables hiding for query fetched from QC sql/sql_cache.h: Key length now stored in table record of query cache
-rw-r--r--mysql-test/r/query_cache.result13
-rw-r--r--mysql-test/t/query_cache.test12
-rw-r--r--sql/sql_cache.cc32
-rw-r--r--sql/sql_cache.h3
4 files changed, 59 insertions, 1 deletions
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index a9e9f167e5f..85fe77b1f10 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -704,4 +704,17 @@ Qcache_queries_in_cache 1
unlock table;
drop table t1,t2;
set query_cache_wlock_invalidate=default;
+CREATE TABLE t1 (id INT PRIMARY KEY);
+insert into t1 values (1),(2),(3);
+select * from t1;
+id
+1
+2
+3
+create temporary table t1 (a int not null auto_increment
+primary key);
+select * from t1;
+a
+drop table t1;
+drop table t1;
set GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 8a07c0a53a0..61fbadde1e1 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -521,4 +521,16 @@ unlock table;
drop table t1,t2;
set query_cache_wlock_invalidate=default;
+#
+# hiding real table stored in query cache by temporary table
+#
+CREATE TABLE t1 (id INT PRIMARY KEY);
+insert into t1 values (1),(2),(3);
+select * from t1;
+create temporary table t1 (a int not null auto_increment
+primary key);
+select * from t1;
+drop table t1;
+drop table t1;
+
set GLOBAL query_cache_size=0;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 60f0cfadc8e..8e953e223a9 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -971,9 +971,38 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
for (; block_table != block_table_end; block_table++)
{
TABLE_LIST table_list;
- bzero((char*) &table_list,sizeof(table_list));
+ TABLE *tmptable;
Query_cache_table *table = block_table->parent;
+
+ /*
+ Check that we have not temporary tables with same names of tables
+ of this query. If we have such tables, we will not send data from
+ query cache, because temporary tables hide real tables by which
+ query in query cache was made.
+ */
+ for (tmptable= thd->temporary_tables; tmptable ; tmptable= tmptable->next)
+ {
+ if (tmptable->key_length - 8 == table->key_len() &&
+ !memcmp(tmptable->table_cache_key, table->data(),
+ table->key_len()))
+ {
+ DBUG_PRINT("qcache",
+ ("Temporary table detected: '%s.%s'",
+ table_list.db, table_list.alias));
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ /*
+ We should not store result of this query because it contain
+ temporary tables => assign following wariable to make check
+ faster.
+ */
+ thd->safe_to_cache_query=0;
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(-1);
+ }
+ }
+
+ bzero((char*) &table_list,sizeof(table_list));
table_list.db = table->db();
table_list.alias= table_list.real_name= table->table();
if (check_table_access(thd,SELECT_ACL,&table_list,1))
@@ -2066,6 +2095,7 @@ Query_cache::insert_table(uint key_len, char *key,
}
char *db = header->db();
header->table(db + db_length + 1);
+ header->key_len(key_len);
}
Query_cache_block_table *list_root = table_block->table(0);
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 0c6579250ab..454f0318c12 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -144,10 +144,13 @@ struct Query_cache_query
struct Query_cache_table
{
char *tbl;
+ uint32 key_length;
inline char *db() { return (char *) data(); }
inline char *table() { return tbl; }
inline void table(char *table) { tbl = table; }
+ inline uint32 key_len() { return key_length; }
+ inline void key_len(uint32 len) { key_length= len; }
inline gptr data()
{
return (gptr)(((byte*)this)+