Commit 5a0da832 authored by Tatjana Azundris Nuernberg's avatar Tatjana Azundris Nuernberg

auto-merge

parents 9a0ec3cf e7a8fedf
...@@ -1038,12 +1038,22 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) ...@@ -1038,12 +1038,22 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
/* /*
Allocate additional space at the end of the new query string for the Allocate additional space at the end of the new query string for the
query_cache_send_result_to_client function. query_cache_send_result_to_client function.
The query buffer layout is:
buffer :==
<statement> The input statement(s)
'\0' Terminating null char
<length> Length of following current database name (size_t)
<db_name> Name of current database
<flags> Flags struct
*/ */
buf_len= qbuf.length() + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE + 1; buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length +
QUERY_CACHE_FLAGS_SIZE + 1;
if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len))) if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len)))
{ {
memcpy(pbuf, qbuf.ptr(), qbuf.length()); memcpy(pbuf, qbuf.ptr(), qbuf.length());
pbuf[qbuf.length()]= 0; pbuf[qbuf.length()]= 0;
*(size_t *)(pbuf+qbuf.length()+1)= thd->db_length;
} }
else else
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
......
...@@ -1278,8 +1278,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", ...@@ -1278,8 +1278,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Key is query + database + flag */ /* Key is query + database + flag */
if (thd->db_length) if (thd->db_length)
{ {
memcpy(thd->query() + thd->query_length() + 1, thd->db, memcpy(thd->query() + thd->query_length() + 1 + sizeof(size_t),
thd->db_length); thd->db, thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u", DBUG_PRINT("qcache", ("database: %s length: %u",
thd->db, (unsigned) thd->db_length)); thd->db, (unsigned) thd->db_length));
} }
...@@ -1288,7 +1288,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", ...@@ -1288,7 +1288,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
DBUG_PRINT("qcache", ("No active database")); DBUG_PRINT("qcache", ("No active database"));
} }
tot_length= thd->query_length() + thd->db_length + 1 + 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) We should only copy structure (don't use it location directly)
because of alignment issue because of alignment issue
...@@ -1506,7 +1506,28 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -1506,7 +1506,28 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err; 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 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 disabled or if a full cache flush is in progress, the attempt to
...@@ -1522,10 +1543,12 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -1522,10 +1543,12 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_block *query_block; 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) 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", DBUG_PRINT("qcache", ("database: '%s' length: %u",
thd->db, (unsigned)thd->db_length)); thd->db, (unsigned)thd->db_length));
} }
......
...@@ -1637,13 +1637,30 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length) ...@@ -1637,13 +1637,30 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
pos--; pos--;
packet_length--; packet_length--;
} }
/* We must allocate some extra memory for query cache */ /* We must allocate some extra memory for query cache
The query buffer layout is:
buffer :==
<statement> The input statement(s)
'\0' Terminating null char (1 byte)
<length> Length of following current database name (size_t)
<db_name> Name of current database
<flags> Flags struct
*/
if (! (query= (char*) thd->memdup_w_gap(packet, if (! (query= (char*) thd->memdup_w_gap(packet,
packet_length, packet_length,
1 + thd->db_length + 1 + sizeof(size_t) + thd->db_length +
QUERY_CACHE_FLAGS_SIZE))) QUERY_CACHE_FLAGS_SIZE)))
return TRUE; return TRUE;
query[packet_length]= '\0'; query[packet_length]= '\0';
/*
Space to hold the name of the current database is allocated. We
also store this length, in case current database is changed during
execution. We might need to reallocate the 'query' buffer
*/
size_t *len = (size_t *) (query + packet_length + 1);
*len= thd->db_length;
thd->set_query(query, packet_length); thd->set_query(query, packet_length);
/* Reclaim some memory */ /* Reclaim some memory */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment