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:
commit
04e2ca68ff
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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 '),':');
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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++;
|
||||||
|
164
sql/ha_innodb.cc
164
sql/ha_innodb.cc
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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",
|
||||||
|
@ -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},
|
||||||
|
@ -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);
|
||||||
|
16
sql/sp.cc
16
sql/sp.cc
@ -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);
|
||||||
}
|
}
|
||||||
|
216
sql/sp_cache.cc
216
sql/sp_cache.cc
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -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 */
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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 \
|
||||||
|
@ -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
|
||||||
|
33
strings/longlong2str_asm.c
Normal file
33
strings/longlong2str_asm.c
Normal 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);
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user