Merge mysql.com:/home/jimw/my/mysql-5.0-12457

into  mysql.com:/home/jimw/my/mysql-5.0-clean
This commit is contained in:
unknown 2005-08-11 14:35:01 -07:00
commit 04e2ca68ff
60 changed files with 940 additions and 376 deletions

View File

@ -1598,11 +1598,8 @@ You can turn off this feature to get a quicker startup with -A\n\n");
mysql_free_result(fields); mysql_free_result(fields);
} }
else else
{
tee_fprintf(stdout,
"Didn't find any fields in table '%s'\n",table_row[0]);
field_names[i]= 0; field_names[i]= 0;
}
i++; i++;
} }
mysql_free_result(tables); mysql_free_result(tables);

View File

@ -2781,6 +2781,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
if (!disable_result_log) if (!disable_result_log)
{ {
ulong affected_rows; /* Ok to be undef if 'disable_info' is set */ ulong affected_rows; /* Ok to be undef if 'disable_info' is set */
LINT_INIT(affected_rows);
if (res) if (res)
{ {

View File

@ -1,7 +1,7 @@
INCLUDES = -I../include -I../taocrypt/include -I../mySTL INCLUDES = -I../include -I../taocrypt/include -I../mySTL
noinst_LIBRARIES = libyassl.a noinst_LTLIBRARIES = libyassl.la
libyassl_a_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \ libyassl_la_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \
handshake.cpp lock.cpp log.cpp socket_wrapper.cpp ssl.cpp \ handshake.cpp lock.cpp log.cpp socket_wrapper.cpp ssl.cpp \
template_instnt.cpp timer.cpp yassl_imp.cpp yassl_error.cpp yassl_int.cpp template_instnt.cpp timer.cpp yassl_imp.cpp yassl_error.cpp yassl_int.cpp
EXTRA_DIST = ../include/*.hpp ../include/openssl/*.h EXTRA_DIST = ../include/*.hpp ../include/openssl/*.h

View File

@ -1,7 +1,7 @@
INCLUDES = -I../include -I../../mySTL INCLUDES = -I../include -I../../mySTL
noinst_LIBRARIES = libtaocrypt.a noinst_LTLIBRARIES = libtaocrypt.la
libtaocrypt_a_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \ libtaocrypt_la_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \
coding.cpp dh.cpp des.cpp dsa.cpp file.cpp hash.cpp integer.cpp \ coding.cpp dh.cpp des.cpp dsa.cpp file.cpp hash.cpp integer.cpp \
md2.cpp md5.cpp misc.cpp random.cpp ripemd.cpp rsa.cpp sha.cpp \ md2.cpp md5.cpp misc.cpp random.cpp ripemd.cpp rsa.cpp sha.cpp \
template_instnt.cpp template_instnt.cpp

View File

@ -866,6 +866,11 @@ extern void add_compiled_collation(CHARSET_INFO *cs);
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
char *to, ulong to_length, char *to, ulong to_length,
const char *from, ulong length); const char *from, ulong length);
#ifdef __WIN__
#define BACKSLASH_MBTAIL
/* File system character set */
extern CHARSET_INFO *fs_character_set(void);
#endif
extern ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info, extern ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
char *to, ulong to_length, char *to, ulong to_length,
const char *from, ulong length); const char *from, ulong length);

View File

@ -94,6 +94,7 @@ extern ulint srv_max_dirty_pages_pct;
extern ulint srv_force_recovery; extern ulint srv_force_recovery;
extern ulong srv_thread_concurrency; extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
extern ulint srv_max_n_threads; extern ulint srv_max_n_threads;

View File

@ -261,6 +261,7 @@ Value 10 should be good if there are less than 4 processors + 4 disks in the
computer. Bigger computers need bigger values. */ computer. Bigger computers need bigger values. */
ulong srv_thread_concurrency = SRV_CONCURRENCY_THRESHOLD; ulong srv_thread_concurrency = SRV_CONCURRENCY_THRESHOLD;
ulong srv_commit_concurrency = 0;
os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data
structures */ structures */

View File

@ -221,6 +221,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
MI_INFO *info=ftb->info; MI_INFO *info=ftb->info;
uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength; uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength;
byte *lastkey_buf=ftbw->word+ftbw->off; byte *lastkey_buf=ftbw->word+ftbw->off;
LINT_INIT(off);
LINT_INIT(off); LINT_INIT(off);
if (ftbw->flags & FTB_FLAG_TRUNC) if (ftbw->flags & FTB_FLAG_TRUNC)

View File

@ -17,6 +17,15 @@ select 9223372036854775808+1;
select -(0-3),round(-(0-3)), round(9999999999999999999); select -(0-3),round(-(0-3)), round(9999999999999999999);
-(0-3) round(-(0-3)) round(9999999999999999999) -(0-3) round(-(0-3)) round(9999999999999999999)
3 3 9999999999999999999 3 3 9999999999999999999
select 1,11,101,1001,10001,100001,1000001,10000001,100000001,1000000001,10000000001,100000000001,1000000000001,10000000000001,100000000000001,1000000000000001,10000000000000001,100000000000000001,1000000000000000001,10000000000000000001;
1 11 101 1001 10001 100001 1000001 10000001 100000001 1000000001 10000000001 100000000001 1000000000001 10000000000001 100000000000001 1000000000000001 10000000000000001 100000000000000001 1000000000000000001 10000000000000000001
1 11 101 1001 10001 100001 1000001 10000001 100000001 1000000001 10000000001 100000000001 1000000000001 10000000000001 100000000000001 1000000000000001 10000000000000001 100000000000000001 1000000000000000001 10000000000000000001
select -1,-11,-101,-1001,-10001,-100001,-1000001,-10000001,-100000001,-1000000001,-10000000001,-100000000001,-1000000000001,-10000000000001,-100000000000001,-1000000000000001,-10000000000000001,-100000000000000001,-1000000000000000001,-10000000000000000001;
-1 -11 -101 -1001 -10001 -100001 -1000001 -10000001 -100000001 -1000000001 -10000000001 -100000000001 -1000000000001 -10000000000001 -100000000000001 -1000000000000001 -10000000000000001 -100000000000000001 -1000000000000000001 -10000000000000000001
-1 -11 -101 -1001 -10001 -100001 -1000001 -10000001 -100000001 -1000000001 -10000000001 -100000000001 -1000000000001 -10000000000001 -100000000000001 -1000000000000001 -10000000000000001 -100000000000000001 -1000000000000000001 -10000000000000000001
select conv(1,10,16),conv((1<<2)-1,10,16),conv((1<<10)-2,10,16),conv((1<<16)-3,10,16),conv((1<<25)-4,10,16),conv((1<<31)-5,10,16),conv((1<<36)-6,10,16),conv((1<<47)-7,10,16),conv((1<<48)-8,10,16),conv((1<<55)-9,10,16),conv((1<<56)-10,10,16),conv((1<<63)-11,10,16);
conv(1,10,16) conv((1<<2)-1,10,16) conv((1<<10)-2,10,16) conv((1<<16)-3,10,16) conv((1<<25)-4,10,16) conv((1<<31)-5,10,16) conv((1<<36)-6,10,16) conv((1<<47)-7,10,16) conv((1<<48)-8,10,16) conv((1<<55)-9,10,16) conv((1<<56)-10,10,16) conv((1<<63)-11,10,16)
1 3 3FE FFFD 1FFFFFC 7FFFFFFB FFFFFFFFA 7FFFFFFFFFF9 FFFFFFFFFFF8 7FFFFFFFFFFFF7 FFFFFFFFFFFFF6 7FFFFFFFFFFFFFF5
create table t1 (a bigint unsigned not null, primary key(a)); create table t1 (a bigint unsigned not null, primary key(a));
insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612); insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
select * from t1; select * from t1;

View File

@ -45,6 +45,123 @@ www. .se
select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1); select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1);
substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1) substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1)
tcx.se .se tcx.se .se
select substring_index('aaaaaaaaa1','a',1);
substring_index('aaaaaaaaa1','a',1)
select substring_index('aaaaaaaaa1','aa',1);
substring_index('aaaaaaaaa1','aa',1)
select substring_index('aaaaaaaaa1','aa',2);
substring_index('aaaaaaaaa1','aa',2)
aa
select substring_index('aaaaaaaaa1','aa',3);
substring_index('aaaaaaaaa1','aa',3)
aaaa
select substring_index('aaaaaaaaa1','aa',4);
substring_index('aaaaaaaaa1','aa',4)
aaaaaa
select substring_index('aaaaaaaaa1','aa',5);
substring_index('aaaaaaaaa1','aa',5)
aaaaaaaaa1
select substring_index('aaaaaaaaa1','aaa',1);
substring_index('aaaaaaaaa1','aaa',1)
select substring_index('aaaaaaaaa1','aaa',2);
substring_index('aaaaaaaaa1','aaa',2)
aaa
select substring_index('aaaaaaaaa1','aaa',3);
substring_index('aaaaaaaaa1','aaa',3)
aaaaaa
select substring_index('aaaaaaaaa1','aaa',4);
substring_index('aaaaaaaaa1','aaa',4)
aaaaaaaaa1
select substring_index('aaaaaaaaa1','aaaa',1);
substring_index('aaaaaaaaa1','aaaa',1)
select substring_index('aaaaaaaaa1','aaaa',2);
substring_index('aaaaaaaaa1','aaaa',2)
aaaa
select substring_index('aaaaaaaaa1','1',1);
substring_index('aaaaaaaaa1','1',1)
aaaaaaaaa
select substring_index('aaaaaaaaa1','a',-1);
substring_index('aaaaaaaaa1','a',-1)
1
select substring_index('aaaaaaaaa1','aa',-1);
substring_index('aaaaaaaaa1','aa',-1)
1
select substring_index('aaaaaaaaa1','aa',-2);
substring_index('aaaaaaaaa1','aa',-2)
aa1
select substring_index('aaaaaaaaa1','aa',-3);
substring_index('aaaaaaaaa1','aa',-3)
aaaa1
select substring_index('aaaaaaaaa1','aa',-4);
substring_index('aaaaaaaaa1','aa',-4)
aaaaaa1
select substring_index('aaaaaaaaa1','aa',-5);
substring_index('aaaaaaaaa1','aa',-5)
aaaaaaaaa1
select substring_index('aaaaaaaaa1','aaa',-1);
substring_index('aaaaaaaaa1','aaa',-1)
1
select substring_index('aaaaaaaaa1','aaa',-2);
substring_index('aaaaaaaaa1','aaa',-2)
aaa1
select substring_index('aaaaaaaaa1','aaa',-3);
substring_index('aaaaaaaaa1','aaa',-3)
aaaaaa1
select substring_index('aaaaaaaaa1','aaa',-4);
substring_index('aaaaaaaaa1','aaa',-4)
select substring_index('the king of thethe hill','the',-2);
substring_index('the king of thethe hill','the',-2)
the hill
select substring_index('the king of the the hill','the',-2);
substring_index('the king of the the hill','the',-2)
the hill
select substring_index('the king of the the hill','the',-2);
substring_index('the king of the the hill','the',-2)
the hill
select substring_index('the king of the the hill',' the ',-1);
substring_index('the king of the the hill',' the ',-1)
hill
select substring_index('the king of the the hill',' the ',-2);
substring_index('the king of the the hill',' the ',-2)
the hill
select substring_index('the king of the the hill',' ',-1);
substring_index('the king of the the hill',' ',-1)
hill
select substring_index('the king of the the hill',' ',-2);
substring_index('the king of the the hill',' ',-2)
the hill
select substring_index('the king of the the hill',' ',-3);
substring_index('the king of the the hill',' ',-3)
the hill
select substring_index('the king of the the hill',' ',-4);
substring_index('the king of the the hill',' ',-4)
the the hill
select substring_index('the king of the the hill',' ',-5);
substring_index('the king of the the hill',' ',-5)
of the the hill
select substring_index('the king of the.the hill','the',-2);
substring_index('the king of the.the hill','the',-2)
.the hill
select substring_index('the king of thethethe.the hill','the',-3);
substring_index('the king of thethethe.the hill','the',-3)
the.the hill
select substring_index('the king of thethethe.the hill','the',-1);
substring_index('the king of thethethe.the hill','the',-1)
hill
select substring_index('the king of the the hill','the',1);
substring_index('the king of the the hill','the',1)
select substring_index('the king of the the hill','the',2);
substring_index('the king of the the hill','the',2)
the king of
select substring_index('the king of the the hill','the',3);
substring_index('the king of the the hill','the',3)
the king of the
select concat(':',ltrim(' left '),':',rtrim(' right '),':'); select concat(':',ltrim(' left '),':',rtrim(' right '),':');
concat(':',ltrim(' left '),':',rtrim(' right '),':') concat(':',ltrim(' left '),':',rtrim(' right '),':')
:left : right: :left : right:

