diff options
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 6 | ||||
-rw-r--r-- | mysql-test/r/query_cache.result | 33 | ||||
-rw-r--r-- | mysql-test/t/query_cache.test | 12 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sp_head.cc | 11 | ||||
-rw-r--r-- | sql/sql_cache.cc | 45 | ||||
-rw-r--r-- | sql/sql_parse.cc | 10 |
7 files changed, 81 insertions, 37 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3a2794093df..a8edcc6b8ec 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5145,10 +5145,10 @@ sub mysqld_start ($$) { # Write a message about this to the normal log file my $trace_name= "$opt_vardir/log/".$mysqld->name().".trace"; mtr_tofile($output, - "NOTE: When running with --valgrind --debug the output from", - "mysqld(where the valgrind messages shows up) is stored ", + "NOTE: When running with --valgrind --debug the output from ", + "mysqld (where the valgrind messages shows up) is stored ", "together with the trace file to make it ", - "easier to find the exact position of valgrind errors.", + "easier to find the exact position of valgrind errors. ", "See trace file $trace_name.\n"); $output= $trace_name; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index a5d995ffea0..26bf4e74219 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -912,13 +912,13 @@ a a show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 0 +Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 18 +Qcache_inserts 19 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 6 +Qcache_hits 7 DROP TABLE t1; SET GLOBAL query_cache_size=0; SET SESSION query_cache_type = 2; @@ -1070,10 +1070,10 @@ flush status; a show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 0 +Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 0 +Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value Qcache_hits 0 @@ -1081,13 +1081,30 @@ Qcache_hits 0 a show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 0 +Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 0 +Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 0 +Qcache_hits 1 +set global query_cache_strip_comments=1; +(select a from t1) union (select a from t1); +a +(select a from t1) /* */union (select a from t1); +a +set global query_cache_strip_comments=0; +(select a from t1) union (select a from t1); +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 drop table t1; create table t1 (a int); insert into t1 values (1),(2); diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 0d57a5640bf..dc403a30732 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -776,7 +776,19 @@ show status like "Qcache_hits"; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; show status like "Qcache_hits"; + +set global query_cache_strip_comments=1; +(select a from t1) union (select a from t1); +(select a from t1) /* */union (select a from t1); +set global query_cache_strip_comments=0; +(select a from t1) union (select a from t1); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; + drop table t1; + +# # SP cursors and selects with query cache (BUG#9715) # create table t1 (a int); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f0365a856da..d263c8aba4f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1045,6 +1045,7 @@ struct Query_cache_query_flags MY_LOCALE *lc_time_names; }; #define QUERY_CACHE_FLAGS_SIZE sizeof(Query_cache_query_flags) +#define QUERY_CACHE_DB_LENGTH_SIZE 2 #include "sql_cache.h" #define query_cache_store_query(A, B) query_cache.store_query(A, B) #define query_cache_destroy() query_cache.destroy() diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2d0870674f9..b30347a5ca7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1024,17 +1024,18 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) buffer :== <statement> The input statement(s) '\0' Terminating null char - <length> Length of following current database name (size_t) + <length> Length of following current database name 2 <db_name> Name of current database <flags> Flags struct */ - buf_len= qbuf.length() + 1 + sizeof(size_t) + thd->db_length + - QUERY_CACHE_FLAGS_SIZE + 1; + buf_len= (qbuf.length() + 1 + QUERY_CACHE_DB_LENGTH_SIZE + thd->db_length + + QUERY_CACHE_FLAGS_SIZE + 1); if ((pbuf= (char *) alloc_root(thd->mem_root, buf_len))) { + char *ptr= pbuf + qbuf.length(); memcpy(pbuf, qbuf.ptr(), qbuf.length()); - pbuf[qbuf.length()]= 0; - memcpy(pbuf+qbuf.length()+1, (char *) &thd->db_length, sizeof(size_t)); + *ptr= 0; + int2store(ptr+1, thd->db_length); } else DBUG_RETURN(TRUE); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 98d98c1696e..16b6d78576a 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -462,6 +462,7 @@ static void make_base_query(String *new_query, DBUG_ASSERT(query[query_length] == 0); DBUG_ASSERT(!is_white_space(query[0])); + new_query->length(0); // Don't copy anything from old buffer if (new_query->realloc(query_length + additional_length)) { /* @@ -540,8 +541,11 @@ insert_space: } if (buffer == last_space) buffer--; // Remove the last space - *buffer= 0; + *buffer= 0; // End zero after query new_query->length((size_t) (buffer - new_query->ptr())); + + /* Copy db_length */ + memcpy(buffer+1, query_end+1, QUERY_CACHE_DB_LENGTH_SIZE); } @@ -1473,8 +1477,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", /* Key is query + database + flag */ if (thd->db_length) { - memcpy((char*) (query + query_length + 1 + sizeof(size_t)), thd->db, - thd->db_length); + memcpy((char*) (query + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE), + thd->db, thd->db_length); DBUG_PRINT("qcache", ("database: %s length: %u", thd->db, (unsigned) thd->db_length)); } @@ -1482,8 +1486,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", { DBUG_PRINT("qcache", ("No active database")); } - tot_length= query_length + thd->db_length + 1 + sizeof(size_t) + - QUERY_CACHE_FLAGS_SIZE; + tot_length= (query_length + thd->db_length + 1 + + QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE); /* We should only copy structure (don't use it location directly) because of alignment issue @@ -1642,7 +1646,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) Query_cache_block_table *block_table, *block_table_end; ulong tot_length; Query_cache_query_flags flags; - const char *sql, *sql_end; + const char *sql, *sql_end, *found_brace= 0; DBUG_ENTER("Query_cache::send_result_to_client"); /* @@ -1716,9 +1720,16 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) case '\n': case '\t': case ' ': - case '(': // To handle (select a from t1) union (select a from t1); sql++; continue; + case '(': // To handle (select a from t1) union (select a from t1); + if (!found_brace) + { + found_brace= sql; + sql++; + continue; + } + /* fall trough */ default: break; } @@ -1752,8 +1763,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) sure the new current database has a name with the same length as the previous one. */ - size_t db_len; - memcpy((char *) &db_len, (sql + query_length + 1), sizeof(size_t)); + size_t db_len= uint2korr(sql_end+1); if (thd->db_length != db_len) { /* @@ -1788,8 +1798,11 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) Query_cache_block *query_block; if (opt_query_cache_strip_comments) { + if (found_brace) + sql= found_brace; make_base_query(&thd->base_query, sql, (size_t) (sql_end - sql), - thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE); + thd->db_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE + + QUERY_CACHE_FLAGS_SIZE); sql= thd->base_query.ptr(); query_length= thd->base_query.length(); } @@ -1799,15 +1812,15 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) thd->base_query.set(sql, query_length, system_charset_info); } - tot_length= query_length + 1 + sizeof(size_t) + - thd->db_length + QUERY_CACHE_FLAGS_SIZE; + tot_length= (query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE + + thd->db_length + QUERY_CACHE_FLAGS_SIZE); if (thd->db_length) { - memcpy((char*) (sql+query_length+1+ sizeof(size_t)), thd->db, - thd->db_length); + memcpy((uchar*) sql + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE, + thd->db, thd->db_length); DBUG_PRINT("qcache", ("database: '%s' length: %u", - thd->db, (unsigned)thd->db_length)); + thd->db, (uint) thd->db_length)); } else { @@ -1929,7 +1942,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", { DBUG_PRINT("qcache", ("Temporary table detected: '%s.%s'", - table_list.db, table_list.alias)); + tmptable->s->db.str, tmptable->alias.c_ptr())); unlock(); /* We should not store result of this query because it contain diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cdfbce7f0e3..1676d4a09f4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -508,10 +508,10 @@ static void handle_bootstrap_impl(THD *thd) query= (char *) thd->memdup_w_gap(buff, length + 1, thd->db_length + 1 + + QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE); - size_t db_len= 0; - memcpy(query + length + 1, (char *) &db_len, sizeof(size_t)); thd->set_query(query, length); + int2store(query + length + 1, 0); // No db in bootstrap DBUG_PRINT("query",("%-.4096s", thd->query())); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.start_new_query(); @@ -1880,7 +1880,8 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length) */ if (! (query= (char*) thd->memdup_w_gap(packet, packet_length, - 1 + sizeof(size_t) + thd->db_length + + 1 + thd->db_length + + QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE))) return TRUE; query[packet_length]= '\0'; @@ -1889,8 +1890,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length) also store this length, in case current database is changed during execution. We might need to reallocate the 'query' buffer */ - char *len_pos = (query + packet_length + 1); - memcpy(len_pos, (char *) &thd->db_length, sizeof(size_t)); + int2store(query + packet_length + 1, thd->db_length); thd->set_query(query, packet_length); |