diff options
Diffstat (limited to 'sql/sql_cache.cc')
-rw-r--r-- | sql/sql_cache.cc | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index b791428eef0..4800fdedbe5 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1241,8 +1241,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", /* Key is query + database + flag */ if (thd->db_length) { - memcpy(thd->query() + thd->query_length() + 1, thd->db, - thd->db_length); + memcpy(thd->query() + thd->query_length() + 1 + sizeof(size_t), + thd->db, thd->db_length); DBUG_PRINT("qcache", ("database: %s length: %u", thd->db, (unsigned) thd->db_length)); } @@ -1251,7 +1251,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", DBUG_PRINT("qcache", ("No active database")); } tot_length= thd->query_length() + thd->db_length + 1 + - QUERY_CACHE_FLAGS_SIZE; + sizeof(size_t) + QUERY_CACHE_FLAGS_SIZE; /* We should only copy structure (don't use it location directly) because of alignment issue @@ -1462,7 +1462,28 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) goto err; } } + { + /* + We have allocated buffer space (in alloc_query) to hold the + SQL statement(s) + the current database name + a flags struct. + If the database name has changed during execution, which might + happen if there are multiple statements, we need to make + sure the new current database has a name with the same length + as the previous one. + */ + size_t *db_len= (size_t *) (sql + query_length + 1); + if (thd->db_length != *db_len) + { + /* + We should probably reallocate the buffer in this case, + but for now we just leave it uncached + */ + DBUG_PRINT("qcache", + ("Current database has changed since start of query")); + goto err; + } + } /* Try to obtain an exclusive lock on the query cache. If the cache is disabled or if a full cache flush is in progress, the attempt to @@ -1484,10 +1505,12 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) Query_cache_block *query_block; - tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE; + tot_length= query_length + 1 + sizeof(size_t) + + thd->db_length + QUERY_CACHE_FLAGS_SIZE; + if (thd->db_length) { - memcpy(sql+query_length+1, thd->db, thd->db_length); + memcpy(sql + query_length + 1 + sizeof(size_t), thd->db, thd->db_length); DBUG_PRINT("qcache", ("database: '%s' length: %u", thd->db, (unsigned)thd->db_length)); } |