View File

@ -191,3 +191,9 @@ ERROR 23000: Column 'a' in field list is ambiguous
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ; insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
ERROR 23000: Column 't1.a' in field list is ambiguous ERROR 23000: Column 't1.a' in field list is ambiguous
drop table t1; drop table t1;
CREATE TABLE t1 (
a BIGINT(20) NOT NULL DEFAULT 0,
PRIMARY KEY (a)
) ENGINE=MyISAM;
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1;

View File

@ -947,24 +947,18 @@ COUNT(*)
Warnings: Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid'
Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid'; SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
COUNT(*) COUNT(*)
0 0
Warnings: Warnings:
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
Warning 1292 Truncated incorrect INTEGER value: '20050328 invalid'
Warning 1292 Truncated incorrect INTEGER value: '20050328 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid'; SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
COUNT(*) COUNT(*)
0 0
Warnings: Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid'
Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid'
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 0 Qcache_queries_in_cache 0

View File

@ -80,4 +80,18 @@ show status like "Qcache_free_blocks";
Variable_name Value Variable_name Value
Qcache_free_blocks 1 Qcache_free_blocks 1
drop table t1, t2, t3, t11, t21; drop table t1, t2, t3, t11, t21;
CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE =
MyISAM;
LOCK TABLE t1 READ LOCAL;
INSERT INTO t1 VALUES (), (), ();
SELECT * FROM t1;
a
SELECT * FROM t1;
a
1
2
3
SELECT * FROM t1;
a
drop table t1;
set GLOBAL query_cache_size=0; set GLOBAL query_cache_size=0;

View File

@ -37,6 +37,7 @@ Id User Host db Command Time State Info
# root localhost test Sleep # NULL # root localhost test Sleep # NULL
# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2 # root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
# root localhost test Query # NULL show processlist # root localhost test Query # NULL show processlist
# root localhost test Sleep # NULL
unlock tables; unlock tables;
drop procedure bug9486; drop procedure bug9486;
drop table t1, t2; drop table t1, t2;
@ -64,3 +65,27 @@ insert into t1 (select f from v1);
drop function bug11554; drop function bug11554;
drop table t1; drop table t1;
drop view v1; drop view v1;
drop procedure if exists p1;
drop procedure if exists p2;
create table t1 (s1 int)|
create procedure p1() select * from t1|
create procedure p2()
begin
insert into t1 values (1);
call p1();
select * from t1;
end|
use test;
lock table t1 write;
call p2();
use test;
drop procedure p1;
create procedure p1() select * from t1;
unlock tables;
s1
1
s1
1
drop procedure p1;
drop procedure p2;
drop table t1;

View File

@ -2753,7 +2753,28 @@ WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
one two flag one two flag
5 6 N 5 6 N
7 8 N 7 8 N
insert into t2 values (null,null,'N');
SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
one two test
1 2 0
2 3 0
3 4 0
5 6 1
7 8 1
SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
one two test
1 2 NULL
2 3 NULL
3 4 NULL
5 6 1
7 8 1
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
a b
aaa aaa
DROP TABLE t1;
create table t1 (df decimal(5,1)); create table t1 (df decimal(5,1));
insert into t1 values(1.1); insert into t1 values(1.1);
insert into t1 values(2.2); insert into t1 values(2.2);

View File

@ -651,3 +651,16 @@ insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1; drop procedure p1;
drop table t1; drop table t1;
create table t1 (id int, data int, username varchar(16));
insert into t1 (id, data) values (1, 0);
create trigger t1_whoupdated before update on t1 for each row
begin
declare user varchar(32);
declare i int;
select user() into user;
set NEW.username = user;
select count(*) from ((select 1) union (select 2)) as d1 into i;
end|
update t1 set data = 1;
update t1 set data = 2;
drop table t1;

View File

@ -34,7 +34,7 @@ select 0 + b'1111111111111111';
select 0 + b'1000000000000001'; select 0 + b'1000000000000001';
0 + b'1000000000000001' 0 + b'1000000000000001'
32769 32769
drop table if exists t1; drop table if exists t1,t2;
create table t1 (a bit(65)); create table t1 (a bit(65));
ERROR 42000: Display width out of range for column 'a' (max = 64) ERROR 42000: Display width out of range for column 'a' (max = 64)
create table t1 (a bit(0)); create table t1 (a bit(0));

View File

@ -26,6 +26,8 @@ Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
delete from t1; delete from t1;
insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000"); insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000");
insert into t1 values ("2003-003-03");
insert into t1 values ("20030102T131415"),("2001-01-01T01:01:01"), ("2001-1-1T1:01:01");
select * from t1; select * from t1;
t t
2000-01-01 00:00:00 2000-01-01 00:00:00
@ -43,6 +45,17 @@ t
9999-12-31 23:59:59 9999-12-31 23:59:59
2003-01-00 00:00:00 2003-01-00 00:00:00
2003-00-00 00:00:00 2003-00-00 00:00:00
2003-03-03 00:00:00
2003-01-02 13:14:15
2001-01-01 01:01:01
2001-01-01 01:01:01
truncate table t1;
insert into t1 values("2003-0303 12:13:14");
Warnings:
Warning 1264 Out of range value adjusted for column 't' at row 1
select * from t1;
t
0000-00-00 00:00:00
drop table t1; drop table t1;
CREATE TABLE t1 (a timestamp, b date, c time, d datetime); CREATE TABLE t1 (a timestamp, b date, c time, d datetime);
insert into t1 (b,c,d) values(now(),curtime(),now()); insert into t1 (b,c,d) values(now(),curtime(),now());
@ -153,13 +166,3 @@ dt
0000-00-00 00:00:00 0000-00-00 00:00:00
0000-00-00 00:00:00 0000-00-00 00:00:00
drop table t1; drop table t1;
create table t1 (dt datetime);
insert into t1 values ("20010101T010101");
insert into t1 values ("2001-01-01T01:01:01");
insert into t1 values ("2001-1-1T1:01:01");
select * from t1;
dt
2001-01-01 01:01:01
2001-01-01 01:01:01
2001-01-01 01:01:01
drop table t1;

View File

@ -1880,6 +1880,8 @@ test.v5 check error View 'test.v5' references invalid table(s) or column(s) or f
test.v6 check status OK test.v6 check status OK
drop view v1, v2, v3, v4, v5, v6; drop view v1, v2, v3, v4, v5, v6;
drop table t2; drop table t2;
drop function if exists f1;
drop function if exists f2;
CREATE TABLE t1 (col1 time); CREATE TABLE t1 (col1 time);
CREATE TABLE t2 (col1 time); CREATE TABLE t2 (col1 time);
CREATE TABLE t3 (col1 time); CREATE TABLE t3 (col1 time);

View File

@ -14,6 +14,9 @@ select +9999999999999999999,-9999999999999999999;
select cast(9223372036854775808 as unsigned)+1; select cast(9223372036854775808 as unsigned)+1;
select 9223372036854775808+1; select 9223372036854775808+1;
select -(0-3),round(-(0-3)), round(9999999999999999999); select -(0-3),round(-(0-3)), round(9999999999999999999);
select 1,11,101,1001,10001,100001,1000001,10000001,100000001,1000000001,10000000001,100000000001,1000000000001,10000000000001,100000000000001,1000000000000001,10000000000000001,100000000000000001,1000000000000000001,10000000000000000001;
select -1,-11,-101,-1001,-10001,-100001,-1000001,-10000001,-100000001,-1000000001,-10000000001,-100000000001,-1000000000001,-10000000000001,-100000000000001,-1000000000000001,-10000000000000001,-100000000000000001,-1000000000000000001,-10000000000000000001;
select conv(1,10,16),conv((1<<2)-1,10,16),conv((1<<10)-2,10,16),conv((1<<16)-3,10,16),conv((1<<25)-4,10,16),conv((1<<31)-5,10,16),conv((1<<36)-6,10,16),conv((1<<47)-7,10,16),conv((1<<48)-8,10,16),conv((1<<55)-9,10,16),conv((1<<56)-10,10,16),conv((1<<63)-11,10,16);
# #
# In 3.23 we have to disable the test of column to bigint as # In 3.23 we have to disable the test of column to bigint as

View File

