mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-4.0
into mysql.com:/my/mysql-4.0 sql/sql_update.cc: Auto merged
This commit is contained in:
commit
6f6e0a7ab4
40 changed files with 571 additions and 66 deletions
|
@ -180,11 +180,17 @@ enum ha_base_keytype {
|
|||
/* poor old NISAM has 8-bit flags :-( */
|
||||
#define HA_SORT_ALLOWS_SAME 128 /* Intern bit when sorting records */
|
||||
#endif
|
||||
/*
|
||||
Key has a part that can have end space. If this is an unique key
|
||||
we have to handle it differently from other unique keys as we can find
|
||||
many matching rows for one key (becaue end space are not compared)
|
||||
*/
|
||||
#define HA_END_SPACE_KEY 4096
|
||||
|
||||
/* These flags can be order to key-seg-flag */
|
||||
/* These flags can be added to key-seg-flag */
|
||||
|
||||
#define HA_SPACE_PACK 1 /* Pack space in key-seg */
|
||||
#define HA_PART_KEY 4 /* Used by MySQL for part-key-cols */
|
||||
#define HA_PART_KEY_SEG 4 /* Used by MySQL for part-key-cols */
|
||||
#define HA_VAR_LENGTH 8
|
||||
#define HA_NULL_PART 16
|
||||
#define HA_BLOB_PART 32
|
||||
|
|
|
@ -126,7 +126,7 @@ int chk_status(MI_CHECK *param, register MI_INFO *info)
|
|||
int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
|
||||
{
|
||||
reg2 ha_rows i;
|
||||
uint j,delete_link_length;
|
||||
uint delete_link_length;
|
||||
my_off_t empty,next_link,old_link;
|
||||
char buff[22],buff2[22];
|
||||
DBUG_ENTER("chk_del");
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "myisamdef.h"
|
||||
#include "m_ctype.h"
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
@ -388,53 +389,86 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
|||
return(-1); /* Wrong data to read */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Update auto_increment info
|
||||
|
||||
/* Update auto_increment info */
|
||||
SYNOPSIS
|
||||
update_auto_increment()
|
||||
info MyISAM handler
|
||||
record Row to update
|
||||
|
||||
IMPLEMENTATION
|
||||
Only replace the auto_increment value if it is higher than the previous
|
||||
one. For signed columns we don't update the auto increment value if it's
|
||||
less than zero.
|
||||
*/
|
||||
|
||||
void update_auto_increment(MI_INFO *info,const byte *record)
|
||||
{
|
||||
ulonglong value;
|
||||
MI_KEYSEG *keyseg=info->s->keyinfo[info->s->base.auto_key-1].seg;
|
||||
const uchar *key=(uchar*) record+keyseg->start;
|
||||
ulonglong value= 0; /* Store unsigned values here */
|
||||
longlong s_value= 0; /* Store signed values here */
|
||||
MI_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
|
||||
const uchar *key= (uchar*) record + keyseg->start;
|
||||
|
||||
switch (keyseg->type) {
|
||||
case HA_KEYTYPE_INT8:
|
||||
s_value= (longlong) *(char*)key;
|
||||
break;
|
||||
case HA_KEYTYPE_BINARY:
|
||||
value=(ulonglong) *(uchar*) key;
|
||||
break;
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
s_value= (longlong) sint2korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
value=(ulonglong) uint2korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
s_value= (longlong) sint4korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
value=(ulonglong) uint4korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
s_value= (longlong) sint3korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_UINT24:
|
||||
value=(ulonglong) uint3korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
|
||||
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
|
||||
{
|
||||
float f_1;
|
||||
float4get(f_1,key);
|
||||
value = (ulonglong) f_1;
|
||||
/* Ignore negative values */
|
||||
value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
|
||||
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
|
||||
{
|
||||
double f_1;
|
||||
float8get(f_1,key);
|
||||
value = (ulonglong) f_1;
|
||||
/* Ignore negative values */
|
||||
value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
s_value= sint8korr(key);
|
||||
break;
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
value= uint8korr(key);
|
||||
break;
|
||||
default:
|
||||
value=0; /* Error */
|
||||
DBUG_ASSERT(0);
|
||||
value=0; /* Error */
|
||||
break;
|
||||
}
|
||||
set_if_bigger(info->s->state.auto_increment,value);
|
||||
|
||||
/*
|
||||
The following code works becasue if s_value < 0 then value is 0
|
||||
and if s_value == 0 then value will contain either s_value or the
|
||||
correct value.
|
||||
*/
|
||||
set_if_bigger(info->s->state.auto_increment,
|
||||
(s_value > 0) ? (ulonglong) s_value : value);
|
||||
}
|
||||
|
|
|
@ -815,6 +815,8 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
|
|||
state->status = mi_uint4korr(ptr); ptr +=4;
|
||||
state->update_count=mi_uint4korr(ptr); ptr +=4;
|
||||
|
||||
ptr+= state->state_diff_length;
|
||||
|
||||
for (i=0; i < keys; i++)
|
||||
{
|
||||
state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
|
||||
|
@ -823,7 +825,6 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
|
|||
{
|
||||
state->key_del[i] = mi_sizekorr(ptr); ptr +=8;
|
||||
}
|
||||
ptr+= state->state_diff_length;
|
||||
state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
|
||||
state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
|
||||
state->version = mi_uint4korr(ptr); ptr +=4;
|
||||
|
|
|
@ -783,7 +783,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
|
@ -801,7 +802,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
}
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX)
|
||||
&& next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a=end;
|
||||
b+=length;
|
||||
|
@ -817,7 +819,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
|
@ -828,7 +831,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
uint length=keyseg->length;
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,length,b,length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=length;
|
||||
b+=length;
|
||||
|
@ -841,9 +845,17 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
get_key_pack_length(b_length,pack_length,b);
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (!(nextflag & (SEARCH_PREFIX | SEARCH_UPDATE)))
|
||||
{
|
||||
while (a_length && a[a_length-1] == ' ')
|
||||
a_length--;
|
||||
while (b_length && b[b_length-1] == ' ')
|
||||
b_length--;
|
||||
}
|
||||
if (piks &&
|
||||
(flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
|
@ -859,7 +871,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
|
|||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0))))
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
|
|
|
@ -105,3 +105,29 @@ Table Op Msg_type Msg_text
|
|||
test.t1 check warning Found row where the auto_increment column has the value 0
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
create table t1 (a int not null auto_increment primary key);
|
||||
insert into t1 values (NULL);
|
||||
insert into t1 values (-1);
|
||||
select last_insert_id();
|
||||
last_insert_id()
|
||||
1
|
||||
insert into t1 values (NULL);
|
||||
select * from t1;
|
||||
a
|
||||
-1
|
||||
1
|
||||
2
|
||||
drop table t1;
|
||||
create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */;
|
||||
insert into t1 values (NULL);
|
||||
insert into t1 values (-1);
|
||||
select last_insert_id();
|
||||
last_insert_id()
|
||||
1
|
||||
insert into t1 values (NULL);
|
||||
select * from t1;
|
||||
a
|
||||
-1
|
||||
1
|
||||
2
|
||||
drop table t1;
|
||||
|
|
|
@ -65,6 +65,7 @@ a b
|
|||
alter table t1 modify b tinytext not null, drop key b, add key (b(100));
|
||||
select * from t1 where b="hello ";
|
||||
a b
|
||||
hello hello
|
||||
select * from t1 ignore index (b) where b="hello ";
|
||||
a b
|
||||
hello hello
|
||||
|
|
|
@ -164,6 +164,9 @@ NULL '\0\Z'
|
|||
select length(quote(concat(char(0),"test")));
|
||||
length(quote(concat(char(0),"test")))
|
||||
8
|
||||
select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))));
|
||||
hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))))
|
||||
27E0E3E6E7E8EAEB27
|
||||
select reverse("");
|
||||
reverse("")
|
||||
|
||||
|
|
|
@ -431,3 +431,12 @@ select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
|
|||
start ctime1 ctime2
|
||||
2002-11-04 00:00:00 2002-10-29 16:51:06 2002-11-05 16:47:31
|
||||
drop table t1,t2,t3;
|
||||
select @a:=FROM_UNIXTIME(1);
|
||||
@a:=FROM_UNIXTIME(1)
|
||||
1970-01-01 03:00:01
|
||||
select unix_timestamp(@a);
|
||||
unix_timestamp(@a)
|
||||
1
|
||||
select unix_timestamp('1969-12-01 19:00:01');
|
||||
unix_timestamp('1969-12-01 19:00:01')
|
||||
0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
Variable_name Value
|
||||
timezone MEST
|
||||
timezone MET
|
|
@ -1233,3 +1233,13 @@ create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, pri
|
|||
insert into t2 select * from t1;
|
||||
delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
|
||||
drop table t1,t2;
|
||||
SET AUTOCOMMIT=1;
|
||||
create table t1 (a integer auto_increment primary key) type=innodb;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
truncate table t1;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
SELECT * from t1;
|
||||
a
|
||||
3
|
||||
4
|
||||
drop table t1;
|
||||
|
|
|
@ -327,6 +327,16 @@ select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and
|
|||
a b a b
|
||||
2 2 NULL NULL
|
||||
drop table t1,t2;
|
||||
create table t1 (a int not null auto_increment primary key, b int not null);
|
||||
insert into t1 (b) values (1),(2),(3),(4);
|
||||
update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a;
|
||||
select * from t1;
|
||||
a b
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
drop table t1;
|
||||
drop table if exists t1, t2;
|
||||
create table t1(id1 smallint(5), field char(5));
|
||||
create table t2(id2 smallint(5), field char(5));
|
||||
|
|
|
@ -64,3 +64,23 @@ t9 CREATE TABLE `t9` (
|
|||
PRIMARY KEY (`a`)
|
||||
) TYPE=MyISAM DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/'
|
||||
drop database mysqltest;
|
||||
create table t1 (a int not null) type=myisam;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM
|
||||
alter table t1 add b int;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) default NULL
|
||||
) TYPE=MyISAM
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) default NULL
|
||||
) TYPE=MyISAM
|
||||
drop table t1;
|
||||
|
|
|
@ -23,3 +23,9 @@ ts from_unixtime(ts)
|
|||
1048989599 2003-03-30 03:59:59
|
||||
1048989601 2003-03-30 04:00:01
|
||||
DROP TABLE t1;
|
||||
select @a:=FROM_UNIXTIME(1);
|
||||
@a:=FROM_UNIXTIME(1)
|
||||
1970-01-01 01:00:01
|
||||
select unix_timestamp(@a);
|
||||
unix_timestamp(@a)
|
||||
1
|
||||
|
|
|
@ -23,3 +23,12 @@ n
|
|||
drop table t1;
|
||||
truncate non_existing_table;
|
||||
Table 'test.non_existing_table' doesn't exist
|
||||
create table t1 (a integer auto_increment primary key);
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
truncate table t1;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
SELECT * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
drop table t1;
|
||||
|
|
|
@ -455,3 +455,149 @@ select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
|
|||
if(imagem is null, "ERROR", "OK") length(imagem)
|
||||
OK 581
|
||||
drop table t1;
|
||||
create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20)));
|
||||
insert into t1 (txt) values ('Chevy'), ('Chevy ');
|
||||
select * from t1 where txt='Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy ' or txt='Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where id='1' or id='2';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
insert into t1 (txt) values('Ford');
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
3 Ford
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt in ('Chevy ','Chevy');
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt in ('Chevy');
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt < 'Chevy ';
|
||||
id txt
|
||||
select * from t1 where txt <= 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt > 'Chevy';
|
||||
id txt
|
||||
3 Ford
|
||||
select * from t1 where txt >= 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
3 Ford
|
||||
drop table t1;
|
||||
create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
|
||||
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
id txt
|
||||
3 NULL
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy ' or txt='Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where id='1' or id='2';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
insert into t1 (txt) values('Ford');
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
4 Ford
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt in ('Chevy ','Chevy');
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt in ('Chevy');
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt < 'Chevy ';
|
||||
id txt
|
||||
select * from t1 where txt < 'Chevy ' or txt is NULL;
|
||||
id txt
|
||||
3 NULL
|
||||
select * from t1 where txt <= 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
select * from t1 where txt > 'Chevy';
|
||||
id txt
|
||||
4 Ford
|
||||
select * from t1 where txt >= 'Chevy';
|
||||
id txt
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
4 Ford
|
||||
drop table t1;
|
||||
|
|
|
@ -70,3 +70,22 @@ select * from t1;
|
|||
check table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test negative values (Bug #1366)
|
||||
#
|
||||
|
||||
create table t1 (a int not null auto_increment primary key);
|
||||
insert into t1 values (NULL);
|
||||
insert into t1 values (-1);
|
||||
select last_insert_id();
|
||||
insert into t1 values (NULL);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */;
|
||||
insert into t1 values (NULL);
|
||||
insert into t1 values (-1);
|
||||
select last_insert_id();
|
||||
insert into t1 values (NULL);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -67,6 +67,7 @@ select quote('\'\"\\test');
|
|||
select quote(concat('abc\'', '\\cba'));
|
||||
select quote(1/0), quote('\0\Z');
|
||||
select length(quote(concat(char(0),"test")));
|
||||
select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))));
|
||||
|
||||
#
|
||||
# Wrong usage of functions
|
||||
|
|
|
@ -201,3 +201,10 @@ select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
|
|||
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
|
||||
select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
|
||||
drop table t1,t2,t3;
|
||||
|
||||
#
|
||||
# Test unix timestamp
|
||||
#
|
||||
select @a:=FROM_UNIXTIME(1);
|
||||
select unix_timestamp(@a);
|
||||
select unix_timestamp('1969-12-01 19:00:01');
|
||||
|
|
|
@ -857,3 +857,15 @@ insert into t2 select * from t1;
|
|||
|
||||
delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# test autoincrement with TRUNCATE
|
||||
#
|
||||
|
||||
SET AUTOCOMMIT=1;
|
||||
create table t1 (a integer auto_increment primary key) type=innodb;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
truncate table t1;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
SELECT * from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -268,6 +268,16 @@ update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1
|
|||
select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# Test reuse of same table
|
||||
#
|
||||
|
||||
create table t1 (a int not null auto_increment primary key, b int not null);
|
||||
insert into t1 (b) values (1),(2),(3),(4);
|
||||
update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
# Test multi-update and multi-delete with impossible where
|
||||
|
||||
drop table if exists t1, t2;
|
||||
|
|
|
@ -90,3 +90,25 @@ select count(*) from mysqltest.t9;
|
|||
--replace_result $MYSQL_TEST_DIR TEST_DIR
|
||||
show create table mysqltest.t9;
|
||||
drop database mysqltest;
|
||||
|
||||
#
|
||||
# Test changing data dir (Bug #1662)
|
||||
#
|
||||
|
||||
create table t1 (a int not null) type=myisam;
|
||||
disable_query_log;
|
||||
eval alter table t1 data directory="$MYSQL_TEST_DIR/var/tmp";
|
||||
enable_query_log;
|
||||
--replace_result $MYSQL_TEST_DIR TEST_DIR
|
||||
show create table t1;
|
||||
alter table t1 add b int;
|
||||
disable_query_log;
|
||||
eval alter table t1 data directory="$MYSQL_TEST_DIR/var/log";
|
||||
enable_query_log;
|
||||
--replace_result $MYSQL_TEST_DIR TEST_DIR
|
||||
show create table t1;
|
||||
disable_query_log;
|
||||
eval alter table t1 index directory="$MYSQL_TEST_DIR/var/log";
|
||||
enable_query_log;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Test of timezone handling. This script must be run with TZ=MEST
|
||||
# Test of timezone handling. This script must be run with TZ=MET
|
||||
|
||||
-- require r/have_mest_timezone.require
|
||||
-- require r/have_met_timezone.require
|
||||
disable_query_log;
|
||||
show variables like "timezone";
|
||||
enable_query_log;
|
||||
|
@ -26,3 +26,9 @@ INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01'));
|
|||
|
||||
SELECT ts,from_unixtime(ts) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test unix timestamp
|
||||
#
|
||||
select @a:=FROM_UNIXTIME(1);
|
||||
select unix_timestamp(@a);
|
||||
|
|
|
@ -21,3 +21,15 @@ select * from t1;
|
|||
drop table t1;
|
||||
--error 1146
|
||||
truncate non_existing_table;
|
||||
|
||||
#
|
||||
# test autoincrement with TRUNCATE
|
||||
#
|
||||
|
||||
create table t1 (a integer auto_increment primary key);
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
truncate table t1;
|
||||
insert into t1 (a) values (NULL),(NULL);
|
||||
SELECT * from t1;
|
||||
drop table t1;
|
||||
|
||||
|
|
|
@ -263,3 +263,52 @@ insert into t1 (id) values (1);
|
|||
update t1 set imagem=load_file('../../std_data/words.dat') where id=1;
|
||||
select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test blob's with end space (Bug #1651)
|
||||
#
|
||||
|
||||
create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20)));
|
||||
insert into t1 (txt) values ('Chevy'), ('Chevy ');
|
||||
select * from t1 where txt='Chevy';
|
||||
select * from t1 where txt='Chevy ';
|
||||
select * from t1 where txt='Chevy ' or txt='Chevy';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
select * from t1 where id='1' or id='2';
|
||||
insert into t1 (txt) values('Ford');
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
|
||||
select * from t1 where txt in ('Chevy ','Chevy');
|
||||
select * from t1 where txt in ('Chevy');
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy';
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy ';
|
||||
select * from t1 where txt < 'Chevy ';
|
||||
select * from t1 where txt <= 'Chevy';
|
||||
select * from t1 where txt > 'Chevy';
|
||||
select * from t1 where txt >= 'Chevy';
|
||||
drop table t1;
|
||||
|
||||
create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
|
||||
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
select * from t1 where txt='Chevy ';
|
||||
select * from t1 where txt='Chevy ' or txt='Chevy';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
select * from t1 where id='1' or id='2';
|
||||
insert into t1 (txt) values('Ford');
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
|
||||
select * from t1 where txt in ('Chevy ','Chevy');
|
||||
select * from t1 where txt in ('Chevy');
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy';
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
|
||||
select * from t1 where txt between 'Chevy' and 'Chevy ';
|
||||
select * from t1 where txt < 'Chevy ';
|
||||
select * from t1 where txt < 'Chevy ' or txt is NULL;
|
||||
select * from t1 where txt <= 'Chevy';
|
||||
select * from t1 where txt > 'Chevy';
|
||||
select * from t1 where txt >= 'Chevy';
|
||||
drop table t1;
|
||||
|
|
|
@ -31,9 +31,19 @@ File my_create_with_symlink(const char *linkname, const char *filename,
|
|||
File file;
|
||||
int tmp_errno;
|
||||
/* Test if we should create a link */
|
||||
int create_link=(linkname && strcmp(linkname,filename));
|
||||
int create_link;
|
||||
DBUG_ENTER("my_create_with_symlink");
|
||||
|
||||
if (my_disable_symlinks)
|
||||
{
|
||||
/* Create only the file, not the link and file */
|
||||
create_link= 0;
|
||||
if (linkname)
|
||||
filename= linkname;
|
||||
}
|
||||
else
|
||||
create_link= (linkname && strcmp(linkname,filename));
|
||||
|
||||
if (!(MyFlags & MY_DELETE_OLD))
|
||||
{
|
||||
if (!access(filename,F_OK))
|
||||
|
|
|
@ -799,9 +799,10 @@ public:
|
|||
binary_flag(binary_arg)
|
||||
{
|
||||
if (binary_arg)
|
||||
flags|=BINARY_FLAG;
|
||||
flags|= BINARY_FLAG;
|
||||
}
|
||||
Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||
Field_varstring(uint32 len_arg,bool maybe_null_arg,
|
||||
const char *field_name_arg,
|
||||
struct st_table *table_arg, bool binary_arg)
|
||||
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||
NONE, field_name_arg, table_arg),
|
||||
|
@ -856,7 +857,7 @@ public:
|
|||
{
|
||||
flags|= BLOB_FLAG;
|
||||
if (binary_arg)
|
||||
flags|=BINARY_FLAG;
|
||||
flags|= BINARY_FLAG;
|
||||
}
|
||||
enum_field_types type() const { return FIELD_TYPE_BLOB;}
|
||||
enum ha_base_keytype key_type() const
|
||||
|
|
|
@ -1788,7 +1788,7 @@ ha_innobase::store_key_val_for_row(
|
|||
|| mysql_type == FIELD_TYPE_BLOB
|
||||
|| mysql_type == FIELD_TYPE_LONG_BLOB) {
|
||||
|
||||
ut_a(key_part->key_part_flag & HA_PART_KEY);
|
||||
ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
|
||||
|
||||
if (is_null) {
|
||||
buff += key_part->length + 2;
|
||||
|
@ -3270,7 +3270,7 @@ create_index(
|
|||
for (i = 0; i < n_fields; i++) {
|
||||
key_part = key->key_part + i;
|
||||
|
||||
/* (The flag HA_PART_KEY denotes in MySQL a column prefix
|
||||
/* (The flag HA_PART_KEY_SEG denotes in MySQL a column prefix
|
||||
field in an index: we only store a specified number of first
|
||||
bytes of the column to the index field.) The flag does not
|
||||
seem to be properly set by MySQL. Let us fall back on testing
|
||||
|
|
|
@ -2169,7 +2169,7 @@ String *Item_func_quote::val_str(String *str)
|
|||
new_length= arg_length+2; /* for beginning and ending ' signs */
|
||||
|
||||
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
|
||||
new_length+= get_esc_bit(escmask, *from);
|
||||
new_length+= get_esc_bit(escmask, (uchar) *from);
|
||||
|
||||
/*
|
||||
We have to use realloc() instead of alloc() as we want to keep the
|
||||
|
|
|
@ -364,6 +364,7 @@ void mysql_execute_command(void);
|
|||
bool do_command(THD *thd);
|
||||
bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
char* packet, uint packet_length);
|
||||
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool check_stack_overrun(THD *thd,char *dummy);
|
||||
#else
|
||||
|
|
|
@ -942,9 +942,10 @@ static SEL_ARG *
|
|||
get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
||||
Item_func::Functype type,Item *value)
|
||||
{
|
||||
uint maybe_null=(uint) field->real_maybe_null();
|
||||
uint maybe_null=(uint) field->real_maybe_null(), copies;
|
||||
uint field_length=field->pack_length()+maybe_null;
|
||||
SEL_ARG *tree;
|
||||
char *str, *str2;
|
||||
DBUG_ENTER("get_mm_leaf");
|
||||
|
||||
if (type == Item_func::LIKE_FUNC)
|
||||
|
@ -1056,15 +1057,39 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
/* This happens when we try to insert a NULL field in a not null column */
|
||||
DBUG_RETURN(&null_element); // cmp with NULL is never true
|
||||
}
|
||||
// Get local copy of key
|
||||
char *str= (char*) alloc_root(param->mem_root,
|
||||
key_part->part_length+maybe_null);
|
||||
/* Get local copy of key */
|
||||
copies= 1;
|
||||
if (field->key_type() == HA_KEYTYPE_VARTEXT)
|
||||
copies= 2;
|
||||
str= str2= (char*) alloc_root(param->mem_root,
|
||||
(key_part->part_length+maybe_null)*copies);
|
||||
if (!str)
|
||||
DBUG_RETURN(0);
|
||||
if (maybe_null)
|
||||
*str= (char) field->is_real_null(); // Set to 1 if null
|
||||
field->get_key_image(str+maybe_null,key_part->part_length);
|
||||
if (!(tree=new SEL_ARG(field,str,str)))
|
||||
if (copies == 2)
|
||||
{
|
||||
/*
|
||||
The key is stored as 2 byte length + key
|
||||
key doesn't match end space. In other words, a key 'X ' should match
|
||||
all rows between 'X' and 'X ...'
|
||||
*/
|
||||
uint length= uint2korr(str+maybe_null);
|
||||
char *end;
|
||||
str2= str+ key_part->part_length + maybe_null;
|
||||
/* remove end space. The 2 is for the packed length */
|
||||
while (length > 0 && str[length+2+maybe_null-1] == ' ')
|
||||
length--;
|
||||
int2store(str+maybe_null, length);
|
||||
/* Create key that is space filled */
|
||||
memcpy(str2, str, length+2+maybe_null);
|
||||
end= str2+ maybe_null + key_part->part_length;
|
||||
for (char *pos= str2+ 2+ length + maybe_null; pos < end ; pos++)
|
||||
*pos++= ' ';
|
||||
int2store(str2+maybe_null, key_part->part_length);
|
||||
}
|
||||
if (!(tree=new SEL_ARG(field,str,str2)))
|
||||
DBUG_RETURN(0); // out of memory
|
||||
|
||||
switch (type) {
|
||||
|
@ -2233,7 +2258,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
|||
param->range_count++;
|
||||
if (!tmp_min_flag && ! tmp_max_flag &&
|
||||
(uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
|
||||
(param->table->key_info[keynr].flags & HA_NOSAME) &&
|
||||
(param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
|
||||
HA_NOSAME &&
|
||||
min_key_length == max_key_length &&
|
||||
!memcmp(param->min_key,param->max_key,min_key_length))
|
||||
tmp=1; // Max one record
|
||||
|
@ -2367,7 +2393,8 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
|
|||
{
|
||||
KEY *table_key=quick->head->key_info+quick->index;
|
||||
flag=EQ_RANGE;
|
||||
if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1)
|
||||
if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
|
||||
key->part == table_key->key_parts-1)
|
||||
{
|
||||
if (!(table_key->flags & HA_NULL_PART_KEY) ||
|
||||
!null_part_in_key(key,
|
||||
|
@ -2412,7 +2439,7 @@ bool QUICK_SELECT::unique_key_range()
|
|||
if (((tmp=ranges.head())->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
|
||||
{
|
||||
KEY *key=head->key_info+index;
|
||||
return ((key->flags & HA_NOSAME) &&
|
||||
return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
|
||||
key->key_length == tmp->min_length);
|
||||
}
|
||||
}
|
||||
|
@ -2465,7 +2492,8 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
|
|||
range->min_key=range->max_key=(char*) ref->key_buff;
|
||||
range->min_length=range->max_length=ref->key_length;
|
||||
range->flag= ((ref->key_length == key_info->key_length &&
|
||||
(key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0);
|
||||
(key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
|
||||
HA_NOSAME) ? EQ_RANGE : 0);
|
||||
|
||||
if (!(quick->key_parts=key_part=(KEY_PART *)
|
||||
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
|
||||
|
|
|
@ -99,11 +99,12 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
|
|||
info->read_record=rr_sequential;
|
||||
table->file->rnd_init();
|
||||
/* We can use record cache if we don't update dynamic length tables */
|
||||
if (use_record_cache > 0 ||
|
||||
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
|
||||
!(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
|
||||
(use_record_cache < 0 &&
|
||||
!(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE)))
|
||||
if (!table->no_cache &&
|
||||
(use_record_cache > 0 ||
|
||||
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
|
||||
!(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
|
||||
(use_record_cache < 0 &&
|
||||
!(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE))))
|
||||
VOID(table->file->extra_opt(HA_EXTRA_CACHE,
|
||||
thd->variables.read_buff_size));
|
||||
}
|
||||
|
|
|
@ -1202,11 +1202,11 @@ static const char *calc_ip(const char *ip, long *val, char end)
|
|||
static void update_hostname(acl_host_and_ip *host, const char *hostname)
|
||||
{
|
||||
host->hostname=(char*) hostname; // This will not be modified!
|
||||
if (hostname &&
|
||||
if (!hostname ||
|
||||
(!(hostname=calc_ip(hostname,&host->ip,'/')) ||
|
||||
!(hostname=calc_ip(hostname+1,&host->ip_mask,'\0'))))
|
||||
{
|
||||
host->ip=host->ip_mask=0; // Not a masked ip
|
||||
host->ip= host->ip_mask=0; // Not a masked ip
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ static int check_for_max_user_connections(USER_CONN *uc);
|
|||
static void decrease_user_connections(USER_CONN *uc);
|
||||
static bool check_db_used(THD *thd,TABLE_LIST *tables);
|
||||
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
|
||||
static bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
|
||||
static void mysql_init_query(THD *thd);
|
||||
static void remove_escape(char *name);
|
||||
static void refresh_status(void);
|
||||
|
@ -3600,7 +3599,7 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
|
|||
|
||||
/* Check if name is used in table list */
|
||||
|
||||
static bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
|
||||
bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
|
||||
{
|
||||
for (; tables ; tables=tables->next)
|
||||
if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db))
|
||||
|
|
|
@ -1261,7 +1261,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||
} while (keyuse->table == table && keyuse->key == key);
|
||||
|
||||
if (eq_part == PREV_BITS(uint,table->key_info[key].key_parts) &&
|
||||
(table->key_info[key].flags & HA_NOSAME) &&
|
||||
((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
|
||||
HA_NOSAME) &&
|
||||
!table->fulltext_searched)
|
||||
{
|
||||
if (const_ref == eq_part)
|
||||
|
@ -2027,7 +2028,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||
if (found_part == PREV_BITS(uint,keyinfo->key_parts))
|
||||
{ /* use eq key */
|
||||
max_key_part= (uint) ~0;
|
||||
if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
|
||||
if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
|
||||
HA_END_SPACE_KEY)) == HA_NOSAME)
|
||||
{
|
||||
tmp=prev_record_reads(join,found_ref);
|
||||
records=1.0;
|
||||
|
@ -2527,8 +2529,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
|||
if (j->type == JT_FT) /* no-op */;
|
||||
else if (j->type == JT_CONST)
|
||||
j->table->const_table=1;
|
||||
else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY))
|
||||
!= HA_NOSAME) ||
|
||||
else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
|
||||
HA_END_SPACE_KEY)) != HA_NOSAME) ||
|
||||
keyparts != keyinfo->key_parts)
|
||||
j->type=JT_REF; /* Must read with repeat */
|
||||
else if (ref_key == j->ref.key_copy)
|
||||
|
@ -5821,7 +5823,7 @@ part_of_refkey(TABLE *table,Field *field)
|
|||
|
||||
for (uint part=0 ; part < ref_parts ; part++,key_part++)
|
||||
if (field->eq(key_part->field) &&
|
||||
!(key_part->key_part_flag & HA_PART_KEY))
|
||||
!(key_part->key_part_flag & HA_PART_KEY_SEG))
|
||||
return table->reginfo.join_tab->ref.items[part];
|
||||
}
|
||||
return (Item*) 0;
|
||||
|
|
|
@ -288,10 +288,10 @@ static int sort_keys(KEY *a, KEY *b)
|
|||
{
|
||||
if (!(b->flags & HA_NOSAME))
|
||||
return -1;
|
||||
if ((a->flags ^ b->flags) & HA_NULL_PART_KEY)
|
||||
if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
|
||||
{
|
||||
/* Sort NOT NULL keys before other keys */
|
||||
return (a->flags & HA_NULL_PART_KEY) ? 1 : -1;
|
||||
return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
|
||||
}
|
||||
if (a->name == primary_key_name)
|
||||
return -1;
|
||||
|
@ -1695,8 +1695,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
}
|
||||
|
||||
/*
|
||||
** Collect all keys which isn't in drop list. Add only those
|
||||
** for which some fields exists.
|
||||
Collect all keys which isn't in drop list. Add only those
|
||||
for which some fields exists.
|
||||
*/
|
||||
|
||||
List_iterator<Key> key_it(keys);
|
||||
|
|
|
@ -544,6 +544,26 @@ int multi_update::prepare(List<Item> ¬_used_values)
|
|||
for (i=0 ; i < table_count ; i++)
|
||||
set_if_bigger(max_fields, fields_for_table[i]->elements);
|
||||
copy_field= new Copy_field[max_fields];
|
||||
|
||||
/*
|
||||
Mark all copies of tables that are updates to ensure that
|
||||
init_read_record() will not try to enable a cache on them
|
||||
|
||||
The problem is that for queries like
|
||||
|
||||
UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a;
|
||||
|
||||
the row buffer may contain things that doesn't match what is on disk
|
||||
which will cause an error when reading a row.
|
||||
(This issue is mostly relevent for MyISAM tables)
|
||||
*/
|
||||
for (table_ref= all_tables; table_ref; table_ref=table_ref->next)
|
||||
{
|
||||
TABLE *table=table_ref->table;
|
||||
if (!(tables_to_update & table->map) &&
|
||||
check_dup(table_ref->db, table_ref->real_name, update_tables))
|
||||
table->no_cache= 1; // Disable row cache
|
||||
}
|
||||
DBUG_RETURN(thd->fatal_error != 0);
|
||||
}
|
||||
|
||||
|
@ -684,7 +704,7 @@ multi_update::~multi_update()
|
|||
{
|
||||
TABLE_LIST *table;
|
||||
for (table= update_tables ; table; table= table->next)
|
||||
table->table->no_keyread=0;
|
||||
table->table->no_keyread= table->table->no_cache= 0;
|
||||
|
||||
if (tmp_tables)
|
||||
{
|
||||
|
|
21
sql/table.cc
21
sql/table.cc
|
@ -430,14 +430,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
|
||||
{
|
||||
/*
|
||||
If the UNIQUE key don't have NULL columns, declare this as
|
||||
a primary key.
|
||||
If the UNIQUE key doesn't have NULL columns and is not a part key
|
||||
declare this as a primary key.
|
||||
*/
|
||||
primary_key=key;
|
||||
for (i=0 ; i < keyinfo->key_parts ;i++)
|
||||
{
|
||||
if (!key_part[i].fieldnr ||
|
||||
outparam->field[key_part[i].fieldnr-1]->null_ptr)
|
||||
uint fieldnr= key_part[i].fieldnr;
|
||||
if (!fieldnr ||
|
||||
outparam->field[fieldnr-1]->null_ptr ||
|
||||
outparam->field[fieldnr-1]->key_length() !=
|
||||
key_part[i].length)
|
||||
{
|
||||
primary_key=MAX_KEY; // Can't be used
|
||||
break;
|
||||
|
@ -476,6 +479,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
|
||||
key_part->store_length+=HA_KEY_BLOB_LENGTH;
|
||||
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
|
||||
/*
|
||||
Mark that there may be many matching values for one key
|
||||
combination ('a', 'a ', 'a '...)
|
||||
*/
|
||||
if (!(field->flags & BINARY_FLAG))
|
||||
keyinfo->flags|= HA_END_SPACE_KEY;
|
||||
}
|
||||
if (i == 0 && key != primary_key)
|
||||
field->flags |=
|
||||
|
@ -513,7 +522,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||
}
|
||||
if (field->key_length() != key_part->length)
|
||||
{
|
||||
key_part->key_part_flag|= HA_PART_KEY;
|
||||
key_part->key_part_flag|= HA_PART_KEY_SEG;
|
||||
if (field->type() != FIELD_TYPE_BLOB)
|
||||
{ // Create a new field
|
||||
field=key_part->field=field->new_field(&outparam->mem_root,
|
||||
|
@ -527,7 +536,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||
as we need to test for NULL = NULL.
|
||||
*/
|
||||
if (field->real_maybe_null())
|
||||
key_part->key_part_flag|= HA_PART_KEY;
|
||||
key_part->key_part_flag|= HA_PART_KEY_SEG;
|
||||
}
|
||||
else
|
||||
{ // Error: shorten key
|
||||
|
|
|
@ -101,7 +101,7 @@ struct st_table {
|
|||
my_bool fulltext_searched;
|
||||
my_bool crashed;
|
||||
my_bool is_view;
|
||||
my_bool no_keyread;
|
||||
my_bool no_keyread, no_cache;
|
||||
Field *next_number_field, /* Set if next_number is activated */
|
||||
*found_next_number_field, /* Set on open */
|
||||
*rowid_field;
|
||||
|
|
|
@ -125,6 +125,8 @@ long my_gmt_sec(TIME *t, long *my_timezone)
|
|||
tmp-=t->minute*60 + t->second; // Move to previous hour
|
||||
}
|
||||
*my_timezone= current_timezone;
|
||||
if (tmp < 0 && t->year <= 1900+YY_PART_YEAR)
|
||||
tmp= 0;
|
||||
return (long) tmp;
|
||||
} /* my_gmt_sec */
|
||||
|
||||
|
@ -445,7 +447,7 @@ time_t str_to_timestamp(const char *str,uint length)
|
|||
|
||||
if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE)
|
||||
return(0);
|
||||
if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR)
|
||||
if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1)
|
||||
{
|
||||
current_thd->cuted_fields++;
|
||||
return(0);
|
||||
|
|
Loading…
Reference in a new issue