Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  mockturtle.local:/home/dlenev/src/mysql-5.0-rt-merge


mysql-test/r/ps.result:
  Auto merged
mysql-test/t/ps.test:
  Auto merged
sql/item.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
This commit is contained in:
unknown 2006-10-02 22:53:10 +04:00
commit 2e2198633e
52 changed files with 1368 additions and 157 deletions

View File

@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# 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)
PROTOCOL_VERSION=10
@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=26
NDB_VERSION_BUILD=27
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?

View File

@ -1370,7 +1370,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
if (filecopy(param,new_file,info->dfile,0L,new_header_length,
if (new_header_length &&
filecopy(param,new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
info->s->state.dellink= HA_OFFSET_ERROR;
@ -2072,7 +2073,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
if (filecopy(param, new_file,info->dfile,0L,new_header_length,
if (new_header_length &&
filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
@ -2440,7 +2442,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
if (filecopy(param, new_file,info->dfile,0L,new_header_length,
if (new_header_length &&
filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)

View File

@ -446,7 +446,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
else
{
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))
goto err;
ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,

View File

@ -126,7 +126,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
doc_cnt++;
if (strcmp(buf, buf2))
{
if (*buf2)
@ -151,6 +150,7 @@ int main(int argc,char *argv[])
keylen2=keylen;
doc_cnt=0;
}
doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
}
if (dump)
{
@ -166,7 +166,6 @@ int main(int argc,char *argv[])
if (count || stats)
{
doc_cnt++;
if (*buf2)
{
uniq++;

View File

@ -33,7 +33,7 @@
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
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;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO *m_info=0;
@ -89,7 +89,10 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
else
fn_format(buff, buff, "", "", 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;
}
if (!m_info) /* First file */
{
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;
}
m_info->reclength=isam->s->base.reclength;
min_keys= isam->s->base.keys;
errpos=3;
}
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->del+= isam->state->del;
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++)
m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] /
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;
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));
/* this works ok if the table list is empty */

View File

@ -65,6 +65,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
error=my_errno;
}
}
else
my_errno= error= HA_ERR_WRONG_INDEX;
return error;
}

View File

@ -755,6 +755,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
export_set(5, name, upper(name), ",", 5)
test1,TEST1,test1,TEST1,TEST1
'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
CREATE TABLE t1 (
status enum('active','passive') collate latin1_general_ci
NOT NULL default 'passive'
);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`status` enum('active','passive') character set latin1 collate latin1_general_ci NOT NULL default 'passive'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t1 ADD a int NOT NULL AFTER status;
CREATE TABLE t2 (
status enum('active','passive') collate ucs2_turkish_ci
NOT NULL default 'passive'
);
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`status` enum('active','passive') character set ucs2 collate ucs2_turkish_ci NOT NULL default 'passive'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t2 ADD a int NOT NULL AFTER status;
DROP TABLE t1,t2;
select password(name) from bug20536;
password(name)
????????????????????

View File

@ -7,6 +7,7 @@ insert delayed into t1 set a = 4;
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 (7, NULL);
FLUSH TABLE t1;
insert into t1 set a = 8,tmsp=19711006010203;
select * from t1 where tmsp=0;
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,"this will give an","error");
ERROR 21S01: Column count doesn't match value count at row 1
FLUSH TABLE t1;
show status like 'not_flushed_delayed_rows';
Variable_name Value
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);
FLUSH TABLE t1;
select * from t1 order by a;
a
1
@ -69,3 +72,174 @@ a
12
13
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;

View File

@ -654,3 +654,12 @@ CHAR_LENGTH( GROUP_CONCAT(b) )
240001
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3);
SELECT GROUP_CONCAT(a), x
FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s
GROUP BY x;
GROUP_CONCAT(a) x
2 1,2
1 2,3
DROP TABLE t1;

View File

@ -860,8 +860,8 @@ CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT t1.b))
0
2
1
SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT 12))
1
@ -1013,7 +1013,7 @@ SELECT SQL_NO_CACHE
WHERE ttt.a = ccc.b AND ttt.a = t.a GROUP BY ttt.a) AS minid
FROM t1 t, t2 c WHERE t.a = c.b;
minid
NULL
1
DROP TABLE t1,t2;
create table t1 select variance(0);
show create table t1;

View File

@ -821,12 +821,3 @@ a b real_b
68 France France
DROP VIEW v1;
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, KEY(a));
INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4);
EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 4
EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
DROP TABLE t1;

View File

@ -178,9 +178,9 @@ t3 CREATE TABLE `t3` (
) 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);
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;
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 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);
@ -768,6 +768,21 @@ Table Op Msg_type Msg_text
test.t1 check status OK
test.t2 check status OK
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 t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);

View File