@ -23,6 +23,45 @@ select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',s
select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1); select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1); select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1);
select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1); select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1);
select substring_index('aaaaaaaaa1','a',1);
select substring_index('aaaaaaaaa1','aa',1);
select substring_index('aaaaaaaaa1','aa',2);
select substring_index('aaaaaaaaa1','aa',3);
select substring_index('aaaaaaaaa1','aa',4);
select substring_index('aaaaaaaaa1','aa',5);
select substring_index('aaaaaaaaa1','aaa',1);
select substring_index('aaaaaaaaa1','aaa',2);
select substring_index('aaaaaaaaa1','aaa',3);
select substring_index('aaaaaaaaa1','aaa',4);
select substring_index('aaaaaaaaa1','aaaa',1);
select substring_index('aaaaaaaaa1','aaaa',2);
select substring_index('aaaaaaaaa1','1',1);
select substring_index('aaaaaaaaa1','a',-1);
select substring_index('aaaaaaaaa1','aa',-1);
select substring_index('aaaaaaaaa1','aa',-2);
select substring_index('aaaaaaaaa1','aa',-3);
select substring_index('aaaaaaaaa1','aa',-4);
select substring_index('aaaaaaaaa1','aa',-5);
select substring_index('aaaaaaaaa1','aaa',-1);
select substring_index('aaaaaaaaa1','aaa',-2);
select substring_index('aaaaaaaaa1','aaa',-3);
select substring_index('aaaaaaaaa1','aaa',-4);
select substring_index('the king of thethe hill','the',-2);
select substring_index('the king of the the hill','the',-2);
select substring_index('the king of the the hill','the',-2);
select substring_index('the king of the the hill',' the ',-1);
select substring_index('the king of the the hill',' the ',-2);
select substring_index('the king of the the hill',' ',-1);
select substring_index('the king of the the hill',' ',-2);
select substring_index('the king of the the hill',' ',-3);
select substring_index('the king of the the hill',' ',-4);
select substring_index('the king of the the hill',' ',-5);
select substring_index('the king of the.the hill','the',-2);
select substring_index('the king of thethethe.the hill','the',-3);
select substring_index('the king of thethethe.the hill','the',-1);
select substring_index('the king of the the hill','the',1);
select substring_index('the king of the the hill','the',2);
select substring_index('the king of the the hill','the',3);
select concat(':',ltrim(' left '),':',rtrim(' right '),':'); select concat(':',ltrim(' left '),':',rtrim(' right '),':');
select concat(':',trim(leading from ' left '),':',trim(trailing from ' right '),':'); select concat(':',trim(leading from ' left '),':',trim(trailing from ' right '),':');

View File

@ -101,4 +101,18 @@ insert into t1 select a from t1 on duplicate key update a=a+1 ;
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ; insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
drop table t1; drop table t1;
#
# Bug#10109 - INSERT .. SELECT ... ON DUPLICATE KEY UPDATE fails
# Bogus "Duplicate columns" error message
#
CREATE TABLE t1 (
a BIGINT(20) NOT NULL DEFAULT 0,
PRIMARY KEY (a)
) ENGINE=MyISAM;
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests

View File

@ -78,4 +78,23 @@ show status like "Qcache_total_blocks";
show status like "Qcache_free_blocks"; show status like "Qcache_free_blocks";
drop table t1, t2, t3, t11, t21; drop table t1, t2, t3, t11, t21;
#
# do not use QC if tables locked (BUG#12385)
#
connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock);
connection root;
CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE =
MyISAM;
LOCK TABLE t1 READ LOCAL;
connect (root2,localhost,root,,test,$MASTER_MYPORT,master.sock);
connection root2;
INSERT INTO t1 VALUES (), (), ();
connection root;
SELECT * FROM t1;
connection root2;
SELECT * FROM t1;
connection root;
SELECT * FROM t1;
drop table t1;
set GLOBAL query_cache_size=0; set GLOBAL query_cache_size=0;

View File

@ -5,6 +5,7 @@
connect (con1root,localhost,root,,); connect (con1root,localhost,root,,);
connect (con2root,localhost,root,,); connect (con2root,localhost,root,,);
connect (con3root,localhost,root,,);
connection con1root; connection con1root;
use test; use test;
@ -130,6 +131,48 @@ drop function bug11554;
drop table t1; drop table t1;
drop view v1; drop view v1;
# BUG#12228
--disable_warnings
drop procedure if exists p1;
drop procedure if exists p2;
--enable_warnings
connection con1root;
delimiter |;
create table t1 (s1 int)|
create procedure p1() select * from t1|
create procedure p2()
begin
insert into t1 values (1);
call p1();
select * from t1;
end|
delimiter ;|
connection con2root;
use test;
lock table t1 write;
connection con1root;
send call p2();
connection con3root;
use test;
drop procedure p1;
create procedure p1() select * from t1;
connection con2root;
unlock tables;
connection con1root;
# Crash will be here if we hit BUG#12228
reap;
drop procedure p1;
drop procedure p2;
drop table t1;
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #

View File

@ -1773,8 +1773,23 @@ SELECT * FROM t1
SELECT * FROM t1 SELECT * FROM t1
WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N'); WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
insert into t2 values (null,null,'N');
SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #12392: where cond with IN predicate for rows and NULL values in table
#
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
# #

View File

@ -662,3 +662,26 @@ create procedure p1() flush privileges;
insert into t1 values (0); insert into t1 values (0);
drop procedure p1; drop procedure p1;
drop table t1; drop table t1;
# Test for bug #11973 "SELECT .. INTO var_name; in trigger cause
# crash on update"
create table t1 (id int, data int, username varchar(16));
insert into t1 (id, data) values (1, 0);
delimiter |;
create trigger t1_whoupdated before update on t1 for each row
begin
declare user varchar(32);
declare i int;
select user() into user;
set NEW.username = user;
select count(*) from ((select 1) union (select 2)) as d1 into i;
end|
delimiter ;|
update t1 set data = 1;
connect (addconroot, localhost, root,,);
connection addconroot;
update t1 set data = 2;
connection default;
drop table t1;

View File

@ -16,7 +16,7 @@ select 0 + b'1111111111111111';
select 0 + b'1000000000000001'; select 0 + b'1000000000000001';
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1,t2;
--enable_warnings --enable_warnings
--error 1439 --error 1439

View File

@ -14,6 +14,17 @@ optimize table t1;
check table t1; check table t1;
delete from t1; delete from t1;
insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000"); insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000");
# Strange dates
insert into t1 values ("2003-003-03");
# Bug #7308: ISO-8601 date format not handled correctly
insert into t1 values ("20030102T131415"),("2001-01-01T01:01:01"), ("2001-1-1T1:01:01");
select * from t1;
# Test some wrong dates
truncate table t1;
insert into t1 values("2003-0303 12:13:14");
select * from t1; select * from t1;
drop table t1; drop table t1;
@ -102,14 +113,4 @@ insert into t1 values ("00-00-00"), ("00-00-00 00:00:00");
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Bug #7308: ISO-8601 date format not handled correctly
#
create table t1 (dt datetime);
insert into t1 values ("20010101T010101");
insert into t1 values ("2001-01-01T01:01:01");
insert into t1 values ("2001-1-1T1:01:01");
select * from t1;
drop table t1;
# End of 4.1 tests # End of 4.1 tests

View File

@ -1711,6 +1711,10 @@ CHECK TABLE v1, v2, v3, v4, v5, v6;
drop view v1, v2, v3, v4, v5, v6; drop view v1, v2, v3, v4, v5, v6;
drop table t2; drop table t2;
--disable_warnings
drop function if exists f1;
drop function if exists f2;
--enable_warnings
CREATE TABLE t1 (col1 time); CREATE TABLE t1 (col1 time);
CREATE TABLE t2 (col1 time); CREATE TABLE t2 (col1 time);
CREATE TABLE t3 (col1 time); CREATE TABLE t3 (col1 time);

View File

@ -679,6 +679,32 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
} }
#ifdef BACKSLASH_MBTAIL
static CHARSET_INFO *fs_cset_cache= NULL;
CHARSET_INFO *fs_character_set()
{
if (!fs_cset_cache)
{
char buf[10]= "cp";
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
buf+2, sizeof(buf)-3);
/*
We cannot call get_charset_by_name here
because fs_character_set() is executed before
LOCK_THD_charset mutex initialization, which
is used inside get_charset_by_name.
As we're now interested in cp932 only,
let's just detect it using strcmp().
*/
fs_cset_cache= !strcmp(buf, "cp932") ?
&my_charset_cp932_japanese_ci : &my_charset_bin;
}
return fs_cset_cache;
}
#endif
/* /*
Escape apostrophes by doubling them up Escape apostrophes by doubling them up

View File

@ -22,6 +22,9 @@
uint dirname_length(const char *name) uint dirname_length(const char *name)
{ {
register my_string pos,gpos; register my_string pos,gpos;
#ifdef BASKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
#ifdef FN_DEVCHAR #ifdef FN_DEVCHAR
if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0) if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
#endif #endif
@ -29,12 +32,22 @@ uint dirname_length(const char *name)
gpos= pos++; gpos= pos++;
for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */ for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */
{
#ifdef BASKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3)))
{
pos+= l - 1;
continue;
}
#endif
if (*pos == FN_LIBCHAR || *pos == '/' if (*pos == FN_LIBCHAR || *pos == '/'
#ifdef FN_C_AFTER_DIR #ifdef FN_C_AFTER_DIR
|| *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2 || *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
#endif #endif
) )
gpos=pos; gpos=pos;
}
return ((uint) (uint) (gpos+1-(char*) name)); return ((uint) (uint) (gpos+1-(char*) name));
} }
@ -85,6 +98,9 @@ uint dirname_part(my_string to, const char *name)
char *convert_dirname(char *to, const char *from, const char *from_end) char *convert_dirname(char *to, const char *from, const char *from_end)
{ {
char *to_org=to; char *to_org=to;
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
/* We use -2 here, becasue we need place for the last FN_LIBCHAR */ /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
if (!from_end || (from_end - from) > FN_REFLEN-2) if (!from_end || (from_end - from) > FN_REFLEN-2)
@ -103,8 +119,23 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
*to++= FN_C_AFTER_DIR; *to++= FN_C_AFTER_DIR;
#endif #endif
else else
{
#ifdef BACKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
{
memmove(to, from, l);
to+= l;
from+= l - 1;
to_org= to; /* Don't look inside mbchar */
}
else
#endif
{
*to++= *from; *to++= *from;
} }
}
}
*to=0; *to=0;
} }
#else #else

View File

