Commit f4cc6c4d authored by konstantin@mysql.com's avatar konstantin@mysql.com

Merge mysql.com:/opt/local/work/mysql-5.0-merge

into  mysql.com:/opt/local/work/mysql-5.1-merge
parents a48773b6 1938052b
...@@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *); ...@@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *);
typedef struct st_hash { typedef struct st_hash {
uint key_offset,key_length; /* Length of key if const length */ uint key_offset,key_length; /* Length of key if const length */
uint records,blength,current_record; uint records, blength;
uint flags; uint flags;
DYNAMIC_ARRAY array; /* Place for hash_keys */ DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key; hash_get_key get_key;
...@@ -41,6 +41,9 @@ typedef struct st_hash { ...@@ -41,6 +41,9 @@ typedef struct st_hash {
CHARSET_INFO *charset; CHARSET_INFO *charset;
} HASH; } HASH;
/* A search iterator state */
typedef uint HASH_SEARCH_STATE;
#define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO) #define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)
my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint default_array_elements, uint key_offset, uint default_array_elements, uint key_offset,
...@@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, ...@@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
void hash_free(HASH *tree); void hash_free(HASH *tree);
void my_hash_reset(HASH *hash); void my_hash_reset(HASH *hash);
byte *hash_element(HASH *hash,uint idx); byte *hash_element(HASH *hash,uint idx);
gptr hash_search(HASH *info,const byte *key,uint length); gptr hash_search(const HASH *info, const byte *key, uint length);
gptr hash_next(HASH *info,const byte *key,uint length); gptr hash_first(const HASH *info, const byte *key, uint length,
HASH_SEARCH_STATE *state);
gptr hash_next(const HASH *info, const byte *key, uint length,
HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info,const byte *data); my_bool my_hash_insert(HASH *info,const byte *data);
my_bool hash_delete(HASH *hash,byte *record); my_bool hash_delete(HASH *hash,byte *record);
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
void hash_replace(HASH *hash, uint idx, byte *new_row); void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */ my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H))) #define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
......
...@@ -1077,6 +1077,22 @@ character_maximum_length character_octet_length ...@@ -1077,6 +1077,22 @@ character_maximum_length character_octet_length
32 32 32 32
64 64 64 64
drop table t1; drop table t1;
CREATE TABLE t1 (f1 BIGINT, f2 VARCHAR(20), f3 BIGINT);
INSERT INTO t1 SET f1 = 1, f2 = 'Schoenenbourg', f3 = 1;
CREATE FUNCTION func2() RETURNS BIGINT RETURN 1;
CREATE FUNCTION func1() RETURNS BIGINT
BEGIN
RETURN ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS);
END//
CREATE VIEW v1 AS SELECT 1 FROM t1
WHERE f3 = (SELECT func2 ());
SELECT func1();
func1()
1
DROP TABLE t1;
DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
select * from information_schema.engines WHERE ENGINE="MyISAM"; select * from information_schema.engines WHERE ENGINE="MyISAM";
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
MyISAM ENABLED Default engine as of MySQL 3.23 with great performance NO NO NO MyISAM ENABLED Default engine as of MySQL 3.23 with great performance NO NO NO
...@@ -769,6 +769,27 @@ from information_schema.columns where table_name='t1'; ...@@ -769,6 +769,27 @@ from information_schema.columns where table_name='t1';
drop table t1; drop table t1;
# #
# Bug#15533 crash, information_schema, function, view
#
CREATE TABLE t1 (f1 BIGINT, f2 VARCHAR(20), f3 BIGINT);
INSERT INTO t1 SET f1 = 1, f2 = 'Schoenenbourg', f3 = 1;
CREATE FUNCTION func2() RETURNS BIGINT RETURN 1;
delimiter //;
CREATE FUNCTION func1() RETURNS BIGINT
BEGIN
RETURN ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS);
END//
delimiter ;//
CREATE VIEW v1 AS SELECT 1 FROM t1
WHERE f3 = (SELECT func2 ());
SELECT func1();
DROP TABLE t1;
DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
# Show engines # Show engines
# #
......
...@@ -36,9 +36,10 @@ typedef struct st_hash_info { ...@@ -36,9 +36,10 @@ typedef struct st_hash_info {
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength); static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink); static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length); static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key,
uint length);
static uint calc_hash(HASH *hash,const byte *key,uint length) static uint calc_hash(const HASH *hash, const byte *key, uint length)
{ {
ulong nr1=1, nr2=4; ulong nr1=1, nr2=4;
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2); hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
...@@ -63,7 +64,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, ...@@ -63,7 +64,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
hash->key_offset=key_offset; hash->key_offset=key_offset;
hash->key_length=key_length; hash->key_length=key_length;
hash->blength=1; hash->blength=1;
hash->current_record= NO_RECORD; /* For the future */
hash->get_key=get_key; hash->get_key=get_key;
hash->free=free_element; hash->free=free_element;
hash->flags=flags; hash->flags=flags;
...@@ -135,7 +135,6 @@ void my_hash_reset(HASH *hash) ...@@ -135,7 +135,6 @@ void my_hash_reset(HASH *hash)
reset_dynamic(&hash->array); reset_dynamic(&hash->array);
/* Set row pointers so that the hash can be reused at once */ /* Set row pointers so that the hash can be reused at once */
hash->blength= 1; hash->blength= 1;
hash->current_record= NO_RECORD;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -147,7 +146,8 @@ void my_hash_reset(HASH *hash) ...@@ -147,7 +146,8 @@ void my_hash_reset(HASH *hash)
*/ */
static inline char* static inline char*
hash_key(HASH *hash,const byte *record,uint *length,my_bool first) hash_key(const HASH *hash, const byte *record, uint *length,
my_bool first)
{ {
if (hash->get_key) if (hash->get_key)
return (*hash->get_key)(record,length,first); return (*hash->get_key)(record,length,first);
...@@ -163,8 +163,8 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength) ...@@ -163,8 +163,8 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
return (hashnr & ((buffmax >> 1) -1)); return (hashnr & ((buffmax >> 1) -1));
} }
static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos,
uint maxlength) uint buffmax, uint maxlength)
{ {
uint length; uint length;
byte *key= (byte*) hash_key(hash,pos->data,&length,0); byte *key= (byte*) hash_key(hash,pos->data,&length,0);
...@@ -186,14 +186,25 @@ unsigned int rec_hashnr(HASH *hash,const byte *record) ...@@ -186,14 +186,25 @@ unsigned int rec_hashnr(HASH *hash,const byte *record)
} }
/* Search after a record based on a key */ gptr hash_search(const HASH *hash, const byte *key, uint length)
/* Sets info->current_ptr to found record */ {
HASH_SEARCH_STATE state;
return hash_first(hash, key, length, &state);
}
/*
Search after a record based on a key
NOTE
Assigns the number of the found record to HASH_SEARCH_STATE state
*/
gptr hash_search(HASH *hash,const byte *key,uint length) gptr hash_first(const HASH *hash, const byte *key, uint length,
HASH_SEARCH_STATE *current_record)
{ {
HASH_LINK *pos; HASH_LINK *pos;
uint flag,idx; uint flag,idx;
DBUG_ENTER("hash_search"); DBUG_ENTER("hash_first");
flag=1; flag=1;
if (hash->records) if (hash->records)
...@@ -206,7 +217,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length) ...@@ -206,7 +217,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length)
if (!hashcmp(hash,pos,key,length)) if (!hashcmp(hash,pos,key,length))
{ {
DBUG_PRINT("exit",("found key at %d",idx)); DBUG_PRINT("exit",("found key at %d",idx));
hash->current_record= idx; *current_record= idx;
DBUG_RETURN (pos->data); DBUG_RETURN (pos->data);
} }
if (flag) if (flag)
...@@ -218,31 +229,32 @@ gptr hash_search(HASH *hash,const byte *key,uint length) ...@@ -218,31 +229,32 @@ gptr hash_search(HASH *hash,const byte *key,uint length)
} }
while ((idx=pos->next) != NO_RECORD); while ((idx=pos->next) != NO_RECORD);
} }
hash->current_record= NO_RECORD; *current_record= NO_RECORD;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* Get next record with identical key */ /* Get next record with identical key */
/* Can only be called if previous calls was hash_search */ /* Can only be called if previous calls was hash_search */
gptr hash_next(HASH *hash,const byte *key,uint length) gptr hash_next(const HASH *hash, const byte *key, uint length,
HASH_SEARCH_STATE *current_record)
{ {
HASH_LINK *pos; HASH_LINK *pos;
uint idx; uint idx;
if (hash->current_record != NO_RECORD) if (*current_record != NO_RECORD)
{ {
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*); HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next) for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next)
{ {
pos=data+idx; pos=data+idx;
if (!hashcmp(hash,pos,key,length)) if (!hashcmp(hash,pos,key,length))
{ {
hash->current_record= idx; *current_record= idx;
return pos->data; return pos->data;
} }
} }
hash->current_record=NO_RECORD; *current_record= NO_RECORD;
} }
return 0; return 0;
} }
...@@ -281,7 +293,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink) ...@@ -281,7 +293,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
!= 0 key of record != key != 0 key of record != key
*/ */
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key,
uint length)
{ {
uint rec_keylength; uint rec_keylength;
byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1); byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1);
...@@ -307,7 +320,6 @@ my_bool my_hash_insert(HASH *info,const byte *record) ...@@ -307,7 +320,6 @@ my_bool my_hash_insert(HASH *info,const byte *record)
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array))) if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
return(TRUE); /* No more memory */ return(TRUE); /* No more memory */
info->current_record= NO_RECORD;
data=dynamic_element(&info->array,0,HASH_LINK*); data=dynamic_element(&info->array,0,HASH_LINK*);
halfbuff= info->blength >> 1; halfbuff= info->blength >> 1;
...@@ -450,7 +462,6 @@ my_bool hash_delete(HASH *hash,byte *record) ...@@ -450,7 +462,6 @@ my_bool hash_delete(HASH *hash,byte *record)
} }
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1; if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
hash->current_record= NO_RECORD;
lastpos=data+hash->records; lastpos=data+hash->records;
/* Remove link to record */ /* Remove link to record */
...@@ -543,7 +554,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length) ...@@ -543,7 +554,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
if ((idx=pos->next) == NO_RECORD) if ((idx=pos->next) == NO_RECORD)
DBUG_RETURN(1); /* Not found in links */ DBUG_RETURN(1); /* Not found in links */
} }
hash->current_record= NO_RECORD;
org_link= *pos; org_link= *pos;
empty=idx; empty=idx;
...@@ -593,10 +603,10 @@ byte *hash_element(HASH *hash,uint idx) ...@@ -593,10 +603,10 @@ byte *hash_element(HASH *hash,uint idx)
isn't changed isn't changed
*/ */
void hash_replace(HASH *hash, uint idx, byte *new_row) void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, byte *new_row)
{ {
if (idx != NO_RECORD) /* Safety */ if (*current_record != NO_RECORD) /* Safety */
dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row; dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;
} }
......
...@@ -74,7 +74,7 @@ static int do_test() ...@@ -74,7 +74,7 @@ static int do_test()
bzero((char*) key1,sizeof(key1[0])*1000); bzero((char*) key1,sizeof(key1[0])*1000);
printf("- Creating hash\n"); printf("- Creating hash\n");
if (hash_init(&hash,recant/2,0,6,0,free_record,0)) if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0))
goto err; goto err;
printf("- Writing records:\n"); printf("- Writing records:\n");
...@@ -172,15 +172,16 @@ static int do_test() ...@@ -172,15 +172,16 @@ static int do_test()
break; break;
if (key1[j] > 1) if (key1[j] > 1)
{ {
HASH_SEARCH_STATE state;
printf("- Testing identical read\n"); printf("- Testing identical read\n");
sprintf(key,"%6d",j); sprintf(key,"%6d",j);
pos=1; pos=1;
if (!(recpos=hash_search(&hash,key,0))) if (!(recpos= hash_first(&hash, key, 0, &state)))
{ {
printf("can't find key1: \"%s\"\n",key); printf("can't find key1: \"%s\"\n",key);
goto err; goto err;
} }
while (hash_next(&hash,key,0) && pos < (ulong) (key1[j]+10)) while (hash_next(&hash, key, 0, &state) && pos < (ulong) (key1[j]+10))
pos++; pos++;
if (pos != (ulong) key1[j]) if (pos != (ulong) key1[j])
{ {
...@@ -189,7 +190,7 @@ static int do_test() ...@@ -189,7 +190,7 @@ static int do_test()
} }
} }
printf("- Creating output heap-file 2\n"); printf("- Creating output heap-file 2\n");
if (hash_init(&hash2,hash.records,0,0,hash2_key,free_record,0)) if (hash_init(&hash2, default_charset_info, hash.records, 0, 0, hash2_key, free_record,0))
goto err; goto err;
printf("- Copying and removing records\n"); printf("- Copying and removing records\n");
......
...@@ -731,15 +731,16 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) ...@@ -731,15 +731,16 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
char *db= table_list->db; char *db= table_list->db;
uint key_length; uint key_length;
HASH_SEARCH_STATE state;
DBUG_ENTER("lock_table_name"); DBUG_ENTER("lock_table_name");
DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name)); DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name));
key_length= create_table_def_key(thd, key, table_list, 0); key_length= create_table_def_key(thd, key, table_list, 0);
/* Only insert the table if we haven't insert it already */ /* Only insert the table if we haven't insert it already */
for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; for (table=(TABLE*) hash_first(&open_cache, (byte*)key, key_length, &state);
table ; table ;
table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length, &state))
{ {
if (table->in_use == thd) if (table->in_use == thd)
{ {
......
...@@ -2243,14 +2243,14 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, ...@@ -2243,14 +2243,14 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
char helping [NAME_LEN*2+USERNAME_LENGTH+3]; char helping [NAME_LEN*2+USERNAME_LENGTH+3];
uint len; uint len;
GRANT_NAME *grant_name,*found=0; GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
for (grant_name=(GRANT_NAME*) hash_search(name_hash, for (grant_name= (GRANT_NAME*) hash_first(name_hash, (byte*) helping,
(byte*) helping, len, &state);
len) ;
grant_name ; grant_name ;
grant_name= (GRANT_NAME*) hash_next(name_hash,(byte*) helping, grant_name= (GRANT_NAME*) hash_next(name_hash,(byte*) helping,
len)) len, &state))
{ {
if (exact) if (exact)
{ {
......
...@@ -1702,6 +1702,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1702,6 +1702,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
char *alias= table_list->alias; char *alias= table_list->alias;
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table"); DBUG_ENTER("open_table");
/* find a unused table in the open table cache */ /* find a unused table in the open table cache */
...@@ -1862,9 +1863,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1862,9 +1863,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (thd->handler_tables) if (thd->handler_tables)
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length,
&state);
table && table->in_use ; table && table->in_use ;
table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
&state))
{ {
if (table->s->version != refresh_version) if (table->s->version != refresh_version)
{ {
...@@ -2240,10 +2243,12 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) ...@@ -2240,10 +2243,12 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
uint key_length= table->s->table_cache_key.length; uint key_length= table->s->table_cache_key.length;
DBUG_PRINT("loop", ("table_name: %s", table->alias)); DBUG_PRINT("loop", ("table_name: %s", table->alias));
for (TABLE *search=(TABLE*) hash_search(&open_cache, HASH_SEARCH_STATE state;
(byte*) key,key_length) ; for (TABLE *search= (TABLE*) hash_first(&open_cache, (byte*) key,
key_length, &state);
search ; search ;
search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) search= (TABLE*) hash_next(&open_cache, (byte*) key,
key_length, &state))
{ {
DBUG_PRINT("info", ("share: 0x%lx locked_by_flush: %d " DBUG_PRINT("info", ("share: 0x%lx locked_by_flush: %d "
"locked_by_name: %d db_stat: %u version: %u", "locked_by_name: %d db_stat: %u version: %u",
...@@ -5848,11 +5853,14 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, ...@@ -5848,11 +5853,14 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
for (;;) for (;;)
{ {
HASH_SEARCH_STATE state;
result= signalled= 0; result= signalled= 0;
for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length,
&state);
table; table;
table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
&state))
{ {
THD *in_use; THD *in_use;
table->s->version=0L; /* Free when thread is ready */ table->s->version=0L; /* Free when thread is ready */
......
...@@ -3055,6 +3055,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3055,6 +3055,7 @@ my_bool Query_cache::move_by_type(byte **border,
} }
case Query_cache_block::TABLE: case Query_cache_block::TABLE:
{ {
HASH_SEARCH_STATE record_idx;
DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block)); DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block));
if (*border == 0) if (*border == 0)
break; break;
...@@ -3072,7 +3073,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3072,7 +3073,7 @@ my_bool Query_cache::move_by_type(byte **border,
byte *key; byte *key;
uint key_length; uint key_length;
key=query_cache_table_get_key((byte*) block, &key_length, 0); key=query_cache_table_get_key((byte*) block, &key_length, 0);
hash_search(&tables, (byte*) key, key_length); hash_first(&tables, (byte*) key, key_length, &record_idx);
block->destroy(); block->destroy();
new_block->init(len); new_block->init(len);
...@@ -3106,7 +3107,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3106,7 +3107,7 @@ my_bool Query_cache::move_by_type(byte **border,
/* Fix pointer to table name */ /* Fix pointer to table name */
new_block->table()->table(new_block->table()->db() + tablename_offset); new_block->table()->table(new_block->table()->db() + tablename_offset);
/* Fix hash to point at moved block */ /* Fix hash to point at moved block */
hash_replace(&tables, tables.current_record, (byte*) new_block); hash_replace(&tables, &record_idx, (byte*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border)); len, (ulong) new_block, (ulong) *border));
...@@ -3114,6 +3115,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3114,6 +3115,7 @@ my_bool Query_cache::move_by_type(byte **border,
} }
case Query_cache_block::QUERY: case Query_cache_block::QUERY:
{ {
HASH_SEARCH_STATE record_idx;
DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block)); DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block));
if (*border == 0) if (*border == 0)
break; break;
...@@ -3131,7 +3133,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3131,7 +3133,7 @@ my_bool Query_cache::move_by_type(byte **border,
byte *key; byte *key;
uint key_length; uint key_length;
key=query_cache_query_get_key((byte*) block, &key_length, 0); key=query_cache_query_get_key((byte*) block, &key_length, 0);
hash_search(&queries, (byte*) key, key_length); hash_first(&queries, (byte*) key, key_length, &record_idx);
// Move table of used tables // Move table of used tables
memmove((char*) new_block->table(0), (char*) block->table(0), memmove((char*) new_block->table(0), (char*) block->table(0),
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table))); ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
...@@ -3199,7 +3201,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -3199,7 +3201,7 @@ my_bool Query_cache::move_by_type(byte **border,
net->query_cache_query= (gptr) new_block; net->query_cache_query= (gptr) new_block;
} }
/* Fix hash to point at moved block */ /* Fix hash to point at moved block */
hash_replace(&queries, queries.current_record, (byte*) new_block); hash_replace(&queries, &record_idx, (byte*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border)); len, (ulong) new_block, (ulong) *border));
break; break;
......
...@@ -2238,6 +2238,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -2238,6 +2238,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
int error= 1; int error= 1;
enum legacy_db_type not_used; enum legacy_db_type not_used;
Open_tables_state open_tables_state_backup; Open_tables_state open_tables_state_backup;
bool save_view_prepare_mode= lex->view_prepare_mode;
lex->view_prepare_mode= TRUE;
DBUG_ENTER("get_all_tables"); DBUG_ENTER("get_all_tables");
LINT_INIT(end); LINT_INIT(end);
...@@ -2423,6 +2425,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -2423,6 +2425,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
lex->derived_tables= derived_tables; lex->derived_tables= derived_tables;
lex->all_selects_list= old_all_select_lex; lex->all_selects_list= old_all_select_lex;
lex->query_tables_last= save_query_tables_last; lex->query_tables_last= save_query_tables_last;
lex->view_prepare_mode= save_view_prepare_mode;
*save_query_tables_last= 0; *save_query_tables_last= 0;
lex->sql_command= save_sql_command; lex->sql_command= save_sql_command;
DBUG_RETURN(error); DBUG_RETURN(error);
......
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