Commit 5d41d5e0 authored by ingo@mysql.com's avatar ingo@mysql.com

Merge mysql.com:/home/mydev/mysql-4.1-4100

into  mysql.com:/home/mydev/mysql-5.0-5000
parents 5845a6e5 330eb045
...@@ -318,19 +318,21 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -318,19 +318,21 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
get_key_pack_length(kseg_len,length_pack,kseg); get_key_pack_length(kseg_len,length_pack,kseg);
key_len_skip=length_pack+kseg_len; key_len_skip=length_pack+kseg_len;
key_len_left=(int) key_len- (int) key_len_skip; key_len_left=(int) key_len- (int) key_len_skip;
/* If key_len is 0, then lenght_pack is 1, then key_len_left is -1. */
cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack; cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg)); DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
/* /*
Keys are compressed the following way: Keys are compressed the following way:
If the max length of first key segment <= 127 characters the prefix is If the max length of first key segment <= 127 bytes the prefix is
1 byte else it's 2 byte 1 byte else it's 2 byte
prefix The high bit is set if this is a prefix for the prev key (prefix) length The high bit is set if this is a prefix for the prev key.
length Packed length if the previous was a prefix byte [suffix length] Packed length of suffix if the previous was a prefix.
[length] Length character of data (suffix) data Key data bytes (past the common prefix or whole segment).
next-key-seg Next key segments [next-key-seg] Next key segments (([packed length], data), ...)
pointer Reference to the data file (last_keyseg->length).
*/ */
matched=0; /* how many char's from prefix were alredy matched */ matched=0; /* how many char's from prefix were alredy matched */
...@@ -351,16 +353,23 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -351,16 +353,23 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if (packed) if (packed)
{ {
if (suffix_len == 0) /* Same key */ if (suffix_len == 0)
{
/* == 0x80 or 0x8000, same key, prefix length == old key length. */
prefix_len=len; prefix_len=len;
}
else else
{ {
/* > 0x80 or 0x8000, this is prefix lgt, packed suffix lgt follows. */
prefix_len=suffix_len; prefix_len=suffix_len;
get_key_length(suffix_len,vseg); get_key_length(suffix_len,vseg);
} }
} }
else else
{
/* Not packed. No prefix used from last key. */
prefix_len=0; prefix_len=0;
}
len=prefix_len+suffix_len; len=prefix_len+suffix_len;
seg_len_pack=get_pack_length(len); seg_len_pack=get_pack_length(len);
...@@ -417,7 +426,12 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -417,7 +426,12 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uint left; uint left;
uchar *k=kseg+prefix_len; uchar *k=kseg+prefix_len;
left=(len>cmplen) ? cmplen-prefix_len : suffix_len; /*
If prefix_len > cmplen then we are in the end-space comparison
phase. Do not try to acces the key any more ==> left= 0.
*/
left= ((len <= cmplen) ? suffix_len :
((prefix_len < cmplen) ? cmplen - prefix_len : 0));
matched=prefix_len+left; matched=prefix_len+left;
...@@ -455,7 +469,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -455,7 +469,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
my_flag= -1; my_flag= -1;
else else
{ {
/* We have to compare k and vseg as if they where space extended */ /* We have to compare k and vseg as if they were space extended */
uchar *end= k+ (cmplen - len); uchar *end= k+ (cmplen - len);
for ( ; k < end && *k == ' '; k++) ; for ( ; k < end && *k == ' '; k++) ;
if (k == end) if (k == end)
...@@ -474,7 +488,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -474,7 +488,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if ((nextflag & SEARCH_PREFIX) && key_len_left == 0) if ((nextflag & SEARCH_PREFIX) && key_len_left == 0)
goto fix_flag; goto fix_flag;
/* We have to compare k and vseg as if they where space extended */ /* We have to compare k and vseg as if they were space extended */
for (end=vseg + (len-cmplen) ; for (end=vseg + (len-cmplen) ;
vseg < end && *vseg == (uchar) ' '; vseg < end && *vseg == (uchar) ' ';
vseg++, matched++) ; vseg++, matched++) ;
......
...@@ -537,3 +537,18 @@ create table t1 ( a timestamp ); ...@@ -537,3 +537,18 @@ create table t1 ( a timestamp );
alter table t1 add unique ( a(1) ); alter table t1 add unique ( a(1) );
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
drop table t1; drop table t1;
create database mysqltest1;
create table t1 (c1 int);
alter table t1 rename mysqltest1.t1;
drop table t1;
ERROR 42S02: Unknown table 't1'
alter table mysqltest1.t1 rename t1;
drop table t1;
create table t1 (c1 int);
use mysqltest1;
drop database mysqltest1;
alter table test.t1 rename t1;
ERROR 3D000: No database selected
alter table test.t1 rename test.t1;
use test;
drop table t1;
...@@ -1703,6 +1703,22 @@ a_id b_list ...@@ -1703,6 +1703,22 @@ a_id b_list
3 NULL 3 NULL
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
create temporary table t1 (a int) engine=innodb;
insert into t1 values (4711);
truncate t1;
insert into t1 values (42);
select * from t1;
a
42
drop table t1;
create table t1 (a int) engine=innodb;
insert into t1 values (4711);
truncate t1;
insert into t1 values (42);
select * from t1;
a
42
drop table t1;
create table t1 (x bigint unsigned not null primary key) engine=innodb; create table t1 (x bigint unsigned not null primary key) engine=innodb;
insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1); insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
select * from t1; select * from t1;
......
...@@ -329,6 +329,22 @@ ERROR 42S21: Duplicate column name 'c1' ...@@ -329,6 +329,22 @@ ERROR 42S21: Duplicate column name 'c1'
alter table t1 add key (c1,c1,c2); alter table t1 add key (c1,c1,c2);
ERROR 42S21: Duplicate column name 'c1' ERROR 42S21: Duplicate column name 'c1'
drop table t1; drop table t1;
create table t1 (
c1 int,
c2 varchar(20) not null,
primary key (c1),
key (c2(10))
) engine=myisam;
insert into t1 values (1,'');
insert into t1 values (2,' \t\tTest String');
insert into t1 values (3,' \n\tTest String');
update t1 set c2 = 'New Test String' where c1 = 1;
select * from t1;
c1 c2
1 New Test String
2 Test String
3
Test String
create table t1 (a varchar(10), b varchar(10), key(a(10),b(10))); create table t1 (a varchar(10), b varchar(10), key(a(10),b(10)));
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -594,6 +594,20 @@ check table t1; ...@@ -594,6 +594,20 @@ check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; drop table t1;
create table t1 (c1 int);
insert into t1 values (1),(2),(3),(4);
checksum table t1;
Table Checksum
test.t1 149057747
delete from t1 where c1 = 1;
create table t2 as select * from t1;
checksum table t1;
Table Checksum
test.t1 984116287
checksum table t2;
Table Checksum
test.t2 984116287
drop table t1, t2;
set storage_engine=MyISAM; set storage_engine=MyISAM;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
--- Testing varchar --- --- Testing varchar ---
......
...@@ -361,4 +361,35 @@ create table t1 ( a timestamp ); ...@@ -361,4 +361,35 @@ create table t1 ( a timestamp );
alter table t1 add unique ( a(1) ); alter table t1 add unique ( a(1) );
drop table t1; drop table t1;
#
# Bug#11493 - Alter table rename to default database does not work without
# db name qualifying
#
create database mysqltest1;
create table t1 (c1 int);
# Move table to other database.
alter table t1 rename mysqltest1.t1;
# Assure that it has moved.
--error 1051
drop table t1;
# Move table back.
alter table mysqltest1.t1 rename t1;
# Assure that it is back.
drop table t1;
# Now test for correct message if no database is selected.
# Create t1 in 'test'.
create table t1 (c1 int);
# Change to other db.
use mysqltest1;
# Drop the current db. This de-selects any db.
drop database mysqltest1;
# Now test for correct message.
--error 1046
alter table test.t1 rename t1;
# Check that explicit qualifying works even with no selected db.
alter table test.t1 rename test.t1;
# Go back to standard 'test' db.
use test;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -1231,6 +1231,24 @@ SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t ...@@ -1231,6 +1231,24 @@ SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#11816 - Truncate table doesn't work with temporary innodb tables
# This is not an innodb bug, but we test it using innodb.
#
create temporary table t1 (a int) engine=innodb;
insert into t1 values (4711);
truncate t1;
insert into t1 values (42);
select * from t1;
drop table t1;
# Show that it works with permanent tables too.
create table t1 (a int) engine=innodb;
insert into t1 values (4711);
truncate t1;
insert into t1 values (42);
select * from t1;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
# #
......
...@@ -326,6 +326,20 @@ alter table t1 add key (c1,c1,c2); ...@@ -326,6 +326,20 @@ alter table t1 add key (c1,c1,c2);
drop table t1; drop table t1;
# #
# Bug#12565 - ERROR 1034 when running simple UPDATE or DELETE
# on large MyISAM table
#
create table t1 (
c1 int,
c2 varchar(20) not null,
primary key (c1),
key (c2(10))
) engine=myisam;
insert into t1 values (1,'');
insert into t1 values (2,' \t\tTest String');
insert into t1 values (3,' \n\tTest String');
update t1 set c2 = 'New Test String' where c1 = 1;
select * from t1;
# If we use a partial field for a key that is actually the length of the # If we use a partial field for a key that is actually the length of the
# field, and we extend the field, we end up with a key that includes the # field, and we extend the field, we end up with a key that includes the
# whole new length of the field. # whole new length of the field.
......
...@@ -563,6 +563,21 @@ update t1 set c2='A B' where c1=2; ...@@ -563,6 +563,21 @@ update t1 set c2='A B' where c1=2;
check table t1; check table t1;
drop table t1; drop table t1;
#
# Bug#12296 - CHECKSUM TABLE reports 0 for the table
# This happened if the first record was marked as deleted.
#
create table t1 (c1 int);
insert into t1 values (1),(2),(3),(4);
checksum table t1;
delete from t1 where c1 = 1;
create table t2 as select * from t1;
# The following returns 0 with the bug in place.
checksum table t1;
# The above should give the same number as the following.
checksum table t2;
drop table t1, t2;
# #
# Test varchar # Test varchar
# #
......
...@@ -768,6 +768,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -768,6 +768,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
TABLE *table= *table_ptr; TABLE *table= *table_ptr;
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
db_type table_type= table->s->db_type; db_type table_type= table->s->db_type;
if (!ha_supports_generate(table_type))
goto trunc_by_del;
strmov(path, table->s->path); strmov(path, table->s->path);
*table_ptr= table->next; // Unlink table from list *table_ptr= table->next; // Unlink table from list
close_temporary(table,0); close_temporary(table,0);
...@@ -786,7 +788,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -786,7 +788,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db, (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
table_list->table_name,reg_ext); table_list->table_name,reg_ext);
fn_format(path,path,"","",4); fn_format(path, path, "", "", MY_UNPACK_FILENAME);
if (!dont_send_ok) if (!dont_send_ok)
{ {
...@@ -798,19 +800,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -798,19 +800,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
if (!ha_supports_generate(table_type) || thd->lex->sphead) if (!ha_supports_generate(table_type) || thd->lex->sphead)
{ goto trunc_by_del;
/* Probably InnoDB table */
ulong save_options= thd->options;
table_list->lock_type= TL_WRITE;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
ha_enable_transaction(thd, FALSE);
mysql_init_select(thd->lex);
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
HA_POS_ERROR, LL(0));
ha_enable_transaction(thd, TRUE);
thd->options= save_options;
DBUG_RETURN(error);
}
if (lock_and_wait_for_table_name(thd, table_list)) if (lock_and_wait_for_table_name(thd, table_list))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
...@@ -844,4 +834,17 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -844,4 +834,17 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
DBUG_RETURN(error); DBUG_RETURN(error);
trunc_by_del:
/* Probably InnoDB table */
ulong save_options= thd->options;
table_list->lock_type= TL_WRITE;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
ha_enable_transaction(thd, FALSE);
mysql_init_select(thd->lex);
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
HA_POS_ERROR, LL(0));
ha_enable_transaction(thd, TRUE);
thd->options= save_options;
DBUG_RETURN(error);
} }
...@@ -2991,7 +2991,24 @@ mysql_execute_command(THD *thd) ...@@ -2991,7 +2991,24 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
if (!select_lex->db) if (!select_lex->db)
select_lex->db= first_table->db; {
/*
In the case of ALTER TABLE ... RENAME we should supply the
default database if the new name is not explicitly qualified
by a database. (Bug #11493)
*/
if (lex->alter_info.flags & ALTER_RENAME)
{
if (! thd->db)
{
send_error(thd,ER_NO_DB_ERROR);
goto error;
}
select_lex->db= thd->db;
}
else
select_lex->db= first_table->db;
}
if (check_access(thd, ALTER_ACL, first_table->db, if (check_access(thd, ALTER_ACL, first_table->db,
&first_table->grant.privilege, 0, 0) || &first_table->grant.privilege, 0, 0) ||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)|| check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)||
......
...@@ -4091,9 +4091,16 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) ...@@ -4091,9 +4091,16 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
protocol->store_null(); protocol->store_null();
else else
{ {
while (!t->file->rnd_next(t->record[0])) for (;;)
{ {
ha_checksum row_crc= 0; ha_checksum row_crc= 0;
int error= t->file->rnd_next(t->record[0]);
if (unlikely(error))
{
if (error == HA_ERR_RECORD_DELETED)
continue;
break;
}
if (t->record[0] != (byte*) t->field[0]->ptr) if (t->record[0] != (byte*) t->field[0]->ptr)
row_crc= my_checksum(row_crc, t->record[0], row_crc= my_checksum(row_crc, t->record[0],
((byte*) t->field[0]->ptr) - t->record[0]); ((byte*) t->field[0]->ptr) - t->record[0]);
......
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