Merge shellback.(none):/home/msvensson/mysql/mysql-5.0
into shellback.(none):/home/msvensson/mysql/mysql-5.0-maint BitKeeper/etc/ignore: auto-union sql/item_func.h: Auto merged sql/set_var.cc: Auto merged sql/sql_class.h: Auto merged
This commit is contained in:
commit
5d5ef8469a
@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
|
|||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
# The Docs Makefile.am parses this line!
|
# The Docs Makefile.am parses this line!
|
||||||
# remember to also change ndb version below and update version.c in ndb
|
# remember to also change ndb version below and update version.c in ndb
|
||||||
AM_INIT_AUTOMAKE(mysql, 5.0.26)
|
AM_INIT_AUTOMAKE(mysql, 5.0.27)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
PROTOCOL_VERSION=10
|
PROTOCOL_VERSION=10
|
||||||
@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
|
|||||||
# ndb version
|
# ndb version
|
||||||
NDB_VERSION_MAJOR=5
|
NDB_VERSION_MAJOR=5
|
||||||
NDB_VERSION_MINOR=0
|
NDB_VERSION_MINOR=0
|
||||||
NDB_VERSION_BUILD=26
|
NDB_VERSION_BUILD=27
|
||||||
NDB_VERSION_STATUS=""
|
NDB_VERSION_STATUS=""
|
||||||
|
|
||||||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||||
|
@ -446,7 +446,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_PRINT("test",("Inserting of key when deleting"));
|
DBUG_PRINT("test",("Inserting of key when deleting"));
|
||||||
if (_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
|
if (!_mi_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
|
||||||
&tmp))
|
&tmp))
|
||||||
goto err;
|
goto err;
|
||||||
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
|
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
|
||||||
|
@ -126,7 +126,6 @@ int main(int argc,char *argv[])
|
|||||||
|
|
||||||
if (count || stats)
|
if (count || stats)
|
||||||
{
|
{
|
||||||
doc_cnt++;
|
|
||||||
if (strcmp(buf, buf2))
|
if (strcmp(buf, buf2))
|
||||||
{
|
{
|
||||||
if (*buf2)
|
if (*buf2)
|
||||||
@ -151,6 +150,7 @@ int main(int argc,char *argv[])
|
|||||||
keylen2=keylen;
|
keylen2=keylen;
|
||||||
doc_cnt=0;
|
doc_cnt=0;
|
||||||
}
|
}
|
||||||
|
doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
|
||||||
}
|
}
|
||||||
if (dump)
|
if (dump)
|
||||||
{
|
{
|
||||||
@ -166,7 +166,6 @@ int main(int argc,char *argv[])
|
|||||||
|
|
||||||
if (count || stats)
|
if (count || stats)
|
||||||
{
|
{
|
||||||
doc_cnt++;
|
|
||||||
if (*buf2)
|
if (*buf2)
|
||||||
{
|
{
|
||||||
uniq++;
|
uniq++;
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
||||||
{
|
{
|
||||||
int save_errno,errpos=0;
|
int save_errno,errpos=0;
|
||||||
uint files=0,i,dir_length,length,key_parts;
|
uint files= 0, i, dir_length, length, key_parts, min_keys= 0;
|
||||||
ulonglong file_offset=0;
|
ulonglong file_offset=0;
|
||||||
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
|
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
|
||||||
MYRG_INFO *m_info=0;
|
MYRG_INFO *m_info=0;
|
||||||
@ -89,7 +89,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
|||||||
else
|
else
|
||||||
fn_format(buff, buff, "", "", 0);
|
fn_format(buff, buff, "", "", 0);
|
||||||
if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
|
if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
|
||||||
|
{
|
||||||
|
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
if (!m_info) /* First file */
|
if (!m_info) /* First file */
|
||||||
{
|
{
|
||||||
key_parts=isam->s->base.key_parts;
|
key_parts=isam->s->base.key_parts;
|
||||||
@ -106,6 +109,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
|||||||
files= 0;
|
files= 0;
|
||||||
}
|
}
|
||||||
m_info->reclength=isam->s->base.reclength;
|
m_info->reclength=isam->s->base.reclength;
|
||||||
|
min_keys= isam->s->base.keys;
|
||||||
errpos=3;
|
errpos=3;
|
||||||
}
|
}
|
||||||
m_info->open_tables[files].table= isam;
|
m_info->open_tables[files].table= isam;
|
||||||
@ -121,6 +125,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
|||||||
m_info->records+= isam->state->records;
|
m_info->records+= isam->state->records;
|
||||||
m_info->del+= isam->state->del;
|
m_info->del+= isam->state->del;
|
||||||
m_info->data_file_length+= isam->state->data_file_length;
|
m_info->data_file_length+= isam->state->data_file_length;
|
||||||
|
if (min_keys > isam->s->base.keys)
|
||||||
|
min_keys= isam->s->base.keys;
|
||||||
for (i=0; i < key_parts; i++)
|
for (i=0; i < key_parts; i++)
|
||||||
m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] /
|
m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] /
|
||||||
m_info->tables);
|
m_info->tables);
|
||||||
@ -138,7 +144,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
|||||||
my_errno=HA_ERR_RECORD_FILE_FULL;
|
my_errno=HA_ERR_RECORD_FILE_FULL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
m_info->keys= files ? isam->s->base.keys : 0;
|
m_info->keys= min_keys;
|
||||||
bzero((char*) &m_info->by_key,sizeof(m_info->by_key));
|
bzero((char*) &m_info->by_key,sizeof(m_info->by_key));
|
||||||
|
|
||||||
/* this works ok if the table list is empty */
|
/* this works ok if the table list is empty */
|
||||||
|
@ -65,6 +65,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
|
|||||||
error=my_errno;
|
error=my_errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
my_errno= error= HA_ERR_WRONG_INDEX;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ insert delayed into t1 set a = 4;
|
|||||||
insert delayed into t1 set a = 5, tmsp = 19711006010203;
|
insert delayed into t1 set a = 5, tmsp = 19711006010203;
|
||||||
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
|
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
|
||||||
insert delayed into t1 (a, tmsp) values (7, NULL);
|
insert delayed into t1 (a, tmsp) values (7, NULL);
|
||||||
|
FLUSH TABLE t1;
|
||||||
insert into t1 set a = 8,tmsp=19711006010203;
|
insert into t1 set a = 8,tmsp=19711006010203;
|
||||||
select * from t1 where tmsp=0;
|
select * from t1 where tmsp=0;
|
||||||
a tmsp
|
a tmsp
|
||||||
@ -22,6 +23,7 @@ insert delayed into t1 values (null,"c");
|
|||||||
insert delayed into t1 values (3,"d"),(null,"e");
|
insert delayed into t1 values (3,"d"),(null,"e");
|
||||||
insert delayed into t1 values (3,"this will give an","error");
|
insert delayed into t1 values (3,"this will give an","error");
|
||||||
ERROR 21S01: Column count doesn't match value count at row 1
|
ERROR 21S01: Column count doesn't match value count at row 1
|
||||||
|
FLUSH TABLE t1;
|
||||||
show status like 'not_flushed_delayed_rows';
|
show status like 'not_flushed_delayed_rows';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Not_flushed_delayed_rows 0
|
Not_flushed_delayed_rows 0
|
||||||
@ -54,6 +56,7 @@ insert delayed into t1 values(null);
|
|||||||
insert delayed into t1 values(null);
|
insert delayed into t1 values(null);
|
||||||
insert delayed into t1 values(null);
|
insert delayed into t1 values(null);
|
||||||
insert delayed into t1 values(null);
|
insert delayed into t1 values(null);
|
||||||
|
FLUSH TABLE t1;
|
||||||
select * from t1 order by a;
|
select * from t1 order by a;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
@ -69,3 +72,174 @@ a
|
|||||||
12
|
12
|
||||||
13
|
13
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
SET @bug20627_old_auto_increment_offset=
|
||||||
|
@@auto_increment_offset= 2;
|
||||||
|
SET @bug20627_old_auto_increment_increment=
|
||||||
|
@@auto_increment_increment= 3;
|
||||||
|
SET @bug20627_old_session_auto_increment_offset=
|
||||||
|
@@session.auto_increment_offset= 4;
|
||||||
|
SET @bug20627_old_session_auto_increment_increment=
|
||||||
|
@@session.auto_increment_increment= 5;
|
||||||
|
SET @@auto_increment_offset= 2;
|
||||||
|
SET @@auto_increment_increment= 3;
|
||||||
|
SET @@session.auto_increment_offset= 4;
|
||||||
|
SET @@session.auto_increment_increment= 5;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
4
|
||||||
|
9
|
||||||
|
14
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
INSERT DELAYED INTO t1 VALUES (NULL),(NULL),(NULL);
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
4
|
||||||
|
9
|
||||||
|
14
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@auto_increment_offset=
|
||||||
|
@bug20627_old_auto_increment_offset;
|
||||||
|
SET @@auto_increment_increment=
|
||||||
|
@bug20627_old_auto_increment_increment;
|
||||||
|
SET @@session.auto_increment_offset=
|
||||||
|
@bug20627_old_session_auto_increment_offset;
|
||||||
|
SET @@session.auto_increment_increment=
|
||||||
|
@bug20627_old_session_auto_increment_increment;
|
||||||
|
SET @bug20830_old_auto_increment_offset=
|
||||||
|
@@auto_increment_offset= 2;
|
||||||
|
SET @bug20830_old_auto_increment_increment=
|
||||||
|
@@auto_increment_increment= 3;
|
||||||
|
SET @bug20830_old_session_auto_increment_offset=
|
||||||
|
@@session.auto_increment_offset= 4;
|
||||||
|
SET @bug20830_old_session_auto_increment_increment=
|
||||||
|
@@session.auto_increment_increment= 5;
|
||||||
|
SET @@auto_increment_offset= 2;
|
||||||
|
SET @@auto_increment_increment= 3;
|
||||||
|
SET @@session.auto_increment_offset= 4;
|
||||||
|
SET @@session.auto_increment_increment= 5;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
c2 INT(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
SET insert_id= 14;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
|
||||||
|
INSERT INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
|
||||||
|
INSERT INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 91);
|
||||||
|
ERROR 23000: Duplicate entry '114' for key 1
|
||||||
|
INSERT INTO t1 VALUES (NULL, 92), (NULL, 93);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 c2
|
||||||
|
14 11
|
||||||
|
19 12
|
||||||
|
24 13
|
||||||
|
29 21
|
||||||
|
34 22
|
||||||
|
39 23
|
||||||
|
69 31
|
||||||
|
74 32
|
||||||
|
79 33
|
||||||
|
84 41
|
||||||
|
89 42
|
||||||
|
94 43
|
||||||
|
114 51
|
||||||
|
119 52
|
||||||
|
124 53
|
||||||
|
129 61
|
||||||
|
134 62
|
||||||
|
139 63
|
||||||
|
49 71
|
||||||
|
144 72
|
||||||
|
149 73
|
||||||
|
154 81
|
||||||
|
159 82
|
||||||
|
164 83
|
||||||
|
169 92
|
||||||
|
174 93
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
COUNT(*)
|
||||||
|
26
|
||||||
|
SELECT SUM(c1) FROM t1;
|
||||||
|
SUM(c1)
|
||||||
|
2569
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
c2 INT(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
SET insert_id= 14;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
|
||||||
|
INSERT DELAYED INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
|
||||||
|
INSERT DELAYED INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 91);
|
||||||
|
INSERT DELAYED INTO t1 VALUES (NULL, 92), (NULL, 93);
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1 c2
|
||||||
|
14 11
|
||||||
|
19 12
|
||||||
|
24 13
|
||||||
|
29 21
|
||||||
|
34 22
|
||||||
|
39 23
|
||||||
|
69 31
|
||||||
|
74 32
|
||||||
|
79 33
|
||||||
|
84 41
|
||||||
|
89 42
|
||||||
|
94 43
|
||||||
|
114 51
|
||||||
|
119 52
|
||||||
|
124 53
|
||||||
|
129 61
|
||||||
|
134 62
|
||||||
|
139 63
|
||||||
|
49 71
|
||||||
|
144 72
|
||||||
|
149 73
|
||||||
|
154 81
|
||||||
|
159 82
|
||||||
|
164 83
|
||||||
|
169 92
|
||||||
|
174 93
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
COUNT(*)
|
||||||
|
26
|
||||||
|
SELECT SUM(c1) FROM t1;
|
||||||
|
SUM(c1)
|
||||||
|
2569
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@auto_increment_offset=
|
||||||
|
@bug20830_old_auto_increment_offset;
|
||||||
|
SET @@auto_increment_increment=
|
||||||
|
@bug20830_old_auto_increment_increment;
|
||||||
|
SET @@session.auto_increment_offset=
|
||||||
|
@bug20830_old_session_auto_increment_offset;
|
||||||
|
SET @@session.auto_increment_increment=
|
||||||
|
@bug20830_old_session_auto_increment_increment;
|
||||||
|
@ -178,9 +178,9 @@ t3 CREATE TABLE `t3` (
|
|||||||
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||||
create table t4 (a int not null, b char(10), key(a)) engine=MERGE UNION=(t1,t2);
|
create table t4 (a int not null, b char(10), key(a)) engine=MERGE UNION=(t1,t2);
|
||||||
select * from t4;
|
select * from t4;
|
||||||
ERROR HY000: All tables in the MERGE table are not identically defined
|
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists
|
||||||
alter table t4 add column c int;
|
alter table t4 add column c int;
|
||||||
ERROR HY000: All tables in the MERGE table are not identically defined
|
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists
|
||||||
create database mysqltest;
|
create database mysqltest;
|
||||||
create table mysqltest.t6 (a int not null primary key auto_increment, message char(20));
|
create table mysqltest.t6 (a int not null primary key auto_increment, message char(20));
|
||||||
create table t5 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,mysqltest.t6);
|
create table t5 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,mysqltest.t6);
|
||||||
@ -768,6 +768,21 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
test.t2 check status OK
|
test.t2 check status OK
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
INSERT INTO t1 VALUES(2),(1);
|
||||||
|
CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
|
||||||
|
SELECT * FROM t2 WHERE a=2;
|
||||||
|
ERROR HY000: Got error 124 from storage engine
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1(a INT) ENGINE=MEMORY;
|
||||||
|
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
|
||||||
|
SELECT * FROM t2;
|
||||||
|
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
|
||||||
|
SELECT * FROM t2;
|
||||||
|
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists
|
||||||
|
DROP TABLE t2;
|
||||||
create table t1 (b bit(1));
|
create table t1 (b bit(1));
|
||||||
create table t2 (b bit(1));
|
create table t2 (b bit(1));
|
||||||
create table tm (b bit(1)) engine = merge union = (t1,t2);
|
create table tm (b bit(1)) engine = merge union = (t1,t2);
|
||||||
|
@ -234,6 +234,135 @@ n b
|
|||||||
2 100
|
2 100
|
||||||
3 350
|
3 350
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
SELECT LAST_INSERT_ID(0);
|
||||||
|
LAST_INSERT_ID(0)
|
||||||
|
0
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id INT NOT NULL DEFAULT 0,
|
||||||
|
last_id INT,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
last_id INT,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID());
|
||||||
|
END|
|
||||||
|
CALL p1();
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id last_id
|
||||||
|
0 1
|
||||||
|
SELECT * FROM t2;
|
||||||
|
id last_id
|
||||||
|
1 0
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id last_id
|
||||||
|
0 1
|
||||||
|
SELECT * FROM t2;
|
||||||
|
id last_id
|
||||||
|
1 0
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
j INT DEFAULT 0
|
||||||
|
);
|
||||||
|
CREATE TABLE t2 (i INT);
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL), (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
END |
|
||||||
|
CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL), (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
RETURN 0;
|
||||||
|
END |
|
||||||
|
CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC
|
||||||
|
RETURN LAST_INSERT_ID() |
|
||||||
|
INSERT INTO t1 VALUES (NULL, -1);
|
||||||
|
CALL p1();
|
||||||
|
SELECT f1();
|
||||||
|
f1()
|
||||||
|
0
|
||||||
|
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
|
||||||
|
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
|
||||||
|
INSERT INTO t1 VALUES (NULL, f2());
|
||||||
|
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
|
||||||
|
(NULL, @@LAST_INSERT_ID);
|
||||||
|
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
|
||||||
|
UPDATE t1 SET j= -1 WHERE i IS NULL;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i j
|
||||||
|
1 -1
|
||||||
|
2 0
|
||||||
|
3 0
|
||||||
|
4 0
|
||||||
|
5 0
|
||||||
|
6 0
|
||||||
|
7 0
|
||||||
|
8 3
|
||||||
|
9 3
|
||||||
|
10 3
|
||||||
|
11 3
|
||||||
|
12 3
|
||||||
|
13 8
|
||||||
|
14 13
|
||||||
|
15 5
|
||||||
|
16 13
|
||||||
|
17 -1
|
||||||
|
18 14
|
||||||
|
SELECT * FROM t2;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
3
|
||||||
|
5
|
||||||
|
6
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i j
|
||||||
|
1 -1
|
||||||
|
2 0
|
||||||
|
3 0
|
||||||
|
4 0
|
||||||
|
5 0
|
||||||
|
6 0
|
||||||
|
7 0
|
||||||
|
8 3
|
||||||
|
9 3
|
||||||
|
10 3
|
||||||
|
11 3
|
||||||
|
12 3
|
||||||
|
13 8
|
||||||
|
14 13
|
||||||
|
15 5
|
||||||
|
16 13
|
||||||
|
17 -1
|
||||||
|
18 14
|
||||||
|
SELECT * FROM t2;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
3
|
||||||
|
5
|
||||||
|
6
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ insert delayed into t1 set a = 4;
|
|||||||
insert delayed into t1 set a = 5, tmsp = 19711006010203;
|
insert delayed into t1 set a = 5, tmsp = 19711006010203;
|
||||||
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
|
insert delayed into t1 (a, tmsp) values (6, 19711006010203);
|
||||||
insert delayed into t1 (a, tmsp) values (7, NULL);
|
insert delayed into t1 (a, tmsp) values (7, NULL);
|
||||||
--sleep 2
|
# Wait until the rows are flushed to the table files.
|
||||||
|
FLUSH TABLE t1;
|
||||||
insert into t1 set a = 8,tmsp=19711006010203;
|
insert into t1 set a = 8,tmsp=19711006010203;
|
||||||
select * from t1 where tmsp=0;
|
select * from t1 where tmsp=0;
|
||||||
select * from t1 where tmsp=19711006010203;
|
select * from t1 where tmsp=19711006010203;
|
||||||
@ -34,8 +35,8 @@ insert delayed into t1 values (null,"c");
|
|||||||
insert delayed into t1 values (3,"d"),(null,"e");
|
insert delayed into t1 values (3,"d"),(null,"e");
|
||||||
--error 1136
|
--error 1136
|
||||||
insert delayed into t1 values (3,"this will give an","error");
|
insert delayed into t1 values (3,"this will give an","error");
|
||||||
# 2 was not enough for --ps-protocol
|
# Wait until the rows are flushed to the table files.
|
||||||
--sleep 4
|
FLUSH TABLE t1;
|
||||||
show status like 'not_flushed_delayed_rows';
|
show status like 'not_flushed_delayed_rows';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -92,10 +93,145 @@ insert delayed into t1 values(null);
|
|||||||
# Works, since the delayed-counter is 8, which is unused
|
# Works, since the delayed-counter is 8, which is unused
|
||||||
insert delayed into t1 values(null);
|
insert delayed into t1 values(null);
|
||||||
|
|
||||||
|
# Wait until the rows are flushed to the table files.
|
||||||
|
FLUSH TABLE t1;
|
||||||
# Check what we have now
|
# Check what we have now
|
||||||
# must wait so that the delayed thread finishes
|
|
||||||
# Note: this must be increased if the test fails
|
|
||||||
--sleep 1
|
|
||||||
select * from t1 order by a;
|
select * from t1 order by a;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#20627 - INSERT DELAYED does not honour auto_increment_* variables
|
||||||
|
#
|
||||||
|
SET @bug20627_old_auto_increment_offset=
|
||||||
|
@@auto_increment_offset= 2;
|
||||||
|
SET @bug20627_old_auto_increment_increment=
|
||||||
|
@@auto_increment_increment= 3;
|
||||||
|
SET @bug20627_old_session_auto_increment_offset=
|
||||||
|
@@session.auto_increment_offset= 4;
|
||||||
|
SET @bug20627_old_session_auto_increment_increment=
|
||||||
|
@@session.auto_increment_increment= 5;
|
||||||
|
SET @@auto_increment_offset= 2;
|
||||||
|
SET @@auto_increment_increment= 3;
|
||||||
|
SET @@session.auto_increment_offset= 4;
|
||||||
|
SET @@session.auto_increment_increment= 5;
|
||||||
|
#
|
||||||
|
# Normal insert as reference.
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
|
||||||
|
# Check what we have now
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Delayed insert.
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
INSERT DELAYED INTO t1 VALUES (NULL),(NULL),(NULL);
|
||||||
|
# Wait until the rows are flushed to the table files.
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
# Check what we have now
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Cleanup
|
||||||
|
SET @@auto_increment_offset=
|
||||||
|
@bug20627_old_auto_increment_offset;
|
||||||
|
SET @@auto_increment_increment=
|
||||||
|
@bug20627_old_auto_increment_increment;
|
||||||
|
SET @@session.auto_increment_offset=
|
||||||
|
@bug20627_old_session_auto_increment_offset;
|
||||||
|
SET @@session.auto_increment_increment=
|
||||||
|
@bug20627_old_session_auto_increment_increment;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#20830 - INSERT DELAYED does not honour SET INSERT_ID
|
||||||
|
#
|
||||||
|
SET @bug20830_old_auto_increment_offset=
|
||||||
|
@@auto_increment_offset= 2;
|
||||||
|
SET @bug20830_old_auto_increment_increment=
|
||||||
|
@@auto_increment_increment= 3;
|
||||||
|
SET @bug20830_old_session_auto_increment_offset=
|
||||||
|
@@session.auto_increment_offset= 4;
|
||||||
|
SET @bug20830_old_session_auto_increment_increment=
|
||||||
|
@@session.auto_increment_increment= 5;
|
||||||
|
SET @@auto_increment_offset= 2;
|
||||||
|
SET @@auto_increment_increment= 3;
|
||||||
|
SET @@session.auto_increment_offset= 4;
|
||||||
|
SET @@session.auto_increment_increment= 5;
|
||||||
|
#
|
||||||
|
# Normal insert as reference.
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
c2 INT(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
SET insert_id= 14;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
|
||||||
|
# Restart sequence at a different value.
|
||||||
|
INSERT INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
|
||||||
|
# Restart sequence at a different value.
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
|
||||||
|
# Set one value below the maximum value.
|
||||||
|
INSERT INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
|
||||||
|
INSERT INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
|
||||||
|
# Create a duplicate value.
|
||||||
|
SET insert_id= 114;
|
||||||
|
--error 1062
|
||||||
|
INSERT INTO t1 VALUES(NULL, 91);
|
||||||
|
INSERT INTO t1 VALUES (NULL, 92), (NULL, 93);
|
||||||
|
# Check what we have now
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
SELECT SUM(c1) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Delayed insert.
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
c2 INT(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (c1)
|
||||||
|
);
|
||||||
|
SET insert_id= 14;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 11), (NULL, 12), (NULL, 13);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 21), (NULL, 22), (NULL, 23);
|
||||||
|
# Restart sequence at a different value.
|
||||||
|
INSERT DELAYED INTO t1 VALUES( 69, 31), (NULL, 32), (NULL, 33);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 41), (NULL, 42), (NULL, 43);
|
||||||
|
# Restart sequence at a different value.
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 51), (NULL, 52), (NULL, 53);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 61), (NULL, 62), (NULL, 63);
|
||||||
|
# Set one value below the maximum value.
|
||||||
|
INSERT DELAYED INTO t1 VALUES( 49, 71), (NULL, 72), (NULL, 73);
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 81), (NULL, 82), (NULL, 83);
|
||||||
|
# Create a duplicate value.
|
||||||
|
SET insert_id= 114;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(NULL, 91);
|
||||||
|
INSERT DELAYED INTO t1 VALUES (NULL, 92), (NULL, 93);
|
||||||
|
# Wait until the rows are flushed to the table files.
|
||||||
|
FLUSH TABLE t1;
|
||||||
|
# Check what we have now
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT COUNT(*) FROM t1;
|
||||||
|
SELECT SUM(c1) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Cleanup
|
||||||
|
SET @@auto_increment_offset=
|
||||||
|
@bug20830_old_auto_increment_offset;
|
||||||
|
SET @@auto_increment_increment=
|
||||||
|
@bug20830_old_auto_increment_increment;
|
||||||
|
SET @@session.auto_increment_offset=
|
||||||
|
@bug20830_old_session_auto_increment_offset;
|
||||||
|
SET @@session.auto_increment_increment=
|
||||||
|
@bug20830_old_session_auto_increment_increment;
|
||||||
|
|
||||||
|
@ -378,6 +378,31 @@ select * from t3;
|
|||||||
check table t1, t2;
|
check table t1, t2;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#21617 - crash when selecting from merge table with inconsistent
|
||||||
|
# indexes
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a INT);
|
||||||
|
INSERT INTO t1 VALUES(2),(1);
|
||||||
|
CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
|
||||||
|
--error 1030
|
||||||
|
SELECT * FROM t2 WHERE a=2;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#10974 - No error message if merge table based on union of innodb,
|
||||||
|
# memory
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a INT) ENGINE=MEMORY;
|
||||||
|
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
|
||||||
|
--error 1168
|
||||||
|
SELECT * FROM t2;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
|
||||||
|
--error 1168
|
||||||
|
SELECT * FROM t2;
|
||||||
|
DROP TABLE t2;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -244,6 +244,118 @@ select * from t1 order by n;
|
|||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#20339: stored procedure using LAST_INSERT_ID() does not
|
||||||
|
# replicate statement-based
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
# Reset result of LAST_INSERT_ID().
|
||||||
|
SELECT LAST_INSERT_ID(0);
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id INT NOT NULL DEFAULT 0,
|
||||||
|
last_id INT,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
last_id INT,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID());
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
CALL p1();
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#21726: Incorrect result with multiple invocations of
|
||||||
|
# LAST_INSERT_ID
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
j INT DEFAULT 0
|
||||||
|
);
|
||||||
|
CREATE TABLE t2 (i INT);
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL), (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
END |
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
INSERT INTO t1 (i) VALUES (NULL), (NULL);
|
||||||
|
INSERT INTO t2 (i) VALUES (LAST_INSERT_ID());
|
||||||
|
RETURN 0;
|
||||||
|
END |
|
||||||
|
|
||||||
|
CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC
|
||||||
|
RETURN LAST_INSERT_ID() |
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (NULL, -1);
|
||||||
|
CALL p1();
|
||||||
|
SELECT f1();
|
||||||
|
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
|
||||||
|
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
|
||||||
|
INSERT INTO t1 VALUES (NULL, f2());
|
||||||
|
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
|
||||||
|
(NULL, @@LAST_INSERT_ID);
|
||||||
|
# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID".
|
||||||
|
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
|
||||||
|
UPDATE t1 SET j= -1 WHERE i IS NULL;
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
|
||||||
--echo
|
--echo
|
||||||
|
@ -164,28 +164,22 @@ void delete_queue(QUEUE *queue)
|
|||||||
|
|
||||||
void queue_insert(register QUEUE *queue, byte *element)
|
void queue_insert(register QUEUE *queue, byte *element)
|
||||||
{
|
{
|
||||||
reg2 uint idx,next;
|
reg2 uint idx, next;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
DBUG_ASSERT(queue->elements < queue->max_elements);
|
||||||
#ifndef DBUG_OFF
|
queue->root[0]= element;
|
||||||
if (queue->elements < queue->max_elements)
|
idx= ++queue->elements;
|
||||||
#endif
|
/* max_at_top swaps the comparison if we want to order by desc */
|
||||||
|
while ((cmp= queue->compare(queue->first_cmp_arg,
|
||||||
|
element + queue->offset_to_key,
|
||||||
|
queue->root[(next= idx >> 1)] +
|
||||||
|
queue->offset_to_key)) &&
|
||||||
|
(cmp ^ queue->max_at_top) < 0)
|
||||||
{
|
{
|
||||||
queue->root[0]=element;
|
queue->root[idx]= queue->root[next];
|
||||||
idx= ++queue->elements;
|
idx= next;
|
||||||
|
|
||||||
/* max_at_top swaps the comparison if we want to order by desc */
|
|
||||||
while ((cmp=queue->compare(queue->first_cmp_arg,
|
|
||||||
element+queue->offset_to_key,
|
|
||||||
queue->root[(next=idx >> 1)] +
|
|
||||||
queue->offset_to_key)) &&
|
|
||||||
(cmp ^ queue->max_at_top) < 0)
|
|
||||||
{
|
|
||||||
queue->root[idx]=queue->root[next];
|
|
||||||
idx=next;
|
|
||||||
}
|
|
||||||
queue->root[idx]=element;
|
|
||||||
}
|
}
|
||||||
|
queue->root[idx]= element;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove item from queue */
|
/* Remove item from queue */
|
||||||
@ -193,16 +187,12 @@ void queue_insert(register QUEUE *queue, byte *element)
|
|||||||
|
|
||||||
byte *queue_remove(register QUEUE *queue, uint idx)
|
byte *queue_remove(register QUEUE *queue, uint idx)
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
byte *element;
|
||||||
if (idx >= queue->max_elements)
|
DBUG_ASSERT(idx < queue->max_elements);
|
||||||
return 0;
|
element= queue->root[++idx]; /* Intern index starts from 1 */
|
||||||
#endif
|
queue->root[idx]= queue->root[queue->elements--];
|
||||||
{
|
_downheap(queue, idx);
|
||||||
byte *element=queue->root[++idx]; /* Intern index starts from 1 */
|
return element;
|
||||||
queue->root[idx]=queue->root[queue->elements--];
|
|
||||||
_downheap(queue,idx);
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix when element on top has been replaced */
|
/* Fix when element on top has been replaced */
|
||||||
|
@ -120,6 +120,8 @@ static bool archive_inited= FALSE;
|
|||||||
/* Variables for archive share methods */
|
/* Variables for archive share methods */
|
||||||
pthread_mutex_t archive_mutex;
|
pthread_mutex_t archive_mutex;
|
||||||
static HASH archive_open_tables;
|
static HASH archive_open_tables;
|
||||||
|
static z_off_t max_zfile_size;
|
||||||
|
static int zoffset_size;
|
||||||
|
|
||||||
/* The file extension */
|
/* The file extension */
|
||||||
#define ARZ ".ARZ" // The data file
|
#define ARZ ".ARZ" // The data file
|
||||||
@ -203,6 +205,18 @@ bool archive_db_init()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
zoffset_size= 2 << ((zlibCompileFlags() >> 6) & 3);
|
||||||
|
switch (sizeof(z_off_t)) {
|
||||||
|
case 2:
|
||||||
|
max_zfile_size= INT_MAX16;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
max_zfile_size= LONGLONG_MAX;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
max_zfile_size= INT_MAX32;
|
||||||
|
}
|
||||||
archive_inited= TRUE;
|
archive_inited= TRUE;
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
@ -240,7 +254,7 @@ ha_archive::ha_archive(TABLE *table_arg)
|
|||||||
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
|
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
|
||||||
|
|
||||||
/* The size of the offset value we will use for position() */
|
/* The size of the offset value we will use for position() */
|
||||||
ref_length = 2 << ((zlibCompileFlags() >> 6) & 3);
|
ref_length = zoffset_size;
|
||||||
DBUG_ASSERT(ref_length <= sizeof(z_off_t));
|
DBUG_ASSERT(ref_length <= sizeof(z_off_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,7 +494,8 @@ int ha_archive::init_archive_writer()
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
share->archive_write_open= TRUE;
|
share->archive_write_open= TRUE;
|
||||||
|
info(HA_STATUS_TIME);
|
||||||
|
share->approx_file_size= data_file_length;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,10 +666,21 @@ error:
|
|||||||
*/
|
*/
|
||||||
int ha_archive::real_write_row(byte *buf, gzFile writer)
|
int ha_archive::real_write_row(byte *buf, gzFile writer)
|
||||||
{
|
{
|
||||||
z_off_t written;
|
z_off_t written, total_row_length;
|
||||||
uint *ptr, *end;
|
uint *ptr, *end;
|
||||||
DBUG_ENTER("ha_archive::real_write_row");
|
DBUG_ENTER("ha_archive::real_write_row");
|
||||||
|
total_row_length= table->s->reclength;
|
||||||
|
for (ptr= table->s->blob_field, end= ptr + table->s->blob_fields;
|
||||||
|
ptr != end; ptr++)
|
||||||
|
total_row_length+= ((Field_blob*) table->field[*ptr])->get_length();
|
||||||
|
if (share->approx_file_size > max_zfile_size - total_row_length)
|
||||||
|
{
|
||||||
|
info(HA_STATUS_TIME);
|
||||||
|
share->approx_file_size= data_file_length;
|
||||||
|
if (share->approx_file_size > max_zfile_size - total_row_length)
|
||||||
|
DBUG_RETURN(HA_ERR_RECORD_FILE_FULL);
|
||||||
|
}
|
||||||
|
share->approx_file_size+= total_row_length;
|
||||||
written= gzwrite(writer, buf, table->s->reclength);
|
written= gzwrite(writer, buf, table->s->reclength);
|
||||||
DBUG_PRINT("ha_archive::real_write_row", ("Wrote %d bytes expected %d", written, table->s->reclength));
|
DBUG_PRINT("ha_archive::real_write_row", ("Wrote %d bytes expected %d", written, table->s->reclength));
|
||||||
if (!delayed_insert || !bulk_insert)
|
if (!delayed_insert || !bulk_insert)
|
||||||
|
@ -38,6 +38,7 @@ typedef struct st_archive_share {
|
|||||||
bool dirty; /* Flag for if a flush should occur */
|
bool dirty; /* Flag for if a flush should occur */
|
||||||
bool crashed; /* Meta file is crashed */
|
bool crashed; /* Meta file is crashed */
|
||||||
ha_rows rows_recorded; /* Number of rows in tables */
|
ha_rows rows_recorded; /* Number of rows in tables */
|
||||||
|
z_off_t approx_file_size; /* Approximate archive data file size */
|
||||||
} ARCHIVE_SHARE;
|
} ARCHIVE_SHARE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3345,6 +3345,34 @@ longlong Item_func_release_lock::val_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_last_insert_id::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
|
||||||
|
if (Item_int_func::fix_fields(thd, ref))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (arg_count == 0)
|
||||||
|
{
|
||||||
|
if (!thd->last_insert_id_used)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
As this statement calls LAST_INSERT_ID(), set
|
||||||
|
THD::last_insert_id_used and remember first generated insert
|
||||||
|
id of the previous statement in THD::current_insert_id.
|
||||||
|
*/
|
||||||
|
thd->last_insert_id_used= TRUE;
|
||||||
|
thd->current_insert_id= thd->last_insert_id;
|
||||||
|
}
|
||||||
|
null_value= FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_last_insert_id::val_int()
|
longlong Item_func_last_insert_id::val_int()
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
@ -3354,12 +3382,13 @@ longlong Item_func_last_insert_id::val_int()
|
|||||||
longlong value= args[0]->val_int();
|
longlong value= args[0]->val_int();
|
||||||
thd->insert_id(value);
|
thd->insert_id(value);
|
||||||
null_value= args[0]->null_value;
|
null_value= args[0]->null_value;
|
||||||
return value; // Avoid side effect of insert_id()
|
return value;
|
||||||
}
|
}
|
||||||
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
|
||||||
return thd->last_insert_id_used ? thd->current_insert_id : thd->insert_id();
|
return thd->current_insert_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is just used to test speed of different functions */
|
/* This function is just used to test speed of different functions */
|
||||||
|
|
||||||
longlong Item_func_benchmark::val_int()
|
longlong Item_func_benchmark::val_int()
|
||||||
|
@ -891,6 +891,7 @@ public:
|
|||||||
if (arg_count)
|
if (arg_count)
|
||||||
max_length= args[0]->max_length;
|
max_length= args[0]->max_length;
|
||||||
}
|
}
|
||||||
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3365,7 +3365,6 @@ int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
|
|||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LAST_INSERT_ID_EVENT:
|
case LAST_INSERT_ID_EVENT:
|
||||||
thd->last_insert_id_used = 1;
|
|
||||||
thd->last_insert_id = val;
|
thd->last_insert_id = val;
|
||||||
break;
|
break;
|
||||||
case INSERT_ID_EVENT:
|
case INSERT_ID_EVENT:
|
||||||
|
@ -2571,8 +2571,17 @@ bool sys_var_last_insert_id::update(THD *thd, set_var *var)
|
|||||||
byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
|
byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
|
||||||
LEX_STRING *base)
|
LEX_STRING *base)
|
||||||
{
|
{
|
||||||
thd->sys_var_tmp.long_value= (long) thd->insert_id();
|
if (!thd->last_insert_id_used)
|
||||||
return (byte*) &thd->last_insert_id;
|
{
|
||||||
|
/*
|
||||||
|
As this statement reads @@LAST_INSERT_ID, set
|
||||||
|
THD::last_insert_id_used and remember first generated insert id
|
||||||
|
of the previous statement in THD::current_insert_id.
|
||||||
|
*/
|
||||||
|
thd->last_insert_id_used= TRUE;
|
||||||
|
thd->current_insert_id= thd->last_insert_id;
|
||||||
|
}
|
||||||
|
return (byte*) &thd->current_insert_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3813,7 +3813,7 @@ ER_WRONG_MRG_TABLE
|
|||||||
cze "V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì"
|
cze "V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì"
|
||||||
dan "Tabellerne i MERGE er ikke defineret ens"
|
dan "Tabellerne i MERGE er ikke defineret ens"
|
||||||
nla "Niet alle tabellen in de MERGE tabel hebben identieke gedefinities"
|
nla "Niet alle tabellen in de MERGE tabel hebben identieke gedefinities"
|
||||||
eng "All tables in the MERGE table are not identically defined"
|
eng "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists"
|
||||||
est "Kõik tabelid MERGE tabeli määratluses ei ole identsed"
|
est "Kõik tabelid MERGE tabeli määratluses ei ole identsed"
|
||||||
fre "Toutes les tables de la table de type MERGE n'ont pas la même définition"
|
fre "Toutes les tables de la table de type MERGE n'ont pas la même définition"
|
||||||
ger "Nicht alle Tabellen in der MERGE-Tabelle sind gleich definiert"
|
ger "Nicht alle Tabellen in der MERGE-Tabelle sind gleich definiert"
|
||||||
|
@ -553,10 +553,24 @@ bool THD::store_globals()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Cleanup after a query */
|
/*
|
||||||
|
Cleanup after query.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
THD::cleanup_after_query()
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function is used to reset thread data to it's default state.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
This function is not suitable for setting thread data to some
|
||||||
|
non-default values, as there is only one replication thread, so
|
||||||
|
different master threads may overwrite data of each other on
|
||||||
|
slave.
|
||||||
|
*/
|
||||||
void THD::cleanup_after_query()
|
void THD::cleanup_after_query()
|
||||||
{
|
{
|
||||||
|
last_insert_id_used= FALSE;
|
||||||
if (clear_next_insert_id)
|
if (clear_next_insert_id)
|
||||||
{
|
{
|
||||||
clear_next_insert_id= 0;
|
clear_next_insert_id= 0;
|
||||||
|
@ -1252,17 +1252,29 @@ public:
|
|||||||
ulonglong next_insert_id;
|
ulonglong next_insert_id;
|
||||||
/* Remember last next_insert_id to reset it if something went wrong */
|
/* Remember last next_insert_id to reset it if something went wrong */
|
||||||
ulonglong prev_insert_id;
|
ulonglong prev_insert_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The insert_id used for the last statement or set by SET LAST_INSERT_ID=#
|
At the beginning of the statement last_insert_id holds the first
|
||||||
or SELECT LAST_INSERT_ID(#). Used for binary log and returned by
|
generated value of the previous statement. During statement
|
||||||
LAST_INSERT_ID()
|
execution it is updated to the value just generated, but then
|
||||||
|
restored to the value that was generated first, so for the next
|
||||||
|
statement it will again be "the first generated value of the
|
||||||
|
previous statement".
|
||||||
|
|
||||||
|
It may also be set with "LAST_INSERT_ID(expr)" or
|
||||||
|
"@@LAST_INSERT_ID= expr", but the effect of such setting will be
|
||||||
|
seen only in the next statement.
|
||||||
*/
|
*/
|
||||||
ulonglong last_insert_id;
|
ulonglong last_insert_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set to the first value that LAST_INSERT_ID() returned for the last
|
current_insert_id remembers the first generated value of the
|
||||||
statement. When this is set, last_insert_id_used is set to true.
|
previous statement, and does not change during statement
|
||||||
|
execution. Its value returned from LAST_INSERT_ID() and
|
||||||
|
@@LAST_INSERT_ID.
|
||||||
*/
|
*/
|
||||||
ulonglong current_insert_id;
|
ulonglong current_insert_id;
|
||||||
|
|
||||||
ulonglong limit_found_rows;
|
ulonglong limit_found_rows;
|
||||||
ulonglong options; /* Bitmap of states */
|
ulonglong options; /* Bitmap of states */
|
||||||
longlong row_count_func; /* For the ROW_COUNT() function */
|
longlong row_count_func; /* For the ROW_COUNT() function */
|
||||||
@ -1325,7 +1337,22 @@ public:
|
|||||||
bool last_cuted_field;
|
bool last_cuted_field;
|
||||||
bool no_errors, password, is_fatal_error;
|
bool no_errors, password, is_fatal_error;
|
||||||
bool query_start_used, rand_used, time_zone_used;
|
bool query_start_used, rand_used, time_zone_used;
|
||||||
bool last_insert_id_used,insert_id_used, clear_next_insert_id;
|
|
||||||
|
/*
|
||||||
|
last_insert_id_used is set when current statement calls
|
||||||
|
LAST_INSERT_ID() or reads @@LAST_INSERT_ID, so that binary log
|
||||||
|
LAST_INSERT_ID_EVENT be generated.
|
||||||
|
*/
|
||||||
|
bool last_insert_id_used;
|
||||||
|
|
||||||
|
/*
|
||||||
|
insert_id_used is set when current statement updates
|
||||||
|
THD::last_insert_id, so that binary log INSERT_ID_EVENT be
|
||||||
|
generated.
|
||||||
|
*/
|
||||||
|
bool insert_id_used;
|
||||||
|
|
||||||
|
bool clear_next_insert_id;
|
||||||
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
|
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
|
||||||
bool substitute_null_with_insert_id;
|
bool substitute_null_with_insert_id;
|
||||||
bool in_lock_tables;
|
bool in_lock_tables;
|
||||||
@ -1461,15 +1488,6 @@ public:
|
|||||||
insert_id_used=1;
|
insert_id_used=1;
|
||||||
substitute_null_with_insert_id= TRUE;
|
substitute_null_with_insert_id= TRUE;
|
||||||
}
|
}
|
||||||
inline ulonglong insert_id(void)
|
|
||||||
{
|
|
||||||
if (!last_insert_id_used)
|
|
||||||
{
|
|
||||||
last_insert_id_used=1;
|
|
||||||
current_insert_id=last_insert_id;
|
|
||||||
}
|
|
||||||
return last_insert_id;
|
|
||||||
}
|
|
||||||
inline ulonglong found_rows(void)
|
inline ulonglong found_rows(void)
|
||||||
{
|
{
|
||||||
return limit_found_rows;
|
return limit_found_rows;
|
||||||
|
@ -590,10 +590,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
#endif
|
#endif
|
||||||
error=write_record(thd, table ,&info);
|
error=write_record(thd, table ,&info);
|
||||||
/*
|
/*
|
||||||
If auto_increment values are used, save the first one
|
If auto_increment values are used, save the first one for
|
||||||
for LAST_INSERT_ID() and for the update log.
|
LAST_INSERT_ID() and for the update log.
|
||||||
We can't use insert_id() as we don't want to touch the
|
|
||||||
last_insert_id_used flag.
|
|
||||||
*/
|
*/
|
||||||
if (! id && thd->insert_id_used)
|
if (! id && thd->insert_id_used)
|
||||||
{ // Get auto increment value
|
{ // Get auto increment value
|
||||||
@ -1303,6 +1301,9 @@ public:
|
|||||||
time_t start_time;
|
time_t start_time;
|
||||||
bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
|
bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
|
||||||
ulonglong last_insert_id;
|
ulonglong last_insert_id;
|
||||||
|
ulonglong next_insert_id;
|
||||||
|
ulong auto_increment_increment;
|
||||||
|
ulong auto_increment_offset;
|
||||||
timestamp_auto_set_type timestamp_field_type;
|
timestamp_auto_set_type timestamp_field_type;
|
||||||
uint query_length;
|
uint query_length;
|
||||||
|
|
||||||
@ -1684,6 +1685,22 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool igno
|
|||||||
row->last_insert_id= thd->last_insert_id;
|
row->last_insert_id= thd->last_insert_id;
|
||||||
row->timestamp_field_type= table->timestamp_field_type;
|
row->timestamp_field_type= table->timestamp_field_type;
|
||||||
|
|
||||||
|
/* The session variable settings can always be copied. */
|
||||||
|
row->auto_increment_increment= thd->variables.auto_increment_increment;
|
||||||
|
row->auto_increment_offset= thd->variables.auto_increment_offset;
|
||||||
|
/*
|
||||||
|
Next insert id must be set for the first value in a multi-row insert
|
||||||
|
only. So clear it after the first use. Assume a multi-row insert.
|
||||||
|
Since the user thread doesn't really execute the insert,
|
||||||
|
thd->next_insert_id is left untouched between the rows. If we copy
|
||||||
|
the same insert id to every row of the multi-row insert, the delayed
|
||||||
|
insert thread would copy this before inserting every row. Thus it
|
||||||
|
tries to insert all rows with the same insert id. This fails on the
|
||||||
|
unique constraint. So just the first row would be really inserted.
|
||||||
|
*/
|
||||||
|
row->next_insert_id= thd->next_insert_id;
|
||||||
|
thd->next_insert_id= 0;
|
||||||
|
|
||||||
di->rows.push_back(row);
|
di->rows.push_back(row);
|
||||||
di->stacked_inserts++;
|
di->stacked_inserts++;
|
||||||
di->status=1;
|
di->status=1;
|
||||||
@ -2055,6 +2072,14 @@ bool delayed_insert::handle_inserts(void)
|
|||||||
thd.insert_id_used=row->insert_id_used;
|
thd.insert_id_used=row->insert_id_used;
|
||||||
table->timestamp_field_type= row->timestamp_field_type;
|
table->timestamp_field_type= row->timestamp_field_type;
|
||||||
|
|
||||||
|
/* The session variable settings can always be copied. */
|
||||||
|
thd.variables.auto_increment_increment= row->auto_increment_increment;
|
||||||
|
thd.variables.auto_increment_offset= row->auto_increment_offset;
|
||||||
|
/* Next insert id must be used only if non-zero. */
|
||||||
|
if (row->next_insert_id)
|
||||||
|
thd.next_insert_id= row->next_insert_id;
|
||||||
|
DBUG_PRINT("loop", ("next_insert_id: %lu", (ulong) thd.next_insert_id));
|
||||||
|
|
||||||
info.ignore= row->ignore;
|
info.ignore= row->ignore;
|
||||||
info.handle_duplicates= row->dup;
|
info.handle_duplicates= row->dup;
|
||||||
if (info.ignore ||
|
if (info.ignore ||
|
||||||
@ -2076,6 +2101,20 @@ bool delayed_insert::handle_inserts(void)
|
|||||||
info.error_count++; // Ignore errors
|
info.error_count++; // Ignore errors
|
||||||
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
|
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
|
||||||
row->log_query = 0;
|
row->log_query = 0;
|
||||||
|
/*
|
||||||
|
We must reset next_insert_id. Otherwise all following rows may
|
||||||
|
become duplicates. If write_record() failed on a duplicate and
|
||||||
|
next_insert_id would be left unchanged, the next rows would also
|
||||||
|
be tried with the same insert id and would fail. Since the end
|
||||||
|
of a multi-row statement is unknown here, all following rows in
|
||||||
|
the queue would be dropped, regardless which thread added them.
|
||||||
|
After the queue is used up, next_insert_id is cleared and the
|
||||||
|
next run will succeed. This could even happen if these come from
|
||||||
|
the same multi-row statement as the current queue contents. That
|
||||||
|
way it would look somewhat random which rows are rejected after
|
||||||
|
a duplicate.
|
||||||
|
*/
|
||||||
|
thd.next_insert_id= 0;
|
||||||
}
|
}
|
||||||
if (using_ignore)
|
if (using_ignore)
|
||||||
{
|
{
|
||||||
@ -2121,6 +2160,7 @@ bool delayed_insert::handle_inserts(void)
|
|||||||
/* This should never happen */
|
/* This should never happen */
|
||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(0));
|
||||||
sql_print_error("%s",thd.net.last_error);
|
sql_print_error("%s",thd.net.last_error);
|
||||||
|
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
query_cache_invalidate3(&thd, table, 1);
|
query_cache_invalidate3(&thd, table, 1);
|
||||||
@ -2146,6 +2186,7 @@ bool delayed_insert::handle_inserts(void)
|
|||||||
{ // This shouldn't happen
|
{ // This shouldn't happen
|
||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(0));
|
||||||
sql_print_error("%s",thd.net.last_error);
|
sql_print_error("%s",thd.net.last_error);
|
||||||
|
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
query_cache_invalidate3(&thd, table, 1);
|
query_cache_invalidate3(&thd, table, 1);
|
||||||
@ -2153,13 +2194,16 @@ bool delayed_insert::handle_inserts(void)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
DBUG_EXECUTE("error", max_rows= 0;);
|
||||||
/* Remove all not used rows */
|
/* Remove all not used rows */
|
||||||
while ((row=rows.get()))
|
while ((row=rows.get()))
|
||||||
{
|
{
|
||||||
delete row;
|
delete row;
|
||||||
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
|
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
|
||||||
stacked_inserts--;
|
stacked_inserts--;
|
||||||
|
DBUG_EXECUTE("error", max_rows++;);
|
||||||
}
|
}
|
||||||
|
DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
|
||||||
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
|
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@ -2447,7 +2491,7 @@ bool select_insert::send_data(List<Item> &values)
|
|||||||
*/
|
*/
|
||||||
table->next_number_field->reset();
|
table->next_number_field->reset();
|
||||||
if (!last_insert_id && thd->insert_id_used)
|
if (!last_insert_id && thd->insert_id_used)
|
||||||
last_insert_id= thd->insert_id();
|
last_insert_id= thd->last_insert_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
|
@ -616,10 +616,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
thd->no_trans_update= no_trans_update;
|
thd->no_trans_update= no_trans_update;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If auto_increment values are used, save the first one
|
If auto_increment values are used, save the first one for
|
||||||
for LAST_INSERT_ID() and for the binary/update log.
|
LAST_INSERT_ID() and for the binary/update log.
|
||||||
We can't use insert_id() as we don't want to touch the
|
|
||||||
last_insert_id_used flag.
|
|
||||||
*/
|
*/
|
||||||
if (!id && thd->insert_id_used)
|
if (!id && thd->insert_id_used)
|
||||||
id= thd->last_insert_id;
|
id= thd->last_insert_id;
|
||||||
@ -784,10 +782,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
if (write_record(thd, table, &info))
|
if (write_record(thd, table, &info))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
/*
|
/*
|
||||||
If auto_increment values are used, save the first one
|
If auto_increment values are used, save the first one for
|
||||||
for LAST_INSERT_ID() and for the binary/update log.
|
LAST_INSERT_ID() and for the binary/update log.
|
||||||
We can't use insert_id() as we don't want to touch the
|
|
||||||
last_insert_id_used flag.
|
|
||||||
*/
|
*/
|
||||||
if (!id && thd->insert_id_used)
|
if (!id && thd->insert_id_used)
|
||||||
id= thd->last_insert_id;
|
id= thd->last_insert_id;
|
||||||
|
@ -2421,6 +2421,20 @@ mysql_execute_command(THD *thd)
|
|||||||
DBUG_ENTER("mysql_execute_command");
|
DBUG_ENTER("mysql_execute_command");
|
||||||
thd->net.no_send_error= 0;
|
thd->net.no_send_error= 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remember first generated insert id value of the previous
|
||||||
|
statement. We remember it here at the beginning of the statement,
|
||||||
|
and also in Item_func_last_insert_id::fix_fields() and
|
||||||
|
sys_var_last_insert_id::value_ptr(). Last two places are required
|
||||||
|
because LAST_INSERT_ID() and @@LAST_INSERT_ID may also be used in
|
||||||
|
expression that is not executed with mysql_execute_command().
|
||||||
|
|
||||||
|
And we remember it here because some statements read
|
||||||
|
@@LAST_INSERT_ID indirectly, like "SELECT * FROM t1 WHERE id IS
|
||||||
|
NULL", that may replace "id IS NULL" with "id = <LAST_INSERT_ID>".
|
||||||
|
*/
|
||||||
|
thd->current_insert_id= thd->last_insert_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In many cases first table of main SELECT_LEX have special meaning =>
|
In many cases first table of main SELECT_LEX have special meaning =>
|
||||||
check that it is first table in global list and relink it first in
|
check that it is first table in global list and relink it first in
|
||||||
@ -5636,7 +5650,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
|
|||||||
DBUG_ENTER("mysql_reset_thd_for_next_command");
|
DBUG_ENTER("mysql_reset_thd_for_next_command");
|
||||||
thd->free_list= 0;
|
thd->free_list= 0;
|
||||||
thd->select_number= 1;
|
thd->select_number= 1;
|
||||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
thd->query_start_used= thd->insert_id_used=0;
|
||||||
thd->is_fatal_error= thd->time_zone_used= 0;
|
thd->is_fatal_error= thd->time_zone_used= 0;
|
||||||
thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
|
thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
|
||||||
SERVER_QUERY_NO_INDEX_USED |
|
SERVER_QUERY_NO_INDEX_USED |
|
||||||
|
@ -8142,7 +8142,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
Field *field=((Item_field*) args[0])->field;
|
Field *field=((Item_field*) args[0])->field;
|
||||||
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
|
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
|
||||||
(thd->options & OPTION_AUTO_IS_NULL) &&
|
(thd->options & OPTION_AUTO_IS_NULL) &&
|
||||||
thd->insert_id() && thd->substitute_null_with_insert_id)
|
thd->current_insert_id && thd->substitute_null_with_insert_id)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_QUERY_CACHE
|
#ifdef HAVE_QUERY_CACHE
|
||||||
query_cache_abort(&thd->net);
|
query_cache_abort(&thd->net);
|
||||||
@ -8150,9 +8150,16 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
|||||||
COND *new_cond;
|
COND *new_cond;
|
||||||
if ((new_cond= new Item_func_eq(args[0],
|
if ((new_cond= new Item_func_eq(args[0],
|
||||||
new Item_int("last_insert_id()",
|
new Item_int("last_insert_id()",
|
||||||
thd->insert_id(),
|
thd->current_insert_id,
|
||||||
21))))
|
21))))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Set THD::last_insert_id_used manually, as this statement
|
||||||
|
uses LAST_INSERT_ID() in a sense, and should issue
|
||||||
|
LAST_INSERT_ID_EVENT.
|
||||||
|
*/
|
||||||
|
thd->last_insert_id_used= TRUE;
|
||||||
|
|
||||||
cond=new_cond;
|
cond=new_cond;
|
||||||
/*
|
/*
|
||||||
Item_func_eq can't be fixed after creation so we do not check
|
Item_func_eq can't be fixed after creation so we do not check
|
||||||
|
@ -568,7 +568,7 @@ int mysql_update(THD *thd,
|
|||||||
thd->row_count_func=
|
thd->row_count_func=
|
||||||
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
||||||
send_ok(thd, (ulong) thd->row_count_func,
|
send_ok(thd, (ulong) thd->row_count_func,
|
||||||
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
thd->insert_id_used ? thd->last_insert_id : 0L,buff);
|
||||||
DBUG_PRINT("info",("%d records updated",updated));
|
DBUG_PRINT("info",("%d records updated",updated));
|
||||||
}
|
}
|
||||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
|
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
|
||||||
@ -1567,6 +1567,6 @@ bool multi_update::send_eof()
|
|||||||
thd->row_count_func=
|
thd->row_count_func=
|
||||||
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
||||||
::send_ok(thd, (ulong) thd->row_count_func,
|
::send_ok(thd, (ulong) thd->row_count_func,
|
||||||
thd->insert_id_used ? thd->insert_id() : 0L,buff);
|
thd->insert_id_used ? thd->last_insert_id : 0L,buff);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -15237,6 +15237,43 @@ static void test_bug21206()
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bug#21726: Incorrect result with multiple invocations of
|
||||||
|
LAST_INSERT_ID
|
||||||
|
|
||||||
|
Test that client gets updated value of insert_id on UPDATE that uses
|
||||||
|
LAST_INSERT_ID(expr).
|
||||||
|
*/
|
||||||
|
static void test_bug21726()
|
||||||
|
{
|
||||||
|
const char *create_table[]=
|
||||||
|
{
|
||||||
|
"DROP TABLE IF EXISTS t1",
|
||||||
|
"CREATE TABLE t1 (i INT)",
|
||||||
|
"INSERT INTO t1 VALUES (1)",
|
||||||
|
};
|
||||||
|
const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
|
||||||
|
int rc;
|
||||||
|
my_ulonglong insert_id;
|
||||||
|
|
||||||
|
DBUG_ENTER("test_bug21726");
|
||||||
|
myheader("test_bug21726");
|
||||||
|
|
||||||
|
fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, update_query);
|
||||||
|
myquery(rc);
|
||||||
|
insert_id= mysql_insert_id(mysql);
|
||||||
|
DIE_UNLESS(insert_id == 2);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, update_query);
|
||||||
|
myquery(rc);
|
||||||
|
insert_id= mysql_insert_id(mysql);
|
||||||
|
DIE_UNLESS(insert_id == 3);
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
@ -15511,7 +15548,8 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug17667", test_bug17667 },
|
{ "test_bug17667", test_bug17667 },
|
||||||
{ "test_bug19671", test_bug19671 },
|
{ "test_bug19671", test_bug19671 },
|
||||||
{ "test_bug15752", test_bug15752 },
|
{ "test_bug15752", test_bug15752 },
|
||||||
{ "test_bug21206", test_bug21206},
|
{ "test_bug21206", test_bug21206 },
|
||||||
|
{ "test_bug21726", test_bug21726 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user