@ -124,6 +124,9 @@ uint cleanup_dirname(register my_string to, const char *from)
reg4 my_string start; reg4 my_string start;
char parent[5], /* for "FN_PARENTDIR" */ char parent[5], /* for "FN_PARENTDIR" */
buff[FN_REFLEN+1],*end_parentdir; buff[FN_REFLEN+1],*end_parentdir;
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
DBUG_ENTER("cleanup_dirname"); DBUG_ENTER("cleanup_dirname");
DBUG_PRINT("enter",("from: '%s'",from)); DBUG_PRINT("enter",("from: '%s'",from));
@ -141,6 +144,15 @@ uint cleanup_dirname(register my_string to, const char *from)
length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent); length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent);
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++) for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
{ {
#ifdef BACKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
{
for (l-- ; l ; *++pos= *from_ptr++, l--);
start= pos + 1; /* Don't look inside multi-byte char */
continue;
}
#endif
if (*pos == '/') if (*pos == '/')
*pos = FN_LIBCHAR; *pos = FN_LIBCHAR;
if (*pos == FN_LIBCHAR) if (*pos == FN_LIBCHAR)

View File

@ -58,7 +58,7 @@ LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
} }
else // repeated message else // repeated message
{ {
if (now < m_last_log_time+m_max_repeat_frequency) if (now < (time_t) (m_last_log_time+m_max_repeat_frequency))
{ {
m_count_repeated_messages++; m_count_repeated_messages++;
m_now= now; m_now= now;

View File

@ -197,7 +197,9 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
If length= 8 or >= 14 then year is of format YYYY. If length= 8 or >= 14 then year is of format YYYY.
(YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS)
*/ */
for (pos=str; pos != end && my_isdigit(&my_charset_latin1,*pos) ; pos++) for (pos=str;
pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T');
pos++)
; ;
digits= (uint) (pos-str); digits= (uint) (pos-str);
@ -263,7 +265,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
const char *start= str; const char *start= str;
ulong tmp_value= (uint) (uchar) (*str++ - '0'); ulong tmp_value= (uint) (uchar) (*str++ - '0');
while (str != end && my_isdigit(&my_charset_latin1,str[0]) && while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
--field_length) (!is_internal_format || --field_length))
{ {
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0'); tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
str++; str++;

View File

@ -48,6 +48,10 @@ have disables the InnoDB inlining in this file. */
pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
prepare_commit_mutex; /* to force correct commit order in prepare_commit_mutex; /* to force correct commit order in
binlog */ binlog */
ulong commit_threads= 0;
pthread_mutex_t commit_threads_m;
pthread_cond_t commit_cond;
pthread_mutex_t commit_cond_m;
bool innodb_inited= 0; bool innodb_inited= 0;
/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/
@ -948,9 +952,7 @@ innobase_query_caching_of_table_permitted(
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
if (trx->has_search_latch) { if (trx->has_search_latch) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("The calling thread is holding the adaptive search, latch though calling innobase_query_caching_of_table_permitted.");
" InnoDB: Error: the calling thread is holding the adaptive search\n"
"InnoDB: latch though calling innobase_query_caching_of_table_permitted\n");
} }
innobase_release_stat_resources(trx); innobase_release_stat_resources(trx);
@ -1266,9 +1268,7 @@ innobase_init(void)
&srv_log_group_home_dirs); &srv_log_group_home_dirs);
if (ret == FALSE || innobase_mirrored_log_groups != 1) { if (ret == FALSE || innobase_mirrored_log_groups != 1) {
fprintf(stderr, sql_print_error("syntax error in innodb_log_group_home_dir, or a wrong number of mirrored log groups");
"InnoDB: syntax error in innodb_log_group_home_dir\n"
"InnoDB: or a wrong number of mirrored log groups\n");
my_free(internal_innobase_data_file_path, my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
@ -1367,6 +1367,9 @@ innobase_init(void)
(hash_get_key) innobase_get_key, 0, 0); (hash_get_key) innobase_get_key, 0, 0);
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1; innodb_inited= 1;
/* If this is a replication slave and we needed to do a crash recovery, /* If this is a replication slave and we needed to do a crash recovery,
@ -1416,6 +1419,9 @@ innobase_end(void)
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
pthread_mutex_destroy(&innobase_share_mutex); pthread_mutex_destroy(&innobase_share_mutex);
pthread_mutex_destroy(&prepare_commit_mutex); pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
pthread_cond_destroy(&commit_cond);
} }
DBUG_RETURN(err); DBUG_RETURN(err);
@ -1542,7 +1548,9 @@ innobase_commit(
reserve the kernel mutex, we have to release the search system latch reserve the kernel mutex, we have to release the search system latch
first to obey the latching order. */ first to obey the latching order. */
innobase_release_stat_resources(trx); if (trx->has_search_latch) {
trx_search_latch_release_if_reserved(trx);
}
/* The flag trx->active_trans is set to 1 in /* The flag trx->active_trans is set to 1 in
@ -1562,11 +1570,8 @@ innobase_commit(
if (trx->active_trans == 0 if (trx->active_trans == 0
&& trx->conc_state != TRX_NOT_STARTED) { && trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr, sql_print_error("trx->active_trans == 0, but trx->conc_state != TRX_NOT_STARTED");
"InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
} }
if (all if (all
|| (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
@ -1575,16 +1580,41 @@ innobase_commit(
/* We need current binlog position for ibbackup to work. /* We need current binlog position for ibbackup to work.
Note, the position is current because of prepare_commit_mutex */ Note, the position is current because of prepare_commit_mutex */
retry:
if (srv_commit_concurrency > 0)
{
pthread_mutex_lock(&commit_cond_m);
commit_threads++;
if (commit_threads > srv_commit_concurrency)
{
commit_threads--;
pthread_cond_wait(&commit_cond, &commit_cond_m);
pthread_mutex_unlock(&commit_cond_m);
goto retry;
}
else
pthread_mutex_unlock(&commit_cond_m);
}
trx->mysql_log_file_name = mysql_bin_log.get_log_fname(); trx->mysql_log_file_name = mysql_bin_log.get_log_fname();
trx->mysql_log_offset = trx->mysql_log_offset =
(ib_longlong)mysql_bin_log.get_log_file()->pos_in_file; (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;
innobase_commit_low(trx); innobase_commit_low(trx);
if (srv_commit_concurrency > 0)
{
pthread_mutex_lock(&commit_cond_m);
commit_threads--;
pthread_cond_signal(&commit_cond);
pthread_mutex_unlock(&commit_cond_m);
}
if (trx->active_trans == 2) { if (trx->active_trans == 2) {
pthread_mutex_unlock(&prepare_commit_mutex); pthread_mutex_unlock(&prepare_commit_mutex);
} }
trx->active_trans = 0; trx->active_trans = 0;
} else { } else {
@ -1606,7 +1636,11 @@ innobase_commit(
/* Tell the InnoDB server that there might be work for utility /* Tell the InnoDB server that there might be work for utility
threads: */ threads: */
if (trx->declared_to_be_inside_innodb) {
/* Release our possible ticket in the FIFO */
srv_conc_force_exit_innodb(trx);
}
srv_active_wake_master_thread(); srv_active_wake_master_thread();
DBUG_RETURN(0); DBUG_RETURN(0);
@ -1813,21 +1847,7 @@ try_again:
if (ret != 0) { if (ret != 0) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("MySQL synchronous replication was not able to send the binlog to the slave within the timeout %lu. We assume that the slave has become inaccessible, and switch off synchronous replication until the communication to the slave works again. MySQL synchronous replication has sent binlog to the slave up to file %s, position %lu. This transaction needs it to be sent up to file %s, position %lu.", thd->variables.sync_replication_timeout, innobase_repl_file_name, (ulong)innobase_repl_pos, trx->repl_wait_binlog_name, (ulong)trx->repl_wait_binlog_pos);
" InnoDB: Error: MySQL synchronous replication\n"
"InnoDB: was not able to send the binlog to the slave within the\n"
"InnoDB: timeout %lu. We assume that the slave has become inaccessible,\n"
"InnoDB: and switch off synchronous replication until the communication.\n"
"InnoDB: to the slave works again.\n",
thd->variables.sync_replication_timeout);
fprintf(stderr,
"InnoDB: MySQL synchronous replication has sent binlog\n"
"InnoDB: to the slave up to file %s, position %lu\n", innobase_repl_file_name,
(ulong)innobase_repl_pos);
fprintf(stderr,
"InnoDB: This transaction needs it to be sent up to\n"
"InnoDB: file %s, position %lu\n", trx->repl_wait_binlog_name,
(ulong)trx->repl_wait_binlog_pos);
innobase_repl_state = 0; innobase_repl_state = 0;
@ -1878,9 +1898,7 @@ innobase_repl_report_sent_binlog(
if (innobase_repl_state == 0) { if (innobase_repl_state == 0) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_warning("Switching MySQL synchronous replication on again at binlog file %s, position %lu", log_file_name, (ulong) end_offset);
" InnoDB: Switching MySQL synchronous replication on again at\n"
"InnoDB: binlog file %s, position %lu\n", log_file_name, (ulong)end_offset);
innobase_repl_state = 1; innobase_repl_state = 1;
} }
@ -1897,14 +1915,7 @@ innobase_repl_report_sent_binlog(
|| (cmp == 0 && end_offset < innobase_repl_pos)) { || (cmp == 0 && end_offset < innobase_repl_pos)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("MySQL synchronous replication has sent binlog to the slave up to file %s, position %lu, but now MySQL reports that it sent the binlog only up to file %s, position %lu", innobase_repl_file_name, (ulong)innobase_repl_pos, log_file_name, (ulong) end_offset);
" InnoDB: Error: MySQL synchronous replication has sent binlog\n"
"InnoDB: to the slave up to file %s, position %lu\n", innobase_repl_file_name,
(ulong)innobase_repl_pos);
fprintf(stderr,
"InnoDB: but now MySQL reports that it sent the binlog only up to\n"
"InnoDB: file %s, position %lu\n", log_file_name, (ulong)end_offset);
} }
} }
@ -2149,9 +2160,7 @@ innobase_close_connection(
if (trx->active_trans == 0 if (trx->active_trans == 0
&& trx->conc_state != TRX_NOT_STARTED) { && trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr, sql_print_error("trx->active_trans == 0, but trx->conc_state != TRX_NOT_STARTED");
"InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
} }
@ -2363,9 +2372,7 @@ ha_innobase::open(
if (!row_table_got_default_clust_index(ib_table)) { if (!row_table_got_default_clust_index(ib_table)) {
if (primary_key >= MAX_KEY) { if (primary_key >= MAX_KEY) {
fprintf(stderr, sql_print_error("Table %s has a primary key in InnoDB data dictionary, but not in MySQL!", name);
"InnoDB: Error: table %s has a primary key in InnoDB\n"
"InnoDB: data dictionary, but not in MySQL!\n", name);
} }
((row_prebuilt_t*)innobase_prebuilt) ((row_prebuilt_t*)innobase_prebuilt)
@ -2379,16 +2386,7 @@ ha_innobase::open(
ref_length = table->key_info[primary_key].key_length; ref_length = table->key_info[primary_key].key_length;
} else { } else {
if (primary_key != MAX_KEY) { if (primary_key != MAX_KEY) {
fprintf(stderr, sql_print_error("Table %s has no primary key in InnoDB data dictionary, but has one in MySQL! If you created the table with a MySQL version < 3.23.54 and did not define a primary key, but defined a unique key with all non-NULL columns, then MySQL internally treats that key as the primary key. You can fix this error by dump + DROP + CREATE + reimport of the table.", name);
"InnoDB: Error: table %s has no primary key in InnoDB\n"
"InnoDB: data dictionary, but has one in MySQL!\n"
"InnoDB: If you created the table with a MySQL\n"
"InnoDB: version < 3.23.54 and did not define a primary\n"
"InnoDB: key, but defined a unique key with all non-NULL\n"
"InnoDB: columns, then MySQL internally treats that key\n"
"InnoDB: as the primary key. You can fix this error by\n"
"InnoDB: dump + DROP + CREATE + reimport of the table.\n",
name);
} }
((row_prebuilt_t*)innobase_prebuilt) ((row_prebuilt_t*)innobase_prebuilt)
@ -2405,10 +2403,7 @@ ha_innobase::open(
and it will never be updated anyway. */ and it will never be updated anyway. */
if (key_used_on_scan != MAX_KEY) { if (key_used_on_scan != MAX_KEY) {
fprintf(stderr, sql_print_warning("Table %s key_used_on_scan is %lu even though there is no primary key inside InnoDB.", name, (ulong) key_used_on_scan);
"InnoDB: Warning: table %s key_used_on_scan is %lu even though there is no\n"
"InnoDB: primary key inside InnoDB.\n",
name, (ulong)key_used_on_scan);
} }
} }
@ -2563,9 +2558,7 @@ innobase_mysql_cmp(
charset = get_charset(charset_number, MYF(MY_WME)); charset = get_charset(charset_number, MYF(MY_WME));
if (charset == NULL) { if (charset == NULL) {
fprintf(stderr, sql_print_error("InnoDB needs charset %lu for doing a comparison, but MySQL cannot find that charset.", (ulong) charset_number);
"InnoDB: fatal error: InnoDB needs charset %lu for doing a comparison,\n"
"InnoDB: but MySQL cannot find that charset.\n", (ulong)charset_number);
ut_a(0); ut_a(0);
} }
} }
@ -3131,11 +3124,8 @@ ha_innobase::write_row(
if (prebuilt->trx != if (prebuilt->trx !=
(trx_t*) current_thd->ha_data[innobase_hton.slot]) { (trx_t*) current_thd->ha_data[innobase_hton.slot]) {
fprintf(stderr, sql_print_error("The transaction object for the table handle is at %p, but for the current thread it is at %p", prebuilt->trx, (trx_t*) current_thd->ha_data[innobase_hton.slot]);
"InnoDB: Error: the transaction object for the table handle is at\n"
"InnoDB: %p, but for the current thread it is at %p\n",
prebuilt->trx,
(trx_t*) current_thd->ha_data[innobase_hton.slot]);
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
fputs("\n" fputs("\n"
@ -3622,9 +3612,7 @@ ha_innobase::unlock_row(void)
if (last_query_id != user_thd->query_id) { if (last_query_id != user_thd->query_id) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("last_query_id is %lu != user_thd_query_id is %lu", (ulong) last_query_id, (ulong) user_thd->query_id);
" InnoDB: Error: last_query_id is %lu != user_thd_query_id is %lu\n",
(ulong)last_query_id, (ulong)user_thd->query_id);
mem_analyze_corruption((byte *) prebuilt->trx); mem_analyze_corruption((byte *) prebuilt->trx);
ut_error; ut_error;
} }
@ -4284,8 +4272,7 @@ ha_innobase::position(
table. */ table. */
if (len != ref_length) { if (len != ref_length) {
fprintf(stderr, sql_print_error("Stored ref len is %lu, but table ref len is %lu",
"InnoDB: Error: stored ref len is %lu, but table ref len is %lu\n",
(ulong) len, (ulong) ref_length); (ulong) len, (ulong) ref_length);
} }
} }
@ -4491,10 +4478,7 @@ create_index(
|| col_type == DATA_FLOAT || col_type == DATA_FLOAT
|| col_type == DATA_DOUBLE || col_type == DATA_DOUBLE
|| col_type == DATA_DECIMAL) { || col_type == DATA_DECIMAL) {
fprintf(stderr, sql_print_error("MySQL is trying to create a column prefix index field, on an inappropriate data type. Table name %s, column name %s.", table_name, key_part->field->field_name);
"InnoDB: error: MySQL is trying to create a column prefix index field\n"
"InnoDB: on an inappropriate data type. Table name %s, column name %s.\n",
table_name, key_part->field->field_name);
prefix_len = 0; prefix_len = 0;
} }
@ -5378,12 +5362,7 @@ ha_innobase::info(
for (i = 0; i < table->s->keys; i++) { for (i = 0; i < table->s->keys; i++) {
if (index == NULL) { if (index == NULL) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("Table %s contains less indexes inside InnoDB than are defined in the MySQL .frm file. Have you mixed up .frm files from different installations? See section 15.1 at http://www.innodb.com/ibman.html", ib_table->name);
" InnoDB: Error: table %s contains less indexes inside InnoDB\n"
"InnoDB: than are defined in the MySQL .frm file. Have you mixed up\n"
"InnoDB: .frm files from different installations? See section\n"
"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n",
ib_table->name);
break; break;
} }
@ -5391,15 +5370,7 @@ ha_innobase::info(
if (j + 1 > index->n_uniq) { if (j + 1 > index->n_uniq) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking statistics for %lu columns. Have you mixed up .frm files from different installations? See section 15.1 at http://www.innodb.com/ibman.html", index->name, ib_table->name, (unsigned long) index->n_uniq, j + 1);
" InnoDB: Error: index %s of %s has %lu columns unique inside InnoDB\n"
"InnoDB: but MySQL is asking statistics for %lu columns. Have you mixed up\n"
"InnoDB: .frm files from different installations? See section\n"
"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n",
index->name,
ib_table->name,
(unsigned long) index->n_uniq,
j + 1);
break; break;
} }
@ -5947,9 +5918,7 @@ ha_innobase::start_stmt(
if (prebuilt->stored_select_lock_type != LOCK_S if (prebuilt->stored_select_lock_type != LOCK_S
&& prebuilt->stored_select_lock_type != LOCK_X) { && prebuilt->stored_select_lock_type != LOCK_X) {
fprintf(stderr, sql_print_error("stored_select_lock_type is %lu inside ::start_stmt()!", prebuilt->stored_select_lock_type);
"InnoDB: Error: stored_select_lock_type is %lu inside ::start_stmt()!\n",
prebuilt->stored_select_lock_type);
/* Set the value to LOCK_X: this is just fault /* Set the value to LOCK_X: this is just fault
tolerance, we do not know what the correct value tolerance, we do not know what the correct value
@ -6725,9 +6694,7 @@ ha_innobase::innobase_read_and_init_auto_inc(
error = 0; error = 0;
} else { } else {
/* This should not happen in a consistent read */ /* This should not happen in a consistent read */
fprintf(stderr, sql_print_error("Consistent read of auto-inc column returned %lu", (ulong) error);
"InnoDB: Error: consistent read of auto-inc column returned %lu\n",
(ulong)error);
auto_inc = -1; auto_inc = -1;
goto func_exit; goto func_exit;
@ -6784,8 +6751,7 @@ ha_innobase::get_auto_increment()
initialized. */ initialized. */
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, sql_print_error("Error %lu in ::get_auto_increment()",
" InnoDB: Error: error %lu in ::get_auto_increment()\n",
(ulong) error); (ulong) error);
return(~(ulonglong) 0); return(~(ulonglong) 0);
} }
@ -7053,9 +7019,7 @@ innobase_xa_prepare(
if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) { if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr, sql_print_error("trx->active_trans == 0, but trx->conc_state != TRX_NOT_STARTED");
"InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
} }
if (all if (all

View File

@ -232,6 +232,7 @@ extern ulong srv_n_spin_wait_rounds;
extern ulong srv_n_free_tickets_to_enter; extern ulong srv_n_free_tickets_to_enter;
extern ulong srv_thread_sleep_delay; extern ulong srv_thread_sleep_delay;
extern ulong srv_thread_concurrency; extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
} }
extern TYPELIB innobase_lock_typelib; extern TYPELIB innobase_lock_typelib;

View File

@ -1903,6 +1903,8 @@ in_row::~in_row()
byte *in_row::get_value(Item *item) byte *in_row::get_value(Item *item)
{ {
tmp.store_value(item); tmp.store_value(item);
if (item->is_null())
return 0;
return (byte *)&tmp; return (byte *)&tmp;
} }

View File

@ -1177,11 +1177,23 @@ String *Item_func_substr_index::val_str(String *str)
} }
} }
else else
{ // Start counting at end
for (offset=res->length() ; ; offset-=delimeter_length-1)
{ {
/*
Negative index, start counting at the end
*/
for (offset=res->length(); offset ;)
{
/*
this call will result in finding the position pointing to one
address space less than where the found substring is located
in res
*/
if ((int) (offset=res->strrstr(*delimeter,offset)) < 0) if ((int) (offset=res->strrstr(*delimeter,offset)) < 0)
return res; // Didn't find, return org string return res; // Didn't find, return org string
/*
At this point, we've searched for the substring
the number of times as supplied by the index value
*/
if (!++count) if (!++count)
{ {
offset+=delimeter_length; offset+=delimeter_length;

View File

@ -1276,6 +1276,14 @@ void Item_allany_subselect::print(String *str)
} }
void subselect_engine::set_thd(THD *thd_arg)
{
thd= thd_arg;
if (result)
result->set_thd(thd_arg);
}
subselect_single_select_engine:: subselect_single_select_engine::
subselect_single_select_engine(st_select_lex *select, subselect_single_select_engine(st_select_lex *select,
select_subselect *result, select_subselect *result,

View File

@ -299,8 +299,11 @@ public:
virtual ~subselect_engine() {}; // to satisfy compiler virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0; virtual void cleanup()= 0;
// set_thd should be called before prepare() /*
void set_thd(THD *thd_arg) { thd= thd_arg; } Also sets "thd" for subselect_engine::result.
Should be called before prepare().
*/
void set_thd(THD *thd_arg);
THD * get_thd() { return thd; } THD * get_thd() { return thd; }
virtual int prepare()= 0; virtual int prepare()= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0; virtual void fix_length_and_dec(Item_cache** row)= 0;

View File

@ -5314,6 +5314,10 @@ log and this option does nothing anymore.",
"Helps in performance tuning in heavily concurrent environments.", "Helps in performance tuning in heavily concurrent environments.",
(gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
0, GET_LONG, REQUIRED_ARG, 20, 1, 1000, 0, 1, 0}, 0, GET_LONG, REQUIRED_ARG, 20, 1, 1000, 0, 1, 0},
{"innodb_commit_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
"Helps in performance tuning in heavily concurrent environments.",
(gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency,
0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
{"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY, {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
"Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0" "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
" disable a sleep", " disable a sleep",

View File

@ -411,6 +411,8 @@ sys_var_long_ptr sys_innodb_thread_sleep_delay("innodb_thread_sleep_delay",
&srv_thread_sleep_delay); &srv_thread_sleep_delay);
sys_var_long_ptr sys_innodb_thread_concurrency("innodb_thread_concurrency", sys_var_long_ptr sys_innodb_thread_concurrency("innodb_thread_concurrency",
&srv_thread_concurrency); &srv_thread_concurrency);
sys_var_long_ptr sys_innodb_commit_concurrency("innodb_commit_concurrency",
&srv_commit_concurrency);
#endif #endif
/* Condition pushdown to storage engine */ /* Condition pushdown to storage engine */
@ -708,6 +710,7 @@ sys_var *sys_variables[]=
&sys_innodb_concurrency_tickets, &sys_innodb_concurrency_tickets,
&sys_innodb_thread_sleep_delay, &sys_innodb_thread_sleep_delay,
&sys_innodb_thread_concurrency, &sys_innodb_thread_concurrency,
&sys_innodb_commit_concurrency,
#endif #endif
&sys_trust_routine_creators, &sys_trust_routine_creators,
&sys_engine_condition_pushdown, &sys_engine_condition_pushdown,
@ -828,6 +831,7 @@ struct show_var_st init_vars[]= {
{sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
{sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS}, {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS},
{sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS}, {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
{sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS},
{sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS}, {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
#endif #endif
{sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS}, {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},

View File

@ -2396,8 +2396,8 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
&my_charset_bin); &my_charset_bin);
protocol->store((ulonglong) mi->rli.group_relay_log_pos); protocol->store((ulonglong) mi->rli.group_relay_log_pos);
protocol->store(mi->rli.group_master_log_name, &my_charset_bin); protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
? "Yes":"No", &my_charset_bin); "Yes" : "No", &my_charset_bin);
protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin); protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
protocol->store(&replicate_do_db); protocol->store(&replicate_do_db);
protocol->store(&replicate_ignore_db); protocol->store(&replicate_ignore_db);

View File

@ -989,13 +989,11 @@ int
sp_drop_procedure(THD *thd, sp_name *name) sp_drop_procedure(THD *thd, sp_name *name)
{ {
int ret; int ret;
bool found;
DBUG_ENTER("sp_drop_procedure"); DBUG_ENTER("sp_drop_procedure");
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_proc_cache, name);
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name); ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name);
if (!found && !ret) if (!ret)
sp_cache_invalidate(); sp_cache_invalidate();
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
@ -1005,13 +1003,11 @@ int
sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
{ {
int ret; int ret;
bool found;
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_proc_cache, name);
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics); ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics);
if (!found && !ret) if (!ret)
sp_cache_invalidate(); sp_cache_invalidate();
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
@ -1102,13 +1098,11 @@ int
sp_drop_function(THD *thd, sp_name *name) sp_drop_function(THD *thd, sp_name *name)
{ {
int ret; int ret;
bool found;
DBUG_ENTER("sp_drop_function"); DBUG_ENTER("sp_drop_function");
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_func_cache, name);
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name); ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name);
if (!found && !ret) if (!ret)
sp_cache_invalidate(); sp_cache_invalidate();
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
@ -1118,13 +1112,11 @@ int
sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics) sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics)
{ {
int ret; int ret;
bool found;
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_func_cache, name);
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics); ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics);
if (!found && !ret) if (!ret)
sp_cache_invalidate(); sp_cache_invalidate();
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }

