mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge mysql.com:/home/mydev/mysql-5.0
into mysql.com:/home/mydev/mysql-5.0-5000
This commit is contained in:
commit
95fa3340c6
7 changed files with 95 additions and 12 deletions
|
@ -40,12 +40,12 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
|
||||||
end= key+ keyseg->length;
|
end= key+ keyseg->length;
|
||||||
if (keyseg->flag & HA_NULL_PART)
|
if (keyseg->flag & HA_NULL_PART)
|
||||||
{
|
{
|
||||||
if (!*key)
|
/* A NULL value is encoded by a 1-byte flag. Zero means NULL. */
|
||||||
|
if (! *(key++))
|
||||||
{
|
{
|
||||||
fprintf(stream,"NULL");
|
fprintf(stream,"NULL");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
key++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (keyseg->type) {
|
switch (keyseg->type) {
|
||||||
|
|
|
@ -31,8 +31,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
||||||
HA_KEYSEG *last_used_keyseg;
|
HA_KEYSEG *last_used_keyseg;
|
||||||
uint pack_key_length, use_key_length, nextflag;
|
uint pack_key_length, use_key_length, nextflag;
|
||||||
DBUG_ENTER("mi_rkey");
|
DBUG_ENTER("mi_rkey");
|
||||||
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
|
DBUG_PRINT("enter", ("base: %p buf: %p inx: %d search_flag: %d",
|
||||||
info,inx,search_flag));
|
info, buf, inx, search_flag));
|
||||||
|
|
||||||
if ((inx = _mi_check_index(info,inx)) < 0)
|
if ((inx = _mi_check_index(info,inx)) < 0)
|
||||||
DBUG_RETURN(my_errno);
|
DBUG_RETURN(my_errno);
|
||||||
|
@ -56,9 +56,12 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
||||||
{
|
{
|
||||||
if (key_len == 0)
|
if (key_len == 0)
|
||||||
key_len=USE_WHOLE_KEY;
|
key_len=USE_WHOLE_KEY;
|
||||||
|
/* Save the packed key for later use in the second buffer of lastkey. */
|
||||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
key_buff=info->lastkey+info->s->base.max_key_length;
|
||||||
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
|
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
|
||||||
key_len, &last_used_keyseg);
|
key_len, &last_used_keyseg);
|
||||||
|
/* Save packed_key_length for use by the MERGE engine. */
|
||||||
|
info->pack_key_length= pack_key_length;
|
||||||
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
|
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
|
||||||
key_buff, pack_key_length););
|
key_buff, pack_key_length););
|
||||||
}
|
}
|
||||||
|
|
|
@ -915,11 +915,21 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||||
reg1 HA_KEYSEG *keyseg;
|
reg1 HA_KEYSEG *keyseg;
|
||||||
uchar *start_key,*page,*page_end,*from,*from_end;
|
uchar *start_key,*page,*page_end,*from,*from_end;
|
||||||
uint length,tmp;
|
uint length,tmp;
|
||||||
|
DBUG_ENTER("_mi_get_binary_pack_key");
|
||||||
|
|
||||||
page= *page_pos;
|
page= *page_pos;
|
||||||
page_end=page+MI_MAX_KEY_BUFF+1;
|
page_end=page+MI_MAX_KEY_BUFF+1;
|
||||||
start_key=key;
|
start_key=key;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Keys are compressed the following way:
|
||||||
|
|
||||||
|
prefix length Packed length of prefix for the prev key. (1 or 3 bytes)
|
||||||
|
for each key segment:
|
||||||
|
[is null] Null indicator if can be null (1 byte, zero means null)
|
||||||
|
[length] Packed length if varlength (1 or 3 bytes)
|
||||||
|
pointer Reference to the data file (last_keyseg->length).
|
||||||
|
*/
|
||||||
get_key_length(length,page);
|
get_key_length(length,page);
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +940,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||||
DBUG_DUMP("key",(char*) *page_pos,16);
|
DBUG_DUMP("key",(char*) *page_pos,16);
|
||||||
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
|
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
|
||||||
my_errno=HA_ERR_CRASHED;
|
my_errno=HA_ERR_CRASHED;
|
||||||
return 0; /* Wrong key */
|
DBUG_RETURN(0); /* Wrong key */
|
||||||
}
|
}
|
||||||
from=key; from_end=key+length;
|
from=key; from_end=key+length;
|
||||||
}
|
}
|
||||||
|
@ -992,12 +1002,12 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
|
||||||
DBUG_PRINT("error",("Error when unpacking key"));
|
DBUG_PRINT("error",("Error when unpacking key"));
|
||||||
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
|
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
|
||||||
my_errno=HA_ERR_CRASHED;
|
my_errno=HA_ERR_CRASHED;
|
||||||
return 0; /* Error */
|
DBUG_RETURN(0); /* Error */
|
||||||
}
|
}
|
||||||
memcpy((byte*) key,(byte*) from,(size_t) length);
|
memcpy((byte*) key,(byte*) from,(size_t) length);
|
||||||
*page_pos= from+length;
|
*page_pos= from+length;
|
||||||
}
|
}
|
||||||
return((uint) (key-start_key)+keyseg->length);
|
DBUG_RETURN((uint) (key-start_key)+keyseg->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -261,6 +261,7 @@ struct st_myisam_info {
|
||||||
uint last_rkey_length; /* Last length in mi_rkey() */
|
uint last_rkey_length; /* Last length in mi_rkey() */
|
||||||
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
|
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
|
||||||
uint save_lastkey_length;
|
uint save_lastkey_length;
|
||||||
|
uint pack_key_length; /* For MYISAMMRG */
|
||||||
int errkey; /* Got last error on this key */
|
int errkey; /* Got last error on this key */
|
||||||
int lock_type; /* How database was locked */
|
int lock_type; /* How database was locked */
|
||||||
int tmp_lock_type; /* When locked by readinfo */
|
int tmp_lock_type; /* When locked by readinfo */
|
||||||
|
|
|
@ -44,11 +44,12 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
|
||||||
MYRG_TABLE *table;
|
MYRG_TABLE *table;
|
||||||
MI_INFO *mi;
|
MI_INFO *mi;
|
||||||
int err;
|
int err;
|
||||||
|
DBUG_ENTER("myrg_rkey");
|
||||||
LINT_INIT(key_buff);
|
LINT_INIT(key_buff);
|
||||||
LINT_INIT(pack_key_length);
|
LINT_INIT(pack_key_length);
|
||||||
|
|
||||||
if (_myrg_init_queue(info,inx,search_flag))
|
if (_myrg_init_queue(info,inx,search_flag))
|
||||||
return my_errno;
|
DBUG_RETURN(my_errno);
|
||||||
|
|
||||||
for (table=info->open_tables ; table != info->end_table ; table++)
|
for (table=info->open_tables ; table != info->end_table ; table++)
|
||||||
{
|
{
|
||||||
|
@ -57,8 +58,9 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
|
||||||
if (table == info->open_tables)
|
if (table == info->open_tables)
|
||||||
{
|
{
|
||||||
err=mi_rkey(mi,0,inx,key,key_len,search_flag);
|
err=mi_rkey(mi,0,inx,key,key_len,search_flag);
|
||||||
|
/* Get the saved packed key and packed key length. */
|
||||||
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
|
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
|
||||||
pack_key_length=mi->last_rkey_length;
|
pack_key_length=mi->pack_key_length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -71,17 +73,22 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
|
||||||
{
|
{
|
||||||
if (err == HA_ERR_KEY_NOT_FOUND)
|
if (err == HA_ERR_KEY_NOT_FOUND)
|
||||||
continue;
|
continue;
|
||||||
return err;
|
DBUG_PRINT("exit", ("err: %d", err));
|
||||||
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
/* adding to queue */
|
/* adding to queue */
|
||||||
queue_insert(&(info->by_key),(byte *)table);
|
queue_insert(&(info->by_key),(byte *)table);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("tables with matches: %u", info->by_key.elements));
|
||||||
if (!info->by_key.elements)
|
if (!info->by_key.elements)
|
||||||
return HA_ERR_KEY_NOT_FOUND;
|
DBUG_RETURN(HA_ERR_KEY_NOT_FOUND);
|
||||||
|
|
||||||
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
|
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
|
||||||
mi->once_flags|= RRND_PRESERVE_LASTINX;
|
mi->once_flags|= RRND_PRESERVE_LASTINX;
|
||||||
return _myrg_mi_read_record(mi,buf);
|
DBUG_PRINT("info", ("using table no: %d",
|
||||||
|
info->current_table - info->open_tables + 1));
|
||||||
|
DBUG_DUMP("result key", (byte*) mi->lastkey, mi->lastkey_length);
|
||||||
|
DBUG_RETURN(_myrg_mi_read_record(mi,buf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -653,6 +653,32 @@ ERROR HY000: You can't specify target table 't2' for update in FROM clause
|
||||||
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
|
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
|
||||||
ERROR HY000: You can't specify target table 't2' for update in FROM clause
|
ERROR HY000: You can't specify target table 't2' for update in FROM clause
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
create table t1 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=merge union=(t2,t3);
|
||||||
|
create table t2 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=myisam;
|
||||||
|
create table t3 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=myisam;
|
||||||
|
insert into t2 values ( null, '');
|
||||||
|
insert into t2 values ( 9999999999.999999, '');
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
select min(a), max(a) from t1;
|
||||||
|
min(a) max(a)
|
||||||
|
9999999999.999998 9999999999.999998
|
||||||
|
flush tables;
|
||||||
|
select min(a), max(a) from t1;
|
||||||
|
min(a) max(a)
|
||||||
|
9999999999.999998 9999999999.999998
|
||||||
|
drop table t1, t2, t3;
|
||||||
create table t1 (a int,b int,c int, index (a,b,c));
|
create table t1 (a int,b int,c int, index (a,b,c));
|
||||||
create table t2 (a int,b int,c int, index (a,b,c));
|
create table t2 (a int,b int,c int, index (a,b,c));
|
||||||
create table t3 (a int,b int,c int, index (a,b,c))
|
create table t3 (a int,b int,c int, index (a,b,c))
|
||||||
|
|
|
@ -288,6 +288,42 @@ create table t3 engine=merge union=(t1, t2) select * from t2;
|
||||||
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
|
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#9112 - Merge table with composite index producing invalid results with some queries
|
||||||
|
# This test case will fail only without the bugfix and some
|
||||||
|
# non-deterministic circumstances. It depends on properly initialized
|
||||||
|
# "un-initialized" memory. At the time it happens with a standard
|
||||||
|
# non-debug build. But there is no guarantee that this will be always so.
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=merge union=(t2,t3);
|
||||||
|
|
||||||
|
create table t2 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=myisam;
|
||||||
|
|
||||||
|
create table t3 (
|
||||||
|
a double(16,6),
|
||||||
|
b varchar(10),
|
||||||
|
index (a,b)
|
||||||
|
) engine=myisam;
|
||||||
|
|
||||||
|
insert into t2 values ( null, '');
|
||||||
|
# We may have insufficient accuracy for 16 digits of '9'.
|
||||||
|
# Suppress a "truncate" warning due to accuracy problems.
|
||||||
|
--disable_warnings
|
||||||
|
insert into t2 values ( 9999999999.999999, '');
|
||||||
|
--enable_warnings
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
select min(a), max(a) from t1;
|
||||||
|
flush tables;
|
||||||
|
select min(a), max(a) from t1;
|
||||||
|
drop table t1, t2, t3;
|
||||||
# BUG#6699 : no sorting on 'ref' retrieval
|
# BUG#6699 : no sorting on 'ref' retrieval
|
||||||
create table t1 (a int,b int,c int, index (a,b,c));
|
create table t1 (a int,b int,c int, index (a,b,c));
|
||||||
create table t2 (a int,b int,c int, index (a,b,c));
|
create table t2 (a int,b int,c int, index (a,b,c));
|
||||||
|
|
Loading…
Add table
Reference in a new issue