From 953ac1a5cf2acc464c3214e715679e61c4d18c24 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Dec 2001 02:43:46 +0200 Subject: [PATCH] Limit created keys to MAX_KEY_LENGTH. Fix problem with query cache and database names mysql-test/mysql-test-run.sh: Portability fixes mysql-test/r/query_cache.result: More tests when using different databases mysql-test/t/query_cache.test: More tests when using different databases sql-bench/test-wisconsin.sh: Portability fix sql/sql_cache.cc: Fix problem with query cache and database names sql/sql_parse.cc: Remove pre and end space in query. sql/sql_table.cc: Limit created keys to MAX_KEY_LENGTH. --- mysql-test/mysql-test-run.sh | 15 +++++++------ mysql-test/r/query_cache.result | 34 ++++++++++++++++++++++++++-- mysql-test/t/query_cache.test | 26 ++++++++++++++++++++-- sql-bench/test-wisconsin.sh | 2 +- sql/sql_cache.cc | 39 ++++++++++++++++----------------- sql/sql_parse.cc | 21 ++++++++++++------ sql/sql_table.cc | 5 +++-- 7 files changed, 101 insertions(+), 41 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 627668f67b1..a2593a766ca 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -347,7 +347,7 @@ fi [ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp [ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run -[ -z "$COLUMNS" ] && COLUMNS=80 +if test ${COLUMNS:-0} -lt 80 ; then COLUMNS=80 ; fi E=`$EXPR $COLUMNS - 8` DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E` @@ -547,10 +547,10 @@ mysql_install_db () { for slave_num in 1 2 ; do - $RM -rf var/slave$slave_num-data/ - mkdir -p var/slave$slave_num-data/mysql - mkdir -p var/slave$slave_num-data/test - cp var/slave-data/mysql/* var/slave$slave_num-data/mysql + $RM -rf var/slave$slave_num-data/ + mkdir -p var/slave$slave_num-data/mysql + mkdir -p var/slave$slave_num-data/test + cp var/slave-data/mysql/* var/slave$slave_num-data/mysql done return 0 } @@ -604,7 +604,8 @@ abort_if_failed() start_manager() { if [ $USE_MANAGER = 0 ] ; then - echo "Manager disabled, skipping manager start." + echo "Manager disabled, skipping manager start." + $RM -f $MYSQL_MANAGER_LOG return fi $ECHO "Starting MySQL Manager" @@ -675,7 +676,7 @@ manager_term() shift if [ $USE_MANAGER = 0 ] ; then $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \ - connect_timeout=5 -O shutdown_timeout=20 shutdown >/dev/null 2>&1 + connect_timeout=5 -O shutdown_timeout=20 shutdown >> $MYSQL_MANAGER_LOG 2>&1 return fi $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 79d101807cd..fa130deec19 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -2,7 +2,7 @@ flush query cache; flush query cache; reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21; +drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; create table t1 (a int not null); insert into t1 values (1),(2),(3); select * from t1; @@ -346,7 +346,7 @@ show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 drop table t1,t2; -create database mysqltest; +create database if not exists mysqltest; create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; @@ -375,6 +375,36 @@ set CHARACTER SET DEFAULT; show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +drop table t1; +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null); +create table t1 (i int not null); +insert into mysqltest.t1 (i) values (1); +insert into t1 (i) values (2); +select * from t1; +i +2 +use mysqltest; +select * from t1; +i +1 +select * from t1; +i +1 +use test; +select * from t1; +i +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +drop database mysqltest; drop table t1; flush query cache; reset query cache; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 955abeaabc4..8a577d0be05 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -8,7 +8,7 @@ flush query cache; # This crashed in some versions flush query cache; # This crashed in some versions reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21; +drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; # # First simple test @@ -235,7 +235,7 @@ drop table t1,t2; # # noncachable ODBC work around (and prepare cache for drop database) # -create database mysqltest; +create database if not exists mysqltest; create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; @@ -258,6 +258,7 @@ set CHARACTER SET cp1251_koi8; select * from t1; set CHARACTER SET DEFAULT; show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; drop table t1; # The following tests can't be done as the values differen on 32 and 64 bit @@ -265,6 +266,27 @@ drop table t1; #show variables like "query_cache_size"; #show status like "Qcache_free_memory"; +# +# same tables in different db +# +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null); +create table t1 (i int not null); +insert into mysqltest.t1 (i) values (1); +insert into t1 (i) values (2); + +select * from t1; +use mysqltest; +select * from t1; +select * from t1; +use test; +select * from t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; + +drop database mysqltest; +drop table t1; + # # Test insert delayed # diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh index e7e3a0f235a..adc3e5b5aa4 100644 --- a/sql-bench/test-wisconsin.sh +++ b/sql-bench/test-wisconsin.sh @@ -242,7 +242,7 @@ sub init_data { @onek= $server->create("onek", - ["unique1 int(4) NOT NULL", + ["unique1 int(5) NOT NULL", "unique2 int(4) NOT NULL", "two int(4)", "four int(4)", diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 399f0dda04e..523e835f472 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -743,7 +743,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) /* Key is query + database + flag */ if (thd->db_length) { - memcpy(thd->query+thd->query_length, thd->db, thd->db_length); + memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length); DBUG_PRINT("qcache", ("database : %s length %u", thd->db, thd->db_length)); } @@ -761,7 +761,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) flags|= (byte) thd->convert_set->number(); DBUG_ASSERT(thd->convert_set->number() < 128); } - tot_length=thd->query_length+1+thd->db_length; + tot_length=thd->query_length+thd->db_length+2; thd->query[tot_length-1] = (char) flags; /* Check if another thread is processing the same query? */ @@ -832,7 +832,6 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) statistic_increment(refused, &structure_guard_mutex); end: - thd->query[thd->query_length]= 0; // Restore end null DBUG_VOID_RETURN; } @@ -890,12 +889,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) goto err; } - /* Test if the query is a SELECT */ - while (*sql == ' ' || *sql == '\t') - { - sql++; - query_length--; - } + /* + Test if the query is a SELECT + (pre-space is removed in dispatch_command) + */ if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' || toupper(sql[2]) !='L') { @@ -911,10 +908,10 @@ 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; + tot_length=query_length+thd->db_length+2; if (thd->db_length) { - memcpy(sql+query_length, thd->db, thd->db_length); + memcpy(sql+query_length+1, thd->db, thd->db_length); DBUG_PRINT("qcache", ("database: '%s' length %u", thd->db, thd->db_length)); } @@ -936,9 +933,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) sql[tot_length-1] = (char) flags; query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql, tot_length); - - sql[query_length] = '\0'; // Restore end null - /* Quick abort on unlocked data */ if (query_block == 0 || query_block->query()->result() == 0 || @@ -2582,8 +2576,11 @@ my_bool Query_cache::move_by_type(byte **border, pthread_cond_init(&new_query->lock, NULL); pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST); + /* + If someone is writing to this block, inform the writer that the block + has been moved. + */ NET *net = new_block->query()->writer(); - /* QQ: When could this happen ? */ if (net != 0) { net->query_cache_query= (gptr) new_block; @@ -2877,15 +2874,17 @@ void Query_cache::queries_dump() { uint len; char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0); - uint flags = (uint) (uchar) str[len-1]; - DBUG_PRINT("qcache", ("%u (%u,%u) %.*s",len, + len--; // Point at flags + uint flags = (uint) (uchar) str[len]; + str[len]=0; + DBUG_PRINT("qcache", ("%u (%u,%u) '%s' '%s'", ((flags & QUERY_CACHE_CLIENT_LONG_FLAG_MASK)? 1:0), - (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len-1, - str)); + (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len, + str,strend(str)+1)); DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block, (ulong) block->next, (ulong) block->prev, (ulong)block->pnext, (ulong)block->pprev)); - + str[len]=(char) flags; for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++) { Query_cache_table *table = block->table(t)->parent; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index af6bd07cdc5..3662aa301e2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -840,25 +840,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_QUERY: { - char *pos=packet-1+packet_length; // Point at end null - /* Remove garage at end of query */ + packet_length--; // Remove end null + /* Remove garage at start and end of query */ + while (isspace(packet[0]) && packet_length > 0) + { + packet++; + packet_length--; + } + char *pos=packet+packet_length; // Point at end null while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1]))) { pos--; packet_length--; } - thd->query_length= packet_length; + /* We must allocate some extra memory for query cache */ if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), - packet_length+1, - thd->db_length+1))) + packet_length, + thd->db_length+2))) break; thd->query[packet_length]=0; thd->packet.shrink(net_buffer_length); // Reclaim some memory if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); mysql_log.write(thd,command,"%s",thd->query); - DBUG_PRINT("query",("%s",thd->query)); - mysql_parse(thd,thd->query,packet_length-1); + DBUG_PRINT("query",("'%s'",thd->query)); + /* thd->query_length is set by mysql_parse() */ + mysql_parse(thd,thd->query,packet_length); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); DBUG_PRINT("info",("query ready")); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d3c11ab8716..6ded046ccbf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -558,9 +558,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } } key_info->key_length=(uint16) key_length; - if (key_length > file->max_key_length() && key->type != Key::FULLTEXT) + uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH); + if (key_length > max_key_length && key->type != Key::FULLTEXT) { - my_error(ER_TOO_LONG_KEY,MYF(0),file->max_key_length()); + my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); DBUG_RETURN(-1); } }