View File

@ -24,17 +24,78 @@
static pthread_mutex_t Cversion_lock; static pthread_mutex_t Cversion_lock;
static ulong Cversion = 0; static ulong Cversion = 0;
void
sp_cache_init() /*
Cache of stored routines.
*/
class sp_cache
{
public:
ulong version;
sp_cache();
~sp_cache();
inline void insert(sp_head *sp)
{
/* TODO: why don't we check return value? */
my_hash_insert(&m_hashtable, (const byte *)sp);
}
inline sp_head *lookup(char *name, uint namelen)
{
return (sp_head *)hash_search(&m_hashtable, (const byte *)name, namelen);
}
#ifdef NOT_USED
inline bool remove(char *name, uint namelen)
{
sp_head *sp= lookup(name, namelen);
if (sp)
{
hash_delete(&m_hashtable, (byte *)sp);
return TRUE;
}
return FALSE;
}
#endif
inline void remove_all()
{
cleanup();
init();
}
private:
void init();
void cleanup();
/* All routines in this cache */
HASH m_hashtable;
}; // class sp_cache
/* Initialize the SP caching once at startup */
void sp_cache_init()
{ {
pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST);
} }
void
sp_cache_clear(sp_cache **cp) /*
Clear the cache *cp and set *cp to NULL.
SYNOPSIS
sp_cache_clear()
cp Pointer to cache to clear
NOTE
This function doesn't invalidate other caches.
*/
void sp_cache_clear(sp_cache **cp)
{ {
sp_cache *c= *cp; sp_cache *c= *cp;
if (c) if (c)
{ {
delete c; delete c;
@ -42,86 +103,122 @@ sp_cache_clear(sp_cache **cp)
} }
} }
void
sp_cache_insert(sp_cache **cp, sp_head *sp) /*
Insert a routine into the cache.
SYNOPSIS
sp_cache_insert()
cp The cache to put routine into
sp Routine to insert.
TODO: Perhaps it will be more straightforward if in case we returned an
error from this function when we couldn't allocate sp_cache. (right
now failure to put routine into cache will cause a 'SP not found'
error to be reported at some later time)
*/
void sp_cache_insert(sp_cache **cp, sp_head *sp)
{ {
sp_cache *c= *cp; sp_cache *c= *cp;
if (! c) if (!c && (c= new sp_cache()))
c= new sp_cache(); {
pthread_mutex_lock(&Cversion_lock); // LOCK
c->version= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
}
if (c) if (c)
{ {
ulong v; DBUG_PRINT("info",("sp_cache: inserting: %*s", sp->m_qname.length,
sp->m_qname.str));
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
{
if (*cp)
c->remove_all();
c->version= v;
}
c->insert(sp); c->insert(sp);
if (*cp == NULL) if (*cp == NULL)
*cp= c; *cp= c;
} }
} }
sp_head *
sp_cache_lookup(sp_cache **cp, sp_name *name)
{
ulong v;
sp_cache *c= *cp;
/*
Look up a routine in the cache.
SYNOPSIS
sp_cache_lookup()
cp Cache to look into
name Name of rutine to find
NOTE
An obsolete (but not more obsolete then since last
sp_cache_flush_obsolete call) routine may be returned.
RETURN
The routine or
NULL if the routine not found.
*/
sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name)
{
sp_cache *c= *cp;
if (!c) if (!c)
return NULL; return NULL;
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
{
c->remove_all();
c->version= v;
return NULL;
}
return c->lookup(name->m_qname.str, name->m_qname.length); return c->lookup(name->m_qname.str, name->m_qname.length);
} }
bool
sp_cache_remove(sp_cache **cp, sp_name *name)
{
sp_cache *c= *cp;
bool found= FALSE;
if (c) /*
{ Invalidate all routines in all caches.
ulong v;
pthread_mutex_lock(&Cversion_lock); // LOCK SYNOPSIS
v= Cversion++;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
c->remove_all();
else
found= c->remove(name->m_qname.str, name->m_qname.length);
c->version= v+1;
}
return found;
}
void
sp_cache_invalidate() sp_cache_invalidate()
NOTE
This is called when a VIEW definition is modifed. We can't destroy sp_head
objects here as one may modify VIEW definitions from prelocking-free SPs.
*/
void sp_cache_invalidate()
{ {
DBUG_PRINT("info",("sp_cache: invalidating"));
pthread_mutex_lock(&Cversion_lock); // LOCK pthread_mutex_lock(&Cversion_lock); // LOCK
Cversion++; Cversion++;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK pthread_mutex_unlock(&Cversion_lock); // UNLOCK
} }
/*
Remove out-of-date SPs from the cache.
SYNOPSIS
sp_cache_flush_obsolete()
cp Cache to flush
NOTE
This invalidates pointers to sp_head objects this thread uses.
In practice that means 'dont call this function when inside SP'.
*/
void sp_cache_flush_obsolete(sp_cache **cp)
{
sp_cache *c= *cp;
if (c)
{
ulong v;
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
{
DBUG_PRINT("info",("sp_cache: deleting all functions"));
/* We need to delete all elements. */
c->remove_all();
c->version= v;
}
}
}
/*************************************************************************
Internal functions
*************************************************************************/
static byte * static byte *
hash_get_key_for_sp_head(const byte *ptr, uint *plen, hash_get_key_for_sp_head(const byte *ptr, uint *plen,
my_bool first) my_bool first)
@ -136,7 +233,6 @@ static void
hash_free_sp_head(void *p) hash_free_sp_head(void *p)
{ {
sp_head *sp= (sp_head *)p; sp_head *sp= (sp_head *)p;
delete sp; delete sp;
} }

View File

@ -32,87 +32,32 @@
class sp_head; class sp_head;
class sp_cache; class sp_cache;
/* Initialize the SP caching once at startup */ /*
Cache usage scenarios:
1. Application-wide init:
sp_cache_init();
2. SP execution in thread:
2.1 While holding sp_head* pointers:
// look up a routine in the cache (no checks if it is up to date or not)
sp_cache_lookup();
sp_cache_insert();
sp_cache_invalidate();
2.2 When not holding any sp_head* pointers:
sp_cache_flush_obsolete();
3. Before thread exit:
sp_cache_clear();
*/
void sp_cache_init(); void sp_cache_init();
/* Clear the cache *cp and set *cp to NULL */
void sp_cache_clear(sp_cache **cp); void sp_cache_clear(sp_cache **cp);
/* Insert an SP into cache. If 'cp' points to NULL, it's set to a new cache */
void sp_cache_insert(sp_cache **cp, sp_head *sp); void sp_cache_insert(sp_cache **cp, sp_head *sp);
/* Lookup an SP in cache */
sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name); sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name);
/*
Remove an SP from cache, and also bump the Cversion number so all other
caches are invalidated.
Returns true if something was removed.
*/
bool sp_cache_remove(sp_cache **cp, sp_name *name);
/* Invalidate all existing SP caches by bumping Cversion number. */
void sp_cache_invalidate(); void sp_cache_invalidate();
void sp_cache_flush_obsolete(sp_cache **cp);
/*
*
* The cache class. Don't use this directly, use the C API above
*
*/
class sp_cache
{
public:
ulong version;
sp_cache();
~sp_cache();
void
init();
void
cleanup();
inline void
insert(sp_head *sp)
{
my_hash_insert(&m_hashtable, (const byte *)sp);
}
inline sp_head *
lookup(char *name, uint namelen)
{
return (sp_head *)hash_search(&m_hashtable, (const byte *)name, namelen);
}
inline bool
remove(char *name, uint namelen)
{
sp_head *sp= lookup(name, namelen);
if (sp)
{
hash_delete(&m_hashtable, (byte *)sp);
return TRUE;
}
return FALSE;
}
inline void
remove_all()
{
cleanup();
init();
}
private:
HASH m_hashtable;
}; // class sp_cache
#endif /* _SP_CACHE_H_ */ #endif /* _SP_CACHE_H_ */

