Commit e6e1600e authored by unknown's avatar unknown
Browse files

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
parent ec8779e9
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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;
+12 −0
Original line number Diff line number Diff line
@@ -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;
+31 −1
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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)+