@ -909,6 +909,53 @@ create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
deallocate prepare stmt;
CREATE TABLE t1(
ID int(10) unsigned NOT NULL auto_increment,
Member_ID varchar(15) NOT NULL default '',
Action varchar(12) NOT NULL,
Action_Date datetime NOT NULL,
Track varchar(15) default NULL,
User varchar(12) default NULL,
Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
PRIMARY KEY (ID),
KEY Action (Action),
KEY Action_Date (Action_Date)
);
INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
('111111', 'Enrolled', '2006-03-01', 'CAD' ),
('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CHF' ),
('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
('333333', 'Enrolled', '2006-03-01', 'CAD' ),
('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
('444444', 'Enrolled', '2006-03-01', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
('555555', 'Enrolled', '2006-07-21', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
('666666', 'Enrolled', '2006-02-09', 'CAD' ),
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
('666666', 'Disenrolled', '2006-06-01', 'CAD' );
PREPARE STMT FROM
"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
WHERE Member_ID=? AND Action='Enrolled' AND
(Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
WHERE Member_ID=?
GROUP BY Track
HAVING Track>='CAD' AND
MAX(Action_Date)>'2006-03-01')";
SET @id='111111';
EXECUTE STMT USING @id,@id;
GROUP_CONCAT(Track SEPARATOR ', ')
NULL
SET @id='222222';
EXECUTE STMT USING @id,@id;
GROUP_CONCAT(Track SEPARATOR ', ')
CAD
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
End of 4.1 tests
create table t1 (a varchar(20));
insert into t1 values ('foo');

View File

@ -234,6 +234,135 @@ n b
2 100
3 350
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

View File

@ -1160,7 +1160,7 @@ Code2 char(2) NOT NULL default '',
PRIMARY KEY (Code)
) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
Continent Name Population
Oceania Sydney 3276207
@ -2512,7 +2512,7 @@ Code2 char(2) NOT NULL default ''
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
@ -2966,6 +2966,42 @@ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
a a b
10 1 359
drop table t1,t2;
CREATE TABLE t1 (
field1 int NOT NULL,
field2 int NOT NULL,
field3 int NOT NULL,
PRIMARY KEY (field1,field2,field3)
);
CREATE TABLE t2 (
fieldA int NOT NULL,
fieldB int NOT NULL,
PRIMARY KEY (fieldA,fieldB)
);
INSERT INTO t1 VALUES
(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
SELECT field1, field2, COUNT(*)
FROM t1 GROUP BY field1, field2;
field1 field2 COUNT(*)
1 1 2
1 2 3
1 3 1
SELECT field1, field2
FROM t1
GROUP BY field1, field2
HAVING COUNT(*) >= ALL (SELECT fieldB
FROM t2 WHERE fieldA = field1);
field1 field2
1 2
SELECT field1, field2
FROM t1
GROUP BY field1, field2
HAVING COUNT(*) < ANY (SELECT fieldB
FROM t2 WHERE fieldA = field1);
field1 field2
1 1
1 3
DROP TABLE t1, t2;
create table t1 (df decimal(5,1));
insert into t1 values(1.1);
insert into t1 values(2.2);
@ -3422,3 +3458,64 @@ id select_type table type possible_keys key key_len ref rows Extra
4 UNION t12 system NULL NULL NULL NULL 0 const row not found
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT);
INSERT INTO t2 values (1);
INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT t1.b) from t2)
2
1
1
SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
FROM t1 GROUP BY t1.a;
(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
2
1
1
SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
2 2
1 1
1 1
SELECT COUNT(DISTINCT t1.b),
(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
FROM t1 GROUP BY t1.a;
COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
2 2
1 1
1 1
SELECT (
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
FROM t1 GROUP BY t1.a;
(
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
2
1
1
SELECT (
SELECT (
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
FROM t1 GROUP BY t1.a LIMIT 1)
FROM t1 t2
GROUP BY t2.a;
(
SELECT (
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
FROM t1 GROUP BY t1.a LIMIT 1)
2
2
2
DROP TABLE t1,t2;

View File

@ -472,11 +472,11 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
insert into v3 values (-60,4,30);
ERROR HY000: The target table v3 of the INSERT is not updatable
ERROR HY000: The target table v3 of the INSERT is not insertable-into
insert into v4 values (-60,4,30);
ERROR HY000: The target table v4 of the INSERT is not updatable
ERROR HY000: The target table v4 of the INSERT is not insertable-into
insert into v5 values (-60,4,30);
ERROR HY000: The target table v5 of the INSERT is not updatable
ERROR HY000: The target table v5 of the INSERT is not insertable-into
insert into v1 values (-60,4,30);
insert into v1 (z,y,x) values (50,6,-100);
insert into v2 values (5,40);
@ -499,11 +499,11 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
insert into v3 select c, b, a from t2;
ERROR HY000: The target table v3 of the INSERT is not updatable
ERROR HY000: The target table v3 of the INSERT is not insertable-into
insert into v4 select c, b, a from t2;
ERROR HY000: The target table v4 of the INSERT is not updatable
ERROR HY000: The target table v4 of the INSERT is not insertable-into
insert into v5 select c, b, a from t2;
ERROR HY000: The target table v5 of the INSERT is not updatable
ERROR HY000: The target table v5 of the INSERT is not insertable-into
insert into v1 select c, b, a from t2;
insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
insert into v2 select b+1, a+10 from t2;
@ -1352,14 +1352,14 @@ drop table t1;
create table t1 (s1 smallint);
create view v1 as select * from t1 where 20 < (select (s1) from t1);
insert into v1 values (30);
ERROR HY000: The target table v1 of the INSERT is not updatable
ERROR HY000: The target table v1 of the INSERT is not insertable-into
create view v2 as select * from t1;
create view v3 as select * from t1 where 20 < (select (s1) from v2);
insert into v3 values (30);
ERROR HY000: The target table v3 of the INSERT is not updatable
ERROR HY000: The target table v3 of the INSERT is not insertable-into
create view v4 as select * from v2 where 20 < (select (s1) from t1);
insert into v4 values (30);
ERROR HY000: The target table v4 of the INSERT is not updatable
ERROR HY000: The target table v4 of the INSERT is not insertable-into
drop view v4, v3, v2, v1;
drop table t1;
create table t1 (a int);
@ -2911,7 +2911,7 @@ INSERT INTO v2 VALUES (0);
RETURN 0;
END |
SELECT f2();
ERROR HY000: The target table v2 of the INSERT is not updatable
ERROR HY000: The target table v2 of the INSERT is not insertable-into
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v1, v2;
@ -2935,4 +2935,25 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
DROP VIEW v1;
DROP TABLE t1;
create table t1 (s1 int);
create view v1 as select s1 as a, s1 as b from t1;
insert into v1 values (1,1);
ERROR HY000: The target table v1 of the INSERT is not insertable-into
update v1 set a = 5;
drop view v1;
drop table t1;
CREATE TABLE t1(pk int PRIMARY KEY);
CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int);
CREATE ALGORITHM=MERGE VIEW v1 AS
SELECT t1.*
FROM t1 JOIN t2
ON t2.fk = t1.pk AND
t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org);
SHOW WARNINGS;
Level Code Message
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
DROP VIEW v1;
DROP TABLE t1, t2;
End of 5.0 tests.

View File

@ -484,6 +484,27 @@ select make_set(3, name, upper(name)) from bug20536;
select export_set(5, name, upper(name)) from bug20536;
select export_set(5, name, upper(name), ",", 5) from bug20536;
#
# Bug #20108: corrupted default enum value for a ucs2 field
#
CREATE TABLE t1 (
status enum('active','passive') collate latin1_general_ci
NOT NULL default 'passive'
);
SHOW CREATE TABLE t1;
ALTER TABLE t1 ADD a int NOT NULL AFTER status;
CREATE TABLE t2 (
status enum('active','passive') collate ucs2_turkish_ci
NOT NULL default 'passive'
);
SHOW CREATE TABLE t2;
ALTER TABLE t2 ADD a int NOT NULL AFTER status;
DROP TABLE t1,t2;
# Some broken functions: add these tests just to document current behavior.
# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would

View File

@ -17,7 +17,8 @@ insert delayed into t1 set a = 4;
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 (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;
select * from t1 where tmsp=0;
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");
--error 1136
insert delayed into t1 values (3,"this will give an","error");
# 2 was not enough for --ps-protocol
--sleep 4
# Wait until the rows are flushed to the table files.
FLUSH TABLE t1;
show status like 'not_flushed_delayed_rows';
select * from t1;
drop table t1;
@ -92,10 +93,145 @@ insert delayed into t1 values(null);
# Works, since the delayed-counter is 8, which is unused
insert delayed into t1 values(null);
# Wait until the rows are flushed to the table files.
FLUSH TABLE t1;
# 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;
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;

View File

@ -447,3 +447,18 @@ SELECT a, CHAR_LENGTH(b) FROM t1;
SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1;
SET GROUP_CONCAT_MAX_LEN = 1024;
DROP TABLE t1;
#
# Bug #22015: crash with GROUP_CONCAT over a derived table that
# returns the results of aggregation by GROUP_CONCAT
#
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,1), (1,2), (2,2), (1,3);
SELECT GROUP_CONCAT(a), x
FROM (SELECT a, GROUP_CONCAT(b) x FROM t1 GROUP BY a) AS s
GROUP BY x;
DROP TABLE t1;

View File

@ -655,15 +655,3 @@ where t2.b=v1.a GROUP BY t2.b;
DROP VIEW v1;
DROP TABLE t1,t2;
#
# Bug #21174: Index degrades sort performance and
# optimizer does not honor IGNORE INDEX
#
CREATE TABLE t1 (a INT, b INT, KEY(a));
INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4);
EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2;
EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2;
DROP TABLE t1;

View File

@ -378,6 +378,31 @@ select * from t3;
check table t1, t2;
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
#

View File

@ -988,6 +988,58 @@ execute stmt;
drop temporary table t1;
deallocate prepare stmt;
#
# BUG#22085: Crash on the execution of a prepared statement that
# uses an IN subquery with aggregate functions in HAVING
#
CREATE TABLE t1(
ID int(10) unsigned NOT NULL auto_increment,
Member_ID varchar(15) NOT NULL default '',
Action varchar(12) NOT NULL,
Action_Date datetime NOT NULL,
Track varchar(15) default NULL,
User varchar(12) default NULL,
Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
PRIMARY KEY (ID),
KEY Action (Action),
KEY Action_Date (Action_Date)
);
INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
('111111', 'Enrolled', '2006-03-01', 'CAD' ),
('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CHF' ),
('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
('333333', 'Enrolled', '2006-03-01', 'CAD' ),
('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
('444444', 'Enrolled', '2006-03-01', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
('555555', 'Enrolled', '2006-07-21', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
('666666', 'Enrolled', '2006-02-09', 'CAD' ),
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
('666666', 'Disenrolled', '2006-06-01', 'CAD' );
PREPARE STMT FROM
"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
WHERE Member_ID=? AND Action='Enrolled' AND
(Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
WHERE Member_ID=?
GROUP BY Track
HAVING Track>='CAD' AND
MAX(Action_Date)>'2006-03-01')";
SET @id='111111';
EXECUTE STMT USING @id,@id;
SET @id='222222';
EXECUTE STMT USING @id,@id;
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
--echo End of 4.1 tests
############################# 5.0 tests start ################################
#

View File

@ -244,6 +244,118 @@ select * from t1 order by n;
connection master;
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;
--echo

View File

@ -665,7 +665,7 @@ CREATE TABLE t2 (
) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
@ -1526,7 +1526,7 @@ CREATE TABLE t1 (
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
@ -1918,6 +1918,43 @@ SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
drop table t1,t2;
#
# Bug #21853: assert failure for a grouping query with
# an ALL/ANY quantified subquery in HAVING
#
CREATE TABLE t1 (
field1 int NOT NULL,
field2 int NOT NULL,
field3 int NOT NULL,
PRIMARY KEY (field1,field2,field3)
);
CREATE TABLE t2 (
fieldA int NOT NULL,
fieldB int NOT NULL,
PRIMARY KEY (fieldA,fieldB)
);
INSERT INTO t1 VALUES
(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
SELECT field1, field2, COUNT(*)
FROM t1 GROUP BY field1, field2;
SELECT field1, field2
FROM t1
GROUP BY field1, field2
HAVING COUNT(*) >= ALL (SELECT fieldB
FROM t2 WHERE fieldA = field1);
SELECT field1, field2
FROM t1
GROUP BY field1, field2
HAVING COUNT(*) < ANY (SELECT fieldB
FROM t2 WHERE fieldA = field1);
DROP TABLE t1, t2;
# End of 4.1 tests
#
@ -2332,3 +2369,34 @@ explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
DROP TABLE t1;
#
# Bug #21540: Subqueries with no from and aggregate functions return
# wrong results
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT);
INSERT INTO t2 values (1);
INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
FROM t1 GROUP BY t1.a;
SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
SELECT COUNT(DISTINCT t1.b),
(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
FROM t1 GROUP BY t1.a;
SELECT (
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
FROM t1 GROUP BY t1.a;
SELECT (
SELECT (
SELECT (
SELECT COUNT(DISTINCT t1.b)
)
)
FROM t1 GROUP BY t1.a LIMIT 1)
FROM t1 t2
GROUP BY t2.a;
DROP TABLE t1,t2;

View File

@ -347,13 +347,13 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
# try insert to VIEW with fields duplicate
-- error 1288
-- error 1471
insert into v3 values (-60,4,30);
# try insert to VIEW with expression in SELECT list
-- error 1288
-- error 1471
insert into v4 values (-60,4,30);
# try insert to VIEW using temporary table algorithm
-- error 1288
-- error 1471
insert into v5 values (-60,4,30);
insert into v1 values (-60,4,30);
insert into v1 (z,y,x) values (50,6,-100);
@ -375,13 +375,13 @@ create view v3 (x,y,z) as select b, a, b from t1;
create view v4 (x,y,z) as select c+1, b, a from t1;
create algorithm=temptable view v5 (x,y,z) as select c, b, a from t1;
# try insert to VIEW with fields duplicate
-- error 1288
-- error 1471
insert into v3 select c, b, a from t2;
# try insert to VIEW with expression in SELECT list
-- error 1288
-- error 1471
insert into v4 select c, b, a from t2;
# try insert to VIEW using temporary table algorithm
-- error 1288
-- error 1471
insert into v5 select c, b, a from t2;
insert into v1 select c, b, a from t2;
insert into v1 (z,y,x) select a+20,b+2,-100 from t2;
@ -1249,14 +1249,14 @@ drop table t1;
#
create table t1 (s1 smallint);
create view v1 as select * from t1 where 20 < (select (s1) from t1);
-- error 1288
-- error 1471
insert into v1 values (30);
create view v2 as select * from t1;
create view v3 as select * from t1 where 20 < (select (s1) from v2);
-- error 1288
-- error 1471
insert into v3 values (30);
create view v4 as select * from v2 where 20 < (select (s1) from t1);
-- error 1288
-- error 1471
insert into v4 values (30);
drop view v4, v3, v2, v1;
drop table t1;
@ -2825,7 +2825,7 @@ BEGIN
END |
delimiter ;|
--error ER_NON_UPDATABLE_TABLE
--error ER_NON_INSERTABLE_TABLE
SELECT f2();
DROP FUNCTION f1;
@ -2850,4 +2850,33 @@ EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
DROP VIEW v1;
DROP TABLE t1;
#
# Bug #5505: Wrong error message on INSERT into a view
#
create table t1 (s1 int);
create view v1 as select s1 as a, s1 as b from t1;
--error 1471
insert into v1 values (1,1);
update v1 set a = 5;
drop view v1;
drop table t1;
#
# Bug #21646: view qith a subquery in ON expression
#
CREATE TABLE t1(pk int PRIMARY KEY);
CREATE TABLE t2(pk int PRIMARY KEY, fk int, ver int, org int);
CREATE ALGORITHM=MERGE VIEW v1 AS
SELECT t1.*
FROM t1 JOIN t2
ON t2.fk = t1.pk AND
t2.ver = (SELECT MAX(t.ver) FROM t2 t WHERE t.org = t2.org);
SHOW WARNINGS;
SHOW CREATE VIEW v1;
DROP VIEW v1;
DROP TABLE t1, t2;
--echo End of 5.0 tests.

View File

@ -46,7 +46,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
MyFlags));
oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
DBUG_RETURN(0);
DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
if (oldsize > newlength)

View File

@ -164,28 +164,22 @@ void delete_queue(QUEUE *queue)
void queue_insert(register QUEUE *queue, byte *element)
{
reg2 uint idx,next;
reg2 uint idx, next;
int cmp;
#ifndef DBUG_OFF
if (queue->elements < queue->max_elements)
#endif
DBUG_ASSERT(queue->elements < queue->max_elements);
queue->root[0]= element;
idx= ++queue->elements;
/* 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;
idx= ++queue->elements;
/* 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]= queue->root[next];
idx= next;
}
queue->root[idx]= element;
}
/* Remove item from queue */
@ -193,16 +187,12 @@ void queue_insert(register QUEUE *queue, byte *element)
byte *queue_remove(register QUEUE *queue, uint idx)
{
#ifndef DBUG_OFF
if (idx >= queue->max_elements)
return 0;
#endif
{
byte *element=queue->root[++idx]; /* Intern index starts from 1 */
queue->root[idx]=queue->root[queue->elements--];
_downheap(queue,idx);
return element;
}
byte *element;
DBUG_ASSERT(idx < queue->max_elements);
element= queue->root[++idx]; /* Intern index starts from 1 */
queue->root[idx]= queue->root[queue->elements--];
_downheap(queue, idx);
return element;
}
/* Fix when element on top has been replaced */

View File

@ -1432,6 +1432,8 @@ public:
uint decimals, flags, pack_length, key_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
TYPELIB *save_interval; // Temporary copy for the above
// Used only for UCS2 intervals
List<String> interval_list;
CHARSET_INFO *charset;
Field::geometry_type geom_type;

View File

@ -1268,6 +1268,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
switch ((sortorder->result_type=sortorder->item->result_type())) {
case STRING_RESULT:
sortorder->length=sortorder->item->max_length;
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
{
sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);

View File

@ -120,6 +120,8 @@ static bool archive_inited= FALSE;
/* Variables for archive share methods */
pthread_mutex_t archive_mutex;
static HASH archive_open_tables;
static z_off_t max_zfile_size;
static int zoffset_size;
/* The file extension */
#define ARZ ".ARZ" // The data file
@ -203,6 +205,18 @@ bool archive_db_init()
}
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;
DBUG_RETURN(FALSE);
}
@ -240,7 +254,7 @@ ha_archive::ha_archive(TABLE *table_arg)
buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
/* 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));
}
@ -480,7 +494,8 @@ int ha_archive::init_archive_writer()
DBUG_RETURN(1);
}
share->archive_write_open= TRUE;
info(HA_STATUS_TIME);
share->approx_file_size= data_file_length;
DBUG_RETURN(0);
}
@ -651,10 +666,21 @@ error:
*/
int ha_archive::real_write_row(byte *buf, gzFile writer)
{
z_off_t written;
z_off_t written, total_row_length;
uint *ptr, *end;
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);
DBUG_PRINT("ha_archive::real_write_row", ("Wrote %d bytes expected %d", written, table->s->reclength));
if (!delayed_insert || !bulk_insert)

View File

@ -38,6 +38,7 @@ typedef struct st_archive_share {
bool dirty; /* Flag for if a flush should occur */
bool crashed; /* Meta file is crashed */
ha_rows rows_recorded; /* Number of rows in tables */
z_off_t approx_file_size; /* Approximate archive data file size */
} ARCHIVE_SHARE;
/*

View File

@ -1182,6 +1182,7 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
split_sum_func(thd, ref_pointer_array, fields);
}
else if ((type() == SUM_FUNC_ITEM || (used_tables() & ~PARAM_TABLE_BIT)) &&
type() != SUBSELECT_ITEM &&
(type() != REF_ITEM ||
((Item_ref*)this)->ref_type() == Item_ref::VIEW_REF))
{

View File

@ -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()
{
THD *thd= current_thd;
@ -3354,12 +3382,13 @@ longlong Item_func_last_insert_id::val_int()
longlong value= args[0]->val_int();
thd->insert_id(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 */
longlong Item_func_benchmark::val_int()

View File

@ -891,6 +891,7 @@ public:
if (arg_count)
max_length= args[0]->max_length;
}
bool fix_fields(THD *thd, Item **ref);
};

View File

@ -246,7 +246,27 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
aggr_sl->inner_sum_func_list->next= this;
}
aggr_sl->inner_sum_func_list= this;
aggr_sl->with_sum_func= 1;
/*
Mark Item_subselect(s) as containing aggregate function all the way up
to aggregate function's calculation context.
Note that we must not mark the Item of calculation context itself
because with_sum_func on the calculation context st_select_lex is
already set above.
with_sum_func being set for an Item means that this Item refers
(somewhere in it, e.g. one of its arguments if it's a function) directly
or through intermediate items to an aggregate function that is calculated
in a context "outside" of the Item (e.g. in the current or outer select).
with_sum_func being set for an st_select_lex means that this st_select_lex
has aggregate functions directly referenced (i.e. not through a sub-select).
*/
for (sl= thd->lex->current_select;
sl && sl != aggr_sl && sl->master_unit()->item;
sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1;
}
return FALSE;
}

View File

@ -3365,7 +3365,6 @@ int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
{
switch (type) {
case LAST_INSERT_ID_EVENT:
thd->last_insert_id_used = 1;
thd->last_insert_id = val;
break;
case INSERT_ID_EVENT:

View File

@ -446,7 +446,8 @@ enum enum_parsing_place
NO_MATTER,
IN_HAVING,
SELECT_LIST,
IN_WHERE
IN_WHERE,
IN_ON
};
struct st_table;

View File

@ -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,
LEX_STRING *base)
{
thd->sys_var_tmp.long_value= (long) thd->insert_id();
return (byte*) &thd->last_insert_id;
if (!thd->last_insert_id_used)
{
/*
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;
}

View File

@ -3813,7 +3813,7 @@ ER_WRONG_MRG_TABLE
cze "V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì"
dan "Tabellerne i MERGE er ikke defineret ens"
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"
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"
@ -5631,3 +5631,6 @@ ER_HOSTNAME
eng "host name"
ER_WRONG_STRING_LENGTH
eng "String '%-.70s' is too long for %s (should be no longer than %d)"
ER_NON_INSERTABLE_TABLE
eng "The target table %-.100s of the %s is not insertable-into"

View File

@ -902,8 +902,11 @@ void update_non_unique_table_error(TABLE_LIST *update,
*/
if (update->view)
{
/* Issue the ER_NON_INSERTABLE_TABLE error for an INSERT */
if (update->view == duplicate->view)
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), update->alias, operation);
my_error(!strncmp(operation, "INSERT", 6) ?
ER_NON_INSERTABLE_TABLE : ER_NON_UPDATABLE_TABLE, MYF(0),
update->alias, operation);
else
my_error(ER_VIEW_PREVENT_UPDATE, MYF(0),
(duplicate->view ? duplicate->alias : update->alias),

View File

@ -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()
{
last_insert_id_used= FALSE;
if (clear_next_insert_id)
{
clear_next_insert_id= 0;

View File

@ -1252,17 +1252,29 @@ public:
ulonglong next_insert_id;
/* Remember last next_insert_id to reset it if something went wrong */
ulonglong prev_insert_id;
/*
The insert_id used for the last statement or set by SET LAST_INSERT_ID=#
or SELECT LAST_INSERT_ID(#). Used for binary log and returned by
LAST_INSERT_ID()
At the beginning of the statement last_insert_id holds the first
generated value of the previous statement. During statement
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;
/*
Set to the first value that LAST_INSERT_ID() returned for the last
statement. When this is set, last_insert_id_used is set to true.
current_insert_id remembers the first generated value of the
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 limit_found_rows;
ulonglong options; /* Bitmap of states */
longlong row_count_func; /* For the ROW_COUNT() function */
@ -1325,7 +1337,22 @@ public:
bool last_cuted_field;
bool no_errors, password, is_fatal_error;
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() */
bool substitute_null_with_insert_id;
bool in_lock_tables;
@ -1461,15 +1488,6 @@ public:
insert_id_used=1;
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)
{
return limit_found_rows;

View File

@ -111,7 +111,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (!table_list->updatable)
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
return -1;
}
@ -214,7 +214,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
(table_list->view &&
check_view_insertability(thd, table_list)))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
return -1;
}
@ -590,10 +590,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
#endif
error=write_record(thd, table ,&info);
/*
If auto_increment values are used, save the first one
for 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 auto_increment values are used, save the first one for
LAST_INSERT_ID() and for the update log.
*/
if (! id && thd->insert_id_used)
{ // Get auto increment value
@ -1303,6 +1301,9 @@ public:
time_t start_time;
bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
ulonglong last_insert_id;
ulonglong next_insert_id;
ulong auto_increment_increment;
ulong auto_increment_offset;
timestamp_auto_set_type timestamp_field_type;
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->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->stacked_inserts++;
di->status=1;
@ -2055,6 +2072,14 @@ bool delayed_insert::handle_inserts(void)
thd.insert_id_used=row->insert_id_used;
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.handle_duplicates= row->dup;
if (info.ignore ||
@ -2076,6 +2101,20 @@ bool delayed_insert::handle_inserts(void)
info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
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)
{
@ -2121,6 +2160,7 @@ bool delayed_insert::handle_inserts(void)
/* This should never happen */
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@ -2146,6 +2186,7 @@ bool delayed_insert::handle_inserts(void)
{ // This shouldn't happen
table->file->print_error(error,MYF(0));
sql_print_error("%s",thd.net.last_error);
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
goto err;
}
query_cache_invalidate3(&thd, table, 1);
@ -2153,13 +2194,16 @@ bool delayed_insert::handle_inserts(void)
DBUG_RETURN(0);
err:
DBUG_EXECUTE("error", max_rows= 0;);
/* Remove all not used rows */
while ((row=rows.get()))
{
delete row;
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
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);
pthread_mutex_lock(&mutex);
DBUG_RETURN(1);
@ -2447,7 +2491,7 @@ bool select_insert::send_data(List<Item> &values)
*/
table->next_number_field->reset();
if (!last_insert_id && thd->insert_id_used)
last_insert_id= thd->insert_id();
last_insert_id= thd->last_insert_id;
}
}
DBUG_RETURN(error);

View File

@ -1710,7 +1710,8 @@ bool st_lex::can_be_merged()
unit= unit->next_unit())
{
if (unit->first_select()->parent_lex == this &&
(unit->item == 0 || unit->item->place() != IN_WHERE))
(unit->item == 0 ||
(unit->item->place() != IN_WHERE && unit->item->place() != IN_ON)))
{
selects_allow_merge= 0;
break;

View File

@ -616,10 +616,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
thd->no_trans_update= no_trans_update;
/*
If auto_increment values are used, save the first one
for 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 auto_increment values are used, save the first one for
LAST_INSERT_ID() and for the binary/update log.
*/
if (!id && thd->insert_id_used)
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))
DBUG_RETURN(1);
/*
If auto_increment values are used, save the first one
for 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 auto_increment values are used, save the first one for
LAST_INSERT_ID() and for the binary/update log.
*/
if (!id && thd->insert_id_used)
id= thd->last_insert_id;

View File

@ -2421,6 +2421,20 @@ mysql_execute_command(THD *thd)
DBUG_ENTER("mysql_execute_command");
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 =>
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");
thd->free_list= 0;
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->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
SERVER_QUERY_NO_INDEX_USED |

View File

@ -8153,7 +8153,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
Field *field=((Item_field*) args[0])->field;
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_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
query_cache_abort(&thd->net);
@ -8161,9 +8161,16 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],
new Item_int("last_insert_id()",
thd->insert_id(),
thd->current_insert_id,
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;
/*
Item_func_eq can't be fixed after creation so we do not check
@ -11740,8 +11747,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
We must not try to use disabled keys.
*/
usable_keys= table->s->keys_in_use;
/* we must not consider keys that are disabled by IGNORE INDEX */
usable_keys.intersect(table->keys_in_use_for_query);
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
{

View File

@ -568,7 +568,7 @@ int mysql_update(THD *thd,
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
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));
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
@ -1561,6 +1561,6 @@ bool multi_update::send_eof()
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
::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;
}

View File

@ -1574,7 +1574,7 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
list->push_back(fld);
else
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
DBUG_RETURN(TRUE);
}
}

View File

@ -5212,11 +5212,13 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Select->parsing_place= IN_ON;
}
expr
{
add_join_on($3,$6);
Lex->pop_context();
Select->parsing_place= NO_MATTER;
}
| table_ref STRAIGHT_JOIN table_factor
ON
@ -5225,12 +5227,14 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Select->parsing_place= IN_ON;
}
expr
{
$3->straight=1;
add_join_on($3,$6);
Lex->pop_context();
Select->parsing_place= NO_MATTER;
}
| table_ref normal_join table_ref
USING
@ -5254,6 +5258,7 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Select->parsing_place= IN_ON;
}
expr
{
@ -5261,6 +5266,7 @@ join_table:
Lex->pop_context();
$5->outer_join|=JOIN_TYPE_LEFT;
$$=$5;
Select->parsing_place= NO_MATTER;
}
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
@ -5285,6 +5291,7 @@ join_table:
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Select->parsing_place= IN_ON;
}
expr
{
@ -5293,6 +5300,7 @@ join_table:
YYABORT;
add_join_on($$, $8);
Lex->pop_context();
Select->parsing_place= NO_MATTER;
}
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{

View File

@ -228,13 +228,19 @@ bool mysql_create_frm(THD *thd, my_string file_name,
goto err3;
{
/* Unescape all UCS2 intervals: were escaped in pack_headers */
/*
Restore all UCS2 intervals.
HEX representation of them is not needed anymore.
*/
List_iterator<create_field> it(create_fields);
create_field *field;
while ((field=it++))
{
if (field->interval && field->charset->mbminlen > 1)
unhex_type2(field->interval);
if (field->save_interval)
{
field->interval= field->save_interval;
field->save_interval= 0;
}
}
}
DBUG_RETURN(0);
@ -514,18 +520,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
reclength=(uint) (field->offset+ data_offset + length);
n_length+= (ulong) strlen(field->field_name)+1;
field->interval_id=0;
field->save_interval= 0;
if (field->interval)
{
uint old_int_count=int_count;
if (field->charset->mbminlen > 1)
{
/* Escape UCS2 intervals using HEX notation */
/*
Escape UCS2 intervals using HEX notation to avoid
problems with delimiters between enum elements.
As the original representation is still needed in
the function make_empty_rec to create a record of
filled with default values it is saved in save_interval
The HEX representation is created from this copy.
*/
field->save_interval= field->interval;
field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB));
*field->interval= *field->save_interval;
field->interval->type_names=
(const char **) sql_alloc(sizeof(char*) *
(field->interval->count+1));
field->interval->type_names[field->interval->count]= 0;
field->interval->type_lengths=
(uint *) sql_alloc(sizeof(uint) * field->interval->count);
for (uint pos= 0; pos < field->interval->count; pos++)
{
char *dst;
uint length= field->interval->type_lengths[pos], hex_length;
const char *src= field->interval->type_names[pos];
uint length= field->save_interval->type_lengths[pos], hex_length;
const char *src= field->save_interval->type_names[pos];
hex_length= length * 2;
field->interval->type_lengths[pos]= hex_length;
field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1);
@ -777,7 +801,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
field->charset,
field->geom_type,
field->unireg_check,
field->interval,
field->save_interval ? field->save_interval :
field->interval,
field->field_name,
&table);
if (!regfield)

View File

@ -15237,6 +15237,43 @@ static void test_bug21206()
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
@ -15511,7 +15548,8 @@ static struct my_tests_st my_tests[]= {
{ "test_bug17667", test_bug17667 },
{ "test_bug19671", test_bug19671 },
{ "test_bug15752", test_bug15752 },
{ "test_bug21206", test_bug21206},
{ "test_bug21206", test_bug21206 },
{ "test_bug21726", test_bug21726 },
{ 0, 0 }
};