View File

@ -762,7 +762,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
TABLE_COUNTER_TYPE local_tables; TABLE_COUNTER_TYPE local_tables;
ulong tot_length; ulong tot_length;
DBUG_ENTER("Query_cache::store_query"); DBUG_ENTER("Query_cache::store_query");
if (query_cache_size == 0) if (query_cache_size == 0 || thd->locked_tables)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
uint8 tables_type= 0; uint8 tables_type= 0;
@ -936,8 +936,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_query_flags flags; Query_cache_query_flags flags;
DBUG_ENTER("Query_cache::send_result_to_client"); DBUG_ENTER("Query_cache::send_result_to_client");
if (query_cache_size == 0 || thd->variables.query_cache_type == 0) if (query_cache_size == 0 || thd->locked_tables ||
thd->variables.query_cache_type == 0)
goto err; goto err;
/* Check that we haven't forgot to reset the query cache variables */ /* Check that we haven't forgot to reset the query cache variables */

View File

@ -1565,6 +1565,7 @@ public:
statement/stored procedure. statement/stored procedure.
*/ */
virtual void cleanup(); virtual void cleanup();
void set_thd(THD *thd_arg) { thd= thd_arg; }
}; };
@ -1920,14 +1921,13 @@ class multi_delete :public select_result_interceptor
{ {
TABLE_LIST *delete_tables, *table_being_deleted; TABLE_LIST *delete_tables, *table_being_deleted;
Unique **tempfiles; Unique **tempfiles;
THD *thd;
ha_rows deleted, found; ha_rows deleted, found;
uint num_of_tables; uint num_of_tables;
int error; int error;
bool do_delete, transactional_tables, normal_tables, delete_while_scanning; bool do_delete, transactional_tables, normal_tables, delete_while_scanning;
public: public:
multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); multi_delete(TABLE_LIST *dt, uint num_of_tables);
~multi_delete(); ~multi_delete();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
@ -1943,7 +1943,6 @@ class multi_update :public select_result_interceptor
TABLE_LIST *all_tables; /* query/update command tables */ TABLE_LIST *all_tables; /* query/update command tables */
TABLE_LIST *leaves; /* list of leves of join table tree */ TABLE_LIST *leaves; /* list of leves of join table tree */
TABLE_LIST *update_tables, *table_being_updated; TABLE_LIST *update_tables, *table_being_updated;
THD *thd;
TABLE **tmp_tables, *main_table, *table_to_update; TABLE **tmp_tables, *main_table, *table_to_update;
TMP_TABLE_PARAM *tmp_table_param; TMP_TABLE_PARAM *tmp_table_param;
ha_rows updated, found; ha_rows updated, found;
@ -1955,7 +1954,7 @@ class multi_update :public select_result_interceptor
bool do_update, trans_safe, transactional_tables, ignore; bool do_update, trans_safe, transactional_tables, ignore;
public: public:
multi_update(THD *thd_arg, TABLE_LIST *ut, TABLE_LIST *leaves_list, multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
List<Item> *fields, List<Item> *values, List<Item> *fields, List<Item> *values,
enum_duplicates handle_duplicates, bool ignore); enum_duplicates handle_duplicates, bool ignore);
~multi_update(); ~multi_update();

