Commit d2cae574 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Limit created keys to MAX_KEY_LENGTH.

Fix problem with query cache and database names
parent 95a3bfac
...@@ -347,7 +347,7 @@ fi ...@@ -347,7 +347,7 @@ fi
[ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp [ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp
[ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run [ -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` E=`$EXPR $COLUMNS - 8`
DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E` DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E`
...@@ -605,6 +605,7 @@ start_manager() ...@@ -605,6 +605,7 @@ start_manager()
{ {
if [ $USE_MANAGER = 0 ] ; then if [ $USE_MANAGER = 0 ] ; then
echo "Manager disabled, skipping manager start." echo "Manager disabled, skipping manager start."
$RM -f $MYSQL_MANAGER_LOG
return return
fi fi
$ECHO "Starting MySQL Manager" $ECHO "Starting MySQL Manager"
...@@ -675,7 +676,7 @@ manager_term() ...@@ -675,7 +676,7 @@ manager_term()
shift shift
if [ $USE_MANAGER = 0 ] ; then if [ $USE_MANAGER = 0 ] ; then
$MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock -O \ $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 return
fi fi
$MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \
......
...@@ -2,7 +2,7 @@ flush query cache; ...@@ -2,7 +2,7 @@ flush query cache;
flush query cache; flush query cache;
reset query cache; reset query cache;
flush status; 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); create table t1 (a int not null);
insert into t1 values (1),(2),(3); insert into t1 values (1),(2),(3);
select * from t1; select * from t1;
...@@ -346,7 +346,7 @@ show status like "Qcache_queries_in_cache"; ...@@ -346,7 +346,7 @@ show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 0 Qcache_queries_in_cache 0
drop table t1,t2; 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)); create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
insert into mysqltest.t1 (a) values (1); insert into mysqltest.t1 (a) values (1);
select * from mysqltest.t1 where i is null; select * from mysqltest.t1 where i is null;
...@@ -375,6 +375,36 @@ set CHARACTER SET DEFAULT; ...@@ -375,6 +375,36 @@ set CHARACTER SET DEFAULT;
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 2 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; drop table t1;
flush query cache; flush query cache;
reset query cache; reset query cache;
......
...@@ -8,7 +8,7 @@ flush query cache; # This crashed in some versions ...@@ -8,7 +8,7 @@ flush query cache; # This crashed in some versions
flush query cache; # This crashed in some versions flush query cache; # This crashed in some versions
reset query cache; reset query cache;
flush status; 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 # First simple test
...@@ -235,7 +235,7 @@ drop table t1,t2; ...@@ -235,7 +235,7 @@ drop table t1,t2;
# #
# noncachable ODBC work around (and prepare cache for drop database) # 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)); create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
insert into mysqltest.t1 (a) values (1); insert into mysqltest.t1 (a) values (1);
select * from mysqltest.t1 where i is null; select * from mysqltest.t1 where i is null;
...@@ -258,6 +258,7 @@ set CHARACTER SET cp1251_koi8; ...@@ -258,6 +258,7 @@ set CHARACTER SET cp1251_koi8;
select * from t1; select * from t1;
set CHARACTER SET DEFAULT; set CHARACTER SET DEFAULT;
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
drop table t1; drop table t1;
# The following tests can't be done as the values differen on 32 and 64 bit # The following tests can't be done as the values differen on 32 and 64 bit
...@@ -265,6 +266,27 @@ drop table t1; ...@@ -265,6 +266,27 @@ drop table t1;
#show variables like "query_cache_size"; #show variables like "query_cache_size";
#show status like "Qcache_free_memory"; #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 # Test insert delayed
# #
......
...@@ -242,7 +242,7 @@ sub init_data ...@@ -242,7 +242,7 @@ sub init_data
{ {
@onek= @onek=
$server->create("onek", $server->create("onek",
["unique1 int(4) NOT NULL", ["unique1 int(5) NOT NULL",
"unique2 int(4) NOT NULL", "unique2 int(4) NOT NULL",
"two int(4)", "two int(4)",
"four int(4)", "four int(4)",
......
...@@ -743,7 +743,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) ...@@ -743,7 +743,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
/* Key is query + database + flag */ /* Key is query + database + flag */
if (thd->db_length) 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", DBUG_PRINT("qcache", ("database : %s length %u",
thd->db, thd->db_length)); thd->db, thd->db_length));
} }
...@@ -761,7 +761,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) ...@@ -761,7 +761,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
flags|= (byte) thd->convert_set->number(); flags|= (byte) thd->convert_set->number();
DBUG_ASSERT(thd->convert_set->number() < 128); 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; thd->query[tot_length-1] = (char) flags;
/* Check if another thread is processing the same query? */ /* Check if another thread is processing the same query? */
...@@ -832,7 +832,6 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) ...@@ -832,7 +832,6 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
statistic_increment(refused, &structure_guard_mutex); statistic_increment(refused, &structure_guard_mutex);
end: end:
thd->query[thd->query_length]= 0; // Restore end null
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -890,12 +889,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -890,12 +889,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err; goto err;
} }
/* Test if the query is a SELECT */ /*
while (*sql == ' ' || *sql == '\t') Test if the query is a SELECT
{ (pre-space is removed in dispatch_command)
sql++; */
query_length--;
}
if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' || if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' ||
toupper(sql[2]) !='L') toupper(sql[2]) !='L')
{ {
...@@ -911,10 +908,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -911,10 +908,10 @@ 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; tot_length=query_length+thd->db_length+2;
if (thd->db_length) 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", DBUG_PRINT("qcache", ("database: '%s' length %u",
thd->db, thd->db_length)); thd->db, thd->db_length));
} }
...@@ -936,9 +933,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -936,9 +933,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
sql[tot_length-1] = (char) flags; sql[tot_length-1] = (char) flags;
query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql, query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
tot_length); tot_length);
sql[query_length] = '\0'; // Restore end null
/* Quick abort on unlocked data */ /* Quick abort on unlocked data */
if (query_block == 0 || if (query_block == 0 ||
query_block->query()->result() == 0 || query_block->query()->result() == 0 ||
...@@ -2582,8 +2576,11 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -2582,8 +2576,11 @@ my_bool Query_cache::move_by_type(byte **border,
pthread_cond_init(&new_query->lock, NULL); pthread_cond_init(&new_query->lock, NULL);
pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST); 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(); NET *net = new_block->query()->writer();
/* QQ: When could this happen ? */
if (net != 0) if (net != 0)
{ {
net->query_cache_query= (gptr) new_block; net->query_cache_query= (gptr) new_block;
...@@ -2877,15 +2874,17 @@ void Query_cache::queries_dump() ...@@ -2877,15 +2874,17 @@ void Query_cache::queries_dump()
{ {
uint len; uint len;
char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0); char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0);
uint flags = (uint) (uchar) str[len-1]; len--; // Point at flags
DBUG_PRINT("qcache", ("%u (%u,%u) %.*s",len, 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_CLIENT_LONG_FLAG_MASK)? 1:0),
(flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len-1, (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len,
str)); str,strend(str)+1));
DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block, DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block,
(ulong) block->next, (ulong) block->prev, (ulong) block->next, (ulong) block->prev,
(ulong)block->pnext, (ulong)block->pprev)); (ulong)block->pnext, (ulong)block->pprev));
str[len]=(char) flags;
for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++) for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++)
{ {
Query_cache_table *table = block->table(t)->parent; Query_cache_table *table = block->table(t)->parent;
......
...@@ -840,25 +840,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -840,25 +840,32 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_QUERY: case COM_QUERY:
{ {
char *pos=packet-1+packet_length; // Point at end null packet_length--; // Remove end null
/* Remove garage at end of query */ /* 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]))) while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1])))
{ {
pos--; pos--;
packet_length--; 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), if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
packet_length+1, packet_length,
thd->db_length+1))) thd->db_length+2)))
break; break;
thd->query[packet_length]=0; thd->query[packet_length]=0;
thd->packet.shrink(net_buffer_length); // Reclaim some memory thd->packet.shrink(net_buffer_length); // Reclaim some memory
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR); my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_log.write(thd,command,"%s",thd->query); mysql_log.write(thd,command,"%s",thd->query);
DBUG_PRINT("query",("%s",thd->query)); DBUG_PRINT("query",("'%s'",thd->query));
mysql_parse(thd,thd->query,packet_length-1); /* thd->query_length is set by mysql_parse() */
mysql_parse(thd,thd->query,packet_length);
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR); my_pthread_setprio(pthread_self(),WAIT_PRIOR);
DBUG_PRINT("info",("query ready")); DBUG_PRINT("info",("query ready"));
......
...@@ -558,9 +558,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -558,9 +558,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
} }
} }
key_info->key_length=(uint16) key_length; 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); DBUG_RETURN(-1);
} }
} }
......
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