View File

@ -407,9 +407,8 @@ bool mysql_multi_delete_prepare(THD *thd)
} }
multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
uint num_of_tables_arg) : delete_tables(dt), deleted(0), found(0),
: delete_tables(dt), thd(thd_arg), deleted(0), found(0),
num_of_tables(num_of_tables_arg), error(0), num_of_tables(num_of_tables_arg), error(0),
do_delete(0), transactional_tables(0), normal_tables(0) do_delete(0), transactional_tables(0), normal_tables(0)
{ {

View File

@ -808,11 +808,11 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0; table_list->next_local= 0;
select_lex->context.resolve_in_table_list_only(table_list); select_lex->context.resolve_in_table_list_only(table_list);
if ((values && check_insert_fields(thd, table_list, fields, *values, if (values &&
!insert_into_view)) || !(res= check_insert_fields(thd, table_list, fields, *values,
(values && setup_fields(thd, 0, *values, 0, 0, 0))) !insert_into_view) ||
res= TRUE; setup_fields(thd, 0, *values, 0, 0, 0)) &&
else if (duplic == DUP_UPDATE) duplic == DUP_UPDATE)
{ {
select_lex->no_wrap_view_item= TRUE; select_lex->no_wrap_view_item= TRUE;
res= check_update_fields(thd, table_list, update_fields); res= check_update_fields(thd, table_list, update_fields);
@ -2089,7 +2089,26 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/ */
lex->current_select= &lex->select_lex; lex->current_select= &lex->select_lex;
res= check_insert_fields(thd, table_list, *fields, values, res= check_insert_fields(thd, table_list, *fields, values,
!insert_into_view); !insert_into_view) ||
setup_fields(thd, 0, values, 0, 0, 0);
if (info.handle_duplicates == DUP_UPDATE)
{
TABLE_LIST *save_next_local= table_list->next_local;
table_list->next_local= 0;
lex->select_lex.context.resolve_in_table_list_only(table_list);
lex->select_lex.no_wrap_view_item= TRUE;
res= res || check_update_fields(thd, table_list, *info.update_fields);
lex->select_lex.no_wrap_view_item= FALSE;
/*
When we are not using GROUP BY we can refer to other tables in the
ON DUPLICATE KEY part
*/
if (!lex->select_lex.group_list.elements)
table_list->next_local= save_next_local;
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
table_list->next_local= save_next_local;
}
lex->current_select= lex_current_select_save; lex->current_select= lex_current_select_save;
if (res) if (res)
DBUG_RETURN(1); DBUG_RETURN(1);

View File

@ -458,6 +458,7 @@ public:
inline bool is_prepared() { return prepared; } inline bool is_prepared() { return prepared; }
bool change_result(select_subselect *result, select_subselect *old_result); bool change_result(select_subselect *result, select_subselect *old_result);
void set_limit(st_select_lex *values); void set_limit(st_select_lex *values);
void set_thd(THD *thd_arg) { thd= thd_arg; }
friend void lex_start(THD *thd, uchar *buf, uint length); friend void lex_start(THD *thd, uchar *buf, uint length);
friend int subselect_union_engine::exec(); friend int subselect_union_engine::exec();

View File

@ -3318,7 +3318,7 @@ end_with_restore_list:
if ((res= mysql_multi_delete_prepare(thd))) if ((res= mysql_multi_delete_prepare(thd)))
goto error; goto error;
if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, if (!thd->is_fatal_error && (result= new multi_delete(aux_tables,
lex->table_count))) lex->table_count)))
{ {
res= mysql_select(thd, &select_lex->ref_pointer_array, res= mysql_select(thd, &select_lex->ref_pointer_array,
@ -5311,10 +5311,12 @@ void create_select_for_variable(const char *var_name)
We set the name of Item to @@session.var_name because that then is used We set the name of Item to @@session.var_name because that then is used
as the column name in the output. as the column name in the output.
*/ */
var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string); if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
{
end= strxmov(buff, "@@session.", var_name, NullS); end= strxmov(buff, "@@session.", var_name, NullS);
var->set_name(buff, end-buff, system_charset_info); var->set_name(buff, end-buff, system_charset_info);
add_item_to_list(thd, var); add_item_to_list(thd, var);
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -5340,11 +5342,12 @@ void mysql_init_multi_delete(LEX *lex)
void mysql_parse(THD *thd, char *inBuf, uint length) void mysql_parse(THD *thd, char *inBuf, uint length)
{ {
DBUG_ENTER("mysql_parse"); DBUG_ENTER("mysql_parse");
mysql_init_query(thd, (uchar*) inBuf, length); mysql_init_query(thd, (uchar*) inBuf, length);
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
if (!yyparse((void *)thd) && ! thd->is_fatal_error) if (!yyparse((void *)thd) && ! thd->is_fatal_error)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -6463,12 +6466,14 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count; THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
for (; lock_p < end_p; lock_p++) for (; lock_p < end_p; lock_p++)
{
if ((*lock_p)->type == TL_WRITE) if ((*lock_p)->type == TL_WRITE)
{ {
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
return 1; return 1;
} }
} }
}
/* /*
Writing to the binlog could cause deadlocks, as we don't log Writing to the binlog could cause deadlocks, as we don't log
UNLOCK TABLES UNLOCK TABLES

View File

@ -73,6 +73,7 @@ Long data handling:
#include <m_ctype.h> // for isspace() #include <m_ctype.h> // for isspace()
#include "sp_head.h" #include "sp_head.h"
#include "sp.h" #include "sp.h"
#include "sp_cache.h"
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
/* include MYSQL_BIND headers */ /* include MYSQL_BIND headers */
#include <mysql.h> #include <mysql.h>
@ -1783,6 +1784,9 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
lex= thd->lex; lex= thd->lex;
lex->safe_to_cache_query= 0; lex->safe_to_cache_query= 0;
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
error= yyparse((void *)thd) || thd->is_fatal_error || error= yyparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(stmt); thd->net.report_error || init_param_array(stmt);
/* /*
@ -1851,6 +1855,13 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
SELECT_LEX *sl= lex->all_selects_list; SELECT_LEX *sl= lex->all_selects_list;
DBUG_ENTER("reinit_stmt_before_use"); DBUG_ENTER("reinit_stmt_before_use");
/*
We have to update "thd" pointer in LEX, all its units and in LEX::result,
since statements which belong to trigger body are associated with TABLE
object and because of this can be used in different threads.
*/
lex->thd= thd;
if (lex->empty_field_list_on_rset) if (lex->empty_field_list_on_rset)
{ {
lex->empty_field_list_on_rset= 0; lex->empty_field_list_on_rset= 0;
@ -1889,6 +1900,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
unit->types.empty(); unit->types.empty();
/* for derived tables & PS (which can't be reset by Item_subquery) */ /* for derived tables & PS (which can't be reset by Item_subquery) */
unit->reinit_exec_mechanism(); unit->reinit_exec_mechanism();
unit->set_thd(thd);
} }
} }
@ -1927,7 +1939,10 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
lex->select_lex.leaf_tables= lex->leaf_tables_insert; lex->select_lex.leaf_tables= lex->leaf_tables_insert;
if (lex->result) if (lex->result)
{
lex->result->cleanup(); lex->result->cleanup();
lex->result->set_thd(thd);
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -2060,6 +2075,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
thd->protocol= stmt->protocol; // Switch to binary protocol thd->protocol= stmt->protocol; // Switch to binary protocol
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR); my_pthread_setprio(pthread_self(),QUERY_PRIOR);
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
mysql_execute_command(thd); mysql_execute_command(thd);
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR); my_pthread_setprio(pthread_self(), WAIT_PRIOR);

View File

@ -289,6 +289,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
List_iterator_fast<Item> tp(types); List_iterator_fast<Item> tp(types);
Query_arena *arena= thd->current_arena; Query_arena *arena= thd->current_arena;
Item *type; Item *type;
ulong create_options;
while ((type= tp++)) while ((type= tp++))
{ {
@ -300,7 +301,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
ulong create_options= (first_select_in_union()->options | thd_arg->options | create_options= (first_select_in_union()->options | thd_arg->options |
TMP_TABLE_ALL_COLUMNS) & ~TMP_TABLE_FORCE_MYISAM; TMP_TABLE_ALL_COLUMNS) & ~TMP_TABLE_FORCE_MYISAM;
/* /*
Force the temporary table to be a MyISAM table if we're going to use Force the temporary table to be a MyISAM table if we're going to use

View File

@ -821,7 +821,7 @@ bool mysql_multi_update(THD *thd,
if (mysql_multi_update_prepare(thd)) if (mysql_multi_update_prepare(thd))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!(result= new multi_update(thd, table_list, if (!(result= new multi_update(table_list,
thd->lex->select_lex.leaf_tables, thd->lex->select_lex.leaf_tables,
fields, values, fields, values,
handle_duplicates, ignore))) handle_duplicates, ignore)))
@ -847,13 +847,13 @@ bool mysql_multi_update(THD *thd,
} }
multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, multi_update::multi_update(TABLE_LIST *table_list,
TABLE_LIST *leaves_list, TABLE_LIST *leaves_list,
List<Item> *field_list, List<Item> *value_list, List<Item> *field_list, List<Item> *value_list,
enum enum_duplicates handle_duplicates_arg, enum enum_duplicates handle_duplicates_arg,
bool ignore_arg) bool ignore_arg)
:all_tables(table_list), leaves(leaves_list), update_tables(0), :all_tables(table_list), leaves(leaves_list), update_tables(0),
thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), tmp_tables(0), updated(0), found(0), fields(field_list),
values(value_list), table_count(0), copy_field(0), values(value_list), table_count(0), copy_field(0),
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0), handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0),
transactional_tables(1), ignore(ignore_arg) transactional_tables(1), ignore(ignore_arg)

View File

@ -22,7 +22,7 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X # Exact one of ASSEMBLER_X
if ASSEMBLER_x86 if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c
else else
if ASSEMBLER_sparc32 if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake # These file MUST all be on the same line!! Otherwise automake
@ -45,7 +45,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc
ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
xml.c decimal.c strto.c strings-x86.s \ xml.c decimal.c strto.c strings-x86.s \
longlong2str.c longlong2str-x86.s \ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
my_strtoll10.c my_strtoll10-x86.s \ my_strtoll10.c my_strtoll10-x86.s \
strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
strfill.c strcend.c is_prefix.c strstr.c strinstr.c \ strfill.c strcend.c is_prefix.c strstr.c strinstr.c \

View File

@ -16,26 +16,26 @@
# Optimized longlong2str function for Intel 80x86 (gcc/gas syntax) # Optimized longlong2str function for Intel 80x86 (gcc/gas syntax)
# Some set sequences are optimized for pentuimpro II # Some set sequences are optimized for pentuimpro II
.file "longlong2str.s" .file "longlong2str-x86.s"
.version "1.01" .version "1.02"
.text .text
.align 4 .align 4
.globl longlong2str .globl longlong2str_with_dig_vector
.type longlong2str,@function .type longlong2str_with_dig_vector,@function
longlong2str: longlong2str_with_dig_vector:
subl $80,%esp subl $80,%esp
pushl %ebp pushl %ebp
pushl %esi pushl %esi
pushl %edi pushl %edi
pushl %ebx pushl %ebx
movl 100(%esp),%esi # Lower part of val movl 100(%esp),%esi # Lower part of val
movl 104(%esp),%ebp # Higher part of val
movl 108(%esp),%edi # get dst
movl 112(%esp),%ebx # Radix movl 112(%esp),%ebx # Radix
movl 104(%esp),%ebp # Higher part of val
movl %ebx,%eax movl %ebx,%eax
movl 108(%esp),%edi # get dst
testl %eax,%eax testl %eax,%eax
jge .L144 jge .L144
@ -69,6 +69,8 @@ longlong2str:
.L150: .L150:
leal 92(%esp),%ecx # End of buffer leal 92(%esp),%ecx # End of buffer
movl %edi, 108(%esp) # Store possible modified dest
movl 116(%esp), %edi # dig_vec_upper
jmp .L155 jmp .L155
.align 4 .align 4
@ -83,7 +85,7 @@ longlong2str:
divl %ebx divl %ebx
decl %ecx decl %ecx
movl %eax,%esi # quotent in ebp:esi movl %eax,%esi # quotent in ebp:esi
movb _dig_vec_upper(%edx),%al # al is faster than dl movb (%edx,%edi),%al # al is faster than dl
movb %al,(%ecx) # store value in buff movb %al,(%ecx) # store value in buff
.align 4 .align 4
.L155: .L155:
@ -91,20 +93,22 @@ longlong2str:
ja .L153 ja .L153
testl %esi,%esi # rest value testl %esi,%esi # rest value
jl .L153 jl .L153
je .L10_mov # Ready je .L160 # Ready
movl %esi,%eax movl %esi,%eax
movl $_dig_vec_upper,%ebp
.align 4 .align 4
.L154: # Do rest with integer precision .L154: # Do rest with integer precision
cltd cltd
divl %ebx divl %ebx
decl %ecx decl %ecx
movb (%edx,%ebp),%dl # bh is always zero as ebx=radix < 36 movb (%edx,%edi),%dl # bh is always zero as ebx=radix < 36
testl %eax,%eax testl %eax,%eax
movb %dl,(%ecx) movb %dl,(%ecx)
jne .L154 jne .L154
.L160:
movl 108(%esp),%edi # get dst
.L10_mov: .L10_mov:
movl %ecx,%esi movl %ecx,%esi
leal 92(%esp),%ecx # End of buffer leal 92(%esp),%ecx # End of buffer
@ -129,7 +133,7 @@ longlong2str:
jmp .L165 jmp .L165
.Lfe3: .Lfe3:
.size longlong2str,.Lfe3-longlong2str .size longlong2str_with_dig_vector,.Lfe3-longlong2str_with_dig_vector
# #
# This is almost equal to the above, except that we can do the final # This is almost equal to the above, except that we can do the final
@ -137,9 +141,6 @@ longlong2str:
# #
.align 4 .align 4
.Ltmp:
.long 0xcccccccd
.align 4
.globl longlong10_to_str .globl longlong10_to_str
.type longlong10_to_str,@function .type longlong10_to_str,@function
@ -202,7 +203,7 @@ longlong10_to_str:
# The following code uses some tricks to change division by 10 to # The following code uses some tricks to change division by 10 to
# multiplication and shifts # multiplication and shifts
movl .Ltmp,%esi # set %esi to 0xcccccccd movl $0xcccccccd,%esi
.L10_40: .L10_40:
movl %ebx,%eax movl %ebx,%eax

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Wrapper for longlong2str.s
We need this because the assembler code can't access the local variable
_dig_vector in a portable manner.
*/
#include <my_global.h>
#include "m_string.h"
extern char *longlong2str_with_dig_vector(longlong val,char *dst,int radix,
const char *dig_vector);
char *longlong2str(longlong val,char *dst,int radix)
{
return longlong2str_with_dig_vector(val, dst, radix, _dig_vec_upper);
}

View File

@ -17,21 +17,8 @@
# For documentation, check my_strtoll.c # For documentation, check my_strtoll.c
.file "my_strtoll10-x86.s" .file "my_strtoll10-x86.s"
.version "01.01" .version "01.02"
.data
.align 32
.type lfactor,@object
.size lfactor,36
lfactor:
.long 1
.long 10
.long 100
.long 1000
.long 10000
.long 100000
.long 1000000
.long 10000000
.long 100000000
.text .text
.align 4 .align 4
@ -209,14 +196,16 @@ my_strtoll10:
jne .L500 jne .L500
cmpl -36(%ebp),%esi # Test if string is less than 18 digits cmpl -36(%ebp),%esi # Test if string is less than 18 digits
jne .Lend_i_and_j jne .Lend_i_and_j
jmp .Lend3 # 18 digit string .L499:
movl $1000000000,%eax
jmp .Lgot_factor # 18 digit string
# Handle the possible next to last digit and store in ecx # Handle the possible next to last digit and store in ecx
.L500: .L500:
movb (%esi),%al movb (%esi),%al
addb $-48,%al addb $-48,%al
cmpb $9,%al cmpb $9,%al
ja .Lend3 ja .L499 # 18 digit string
incl %esi incl %esi
movzbl %al,%ecx movzbl %al,%ecx
@ -315,14 +304,41 @@ my_strtoll10:
.Lend_i_and_j: .Lend_i_and_j:
movl %esi,%ecx movl %esi,%ecx
subl -12(%ebp),%ecx # ecx= number of digits in second part subl -12(%ebp),%ecx # ecx= number of digits in second part
movl lfactor(,%ecx,4),%eax
jmp .L523
# Return -8(%ebp) * $1000000000 + edi # Calculate %eax= 10 ** %cl, where %cl <= 8
# With an array one could do this with:
# movl 10_factor_table(,%ecx,4),%eax
# We calculate the table here to avoid problems in
# position independent code (gcc -pic)
cmpb $3,%cl
ja .L4_to_8
movl $1000, %eax
je .Lgot_factor # %cl=3, eax= 1000
movl $10, %eax
cmpb $1,%cl # %cl is here 0 - 2
je .Lgot_factor # %cl=1, eax= 10
movl $100, %eax
ja .Lgot_factor # %cl=2, eax=100
movl $1, %eax
jmp .Lgot_factor # %cl=0, eax=1
.L4_to_8: # %cl is here 4-8
cmpb $5,%cl
movl $100000, %eax
je .Lgot_factor # %cl=5, eax=100000
movl $10000, %eax
jbe .Lgot_factor # %cl=4, eax=10000
movl $10000000, %eax
cmpb $7,%cl
je .Lgot_factor # %cl=7, eax=10000000
movl $100000000, %eax
ja .Lgot_factor # %cl=8, eax=100000000
movl $1000000, %eax # %cl=6, eax=1000000
# Return -8(%ebp) * %eax + edi
.p2align 4,,7 .p2align 4,,7
.Lend3: .Lgot_factor:
movl $1000000000,%eax
.L523:
mull -8(%ebp) mull -8(%ebp)
addl %edi,%eax addl %edi,%eax
adcl $0,%edx adcl $0,%edx

View File

@ -7195,7 +7195,7 @@ static void test_prepare_grant()
} }
} }
#endif #endif /* EMBEDDED_LIBRARY */
/* /*
Test a crash when invalid/corrupted .frm is used in the Test a crash when invalid/corrupted .frm is used in the