mirror of
https://github.com/MariaDB/server.git
synced 2025-08-09 22:24:09 +03:00
Merge mysql.com:/home/jimw/my/mysql-5.0-clean
into mysql.com:/home/jimw/my/mysql-5.1-clean
This commit is contained in:
@@ -2437,7 +2437,9 @@ a b
|
|||||||
20 NULL
|
20 NULL
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (v varchar(65530), key(v));
|
create table t1 (v varchar(65530), key(v));
|
||||||
ERROR HY000: Can't create table 'test.t1' (errno: 139)
|
Warnings:
|
||||||
|
Warning 1071 Specified key was too long; max key length is 767 bytes
|
||||||
|
drop table t1;
|
||||||
create table t1 (v varchar(65536));
|
create table t1 (v varchar(65536));
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1246 Converting column 'v' from VARCHAR to TEXT
|
Note 1246 Converting column 'v' from VARCHAR to TEXT
|
||||||
@@ -2577,22 +2579,49 @@ create table t8 (col1 blob, index(col1(767)))
|
|||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
|
create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
|
show create table t9;
|
||||||
|
Table Create Table
|
||||||
|
t9 CREATE TABLE `t9` (
|
||||||
|
`col1` varchar(512) default NULL,
|
||||||
|
`col2` varchar(512) default NULL,
|
||||||
|
KEY `col1` (`col1`,`col2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
||||||
create table t1 (col1 varchar(768), index(col1))
|
create table t1 (col1 varchar(768), index(col1))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table 'test.t1' (errno: 139)
|
Warnings:
|
||||||
create table t2 (col1 varchar(768) primary key)
|
Warning 1071 Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t2 (col1 varbinary(768), index(col1))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table 'test.t2' (errno: 139)
|
Warnings:
|
||||||
create table t3 (col1 varbinary(768) primary key)
|
Warning 1071 Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t3 (col1 text, index(col1(768)))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table 'test.t3' (errno: 139)
|
Warnings:
|
||||||
create table t4 (col1 text, index(col1(768)))
|
Warning 1071 Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t4 (col1 blob, index(col1(768)))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table 'test.t4' (errno: 139)
|
Warnings:
|
||||||
create table t5 (col1 blob, index(col1(768)))
|
Warning 1071 Specified key was too long; max key length is 767 bytes
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`col1` varchar(768) default NULL,
|
||||||
|
KEY `col1` (`col1`(767))
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t1, t2, t3, t4;
|
||||||
|
create table t1 (col1 varchar(768) primary key)
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table 'test.t5' (errno: 139)
|
ERROR 42000: Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t2 (col1 varbinary(768) primary key)
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
ERROR 42000: Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t3 (col1 text, primary key(col1(768)))
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
ERROR 42000: Specified key was too long; max key length is 767 bytes
|
||||||
|
create table t4 (col1 blob, primary key(col1(768)))
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
ERROR 42000: Specified key was too long; max key length is 767 bytes
|
||||||
CREATE TABLE t1
|
CREATE TABLE t1
|
||||||
(
|
(
|
||||||
id INT PRIMARY KEY
|
id INT PRIMARY KEY
|
||||||
@@ -2772,6 +2801,38 @@ insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
commit;
|
commit;
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
|
||||||
|
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
|
||||||
|
ERROR HY000: Can't create table './test/t1.frm' (errno: 150)
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2;
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
|
||||||
|
ERROR HY000: Can't create table './test/t2.frm' (errno: 150)
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t1;
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb;
|
||||||
|
alter table t1 modify column a int;
|
||||||
|
Got one of the listed errors
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t1;
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t1;
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
|
||||||
|
rename table t3 to t1;
|
||||||
|
ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t3;
|
||||||
create table t1 (a varchar(255) character set utf8,
|
create table t1 (a varchar(255) character set utf8,
|
||||||
b varchar(255) character set utf8,
|
b varchar(255) character set utf8,
|
||||||
c varchar(255) character set utf8,
|
c varchar(255) character set utf8,
|
||||||
|
77
mysql-test/r/sp-destruct.result
Normal file
77
mysql-test/r/sp-destruct.result
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
use test;
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
call bug14233_3();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
@@ -124,7 +124,7 @@ begin
|
|||||||
declare x int;
|
declare x int;
|
||||||
set x = val+3;
|
set x = val+3;
|
||||||
end|
|
end|
|
||||||
ERROR 42000: No RETURN found in FUNCTION f
|
ERROR 42000: No RETURN found in FUNCTION test.f
|
||||||
create function f(val int) returns int
|
create function f(val int) returns int
|
||||||
begin
|
begin
|
||||||
declare x int;
|
declare x int;
|
||||||
|
@@ -4153,4 +4153,43 @@ A local variable in a nested compound statement takes precedence over table colu
|
|||||||
a - local variable in a nested compound statement
|
a - local variable in a nested compound statement
|
||||||
A local variable in a nested compound statement takes precedence over table column in cursors
|
A local variable in a nested compound statement takes precedence over table column in cursors
|
||||||
a - local variable in a nested compound statement
|
a - local variable in a nested compound statement
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest1'; database doesn't exist
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest2'; database doesn't exist
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
Warnings:
|
||||||
|
Note 1008 Can't drop database 'mysqltest3'; database doesn't exist
|
||||||
|
create schema mysqltest1|
|
||||||
|
create schema mysqltest2|
|
||||||
|
create schema mysqltest3|
|
||||||
|
use mysqltest3|
|
||||||
|
create procedure mysqltest1.p1 (out prequestid varchar(100))
|
||||||
|
begin
|
||||||
|
call mysqltest2.p2('call mysqltest3.p3(1, 2)');
|
||||||
|
end|
|
||||||
|
create procedure mysqltest2.p2(in psql text)
|
||||||
|
begin
|
||||||
|
declare lsql text;
|
||||||
|
set @lsql= psql;
|
||||||
|
prepare lstatement from @lsql;
|
||||||
|
execute lstatement;
|
||||||
|
deallocate prepare lstatement;
|
||||||
|
end|
|
||||||
|
create procedure mysqltest3.p3(in p1 int)
|
||||||
|
begin
|
||||||
|
select p1;
|
||||||
|
end|
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
use test|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
@@ -114,3 +114,26 @@ drop table t1;
|
|||||||
select hex(cast(0x10 as binary(2)));
|
select hex(cast(0x10 as binary(2)));
|
||||||
hex(cast(0x10 as binary(2)))
|
hex(cast(0x10 as binary(2)))
|
||||||
1000
|
1000
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'b' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'vb' at row 1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c char(2), vc varchar(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'vc' at row 1
|
||||||
|
drop table t1;
|
||||||
|
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, NULL);
|
||||||
|
ERROR 22001: Data too long for column 'b' at row 1
|
||||||
|
insert into t1 values(NULL, 0x412020);
|
||||||
|
ERROR 22001: Data too long for column 'vb' at row 1
|
||||||
|
drop table t1;
|
||||||
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
End of 5.0 tests
|
||||||
|
@@ -1356,8 +1356,8 @@ source include/varchar.inc;
|
|||||||
# Clean up filename -- embedded server reports whole path without .frm,
|
# Clean up filename -- embedded server reports whole path without .frm,
|
||||||
# regular server reports relative path with .frm (argh!)
|
# regular server reports relative path with .frm (argh!)
|
||||||
--replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t1.frm t1
|
--replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t1.frm t1
|
||||||
--error 1005
|
|
||||||
create table t1 (v varchar(65530), key(v));
|
create table t1 (v varchar(65530), key(v));
|
||||||
|
drop table t1;
|
||||||
create table t1 (v varchar(65536));
|
create table t1 (v varchar(65536));
|
||||||
show create table t1;
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@@ -1485,7 +1485,7 @@ CREATE TEMPORARY TABLE t2
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that index column max sizes are checked (bug #13315)
|
# Test that index column max sizes are honored (bug #13315)
|
||||||
#
|
#
|
||||||
|
|
||||||
# prefix index
|
# prefix index
|
||||||
@@ -1512,22 +1512,36 @@ create table t8 (col1 blob, index(col1(767)))
|
|||||||
create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
|
create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
|
|
||||||
|
show create table t9;
|
||||||
|
|
||||||
drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
||||||
|
|
||||||
--error 1005
|
# these should have their index length trimmed
|
||||||
create table t1 (col1 varchar(768), index(col1))
|
create table t1 (col1 varchar(768), index(col1))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
--error 1005
|
create table t2 (col1 varbinary(768), index(col1))
|
||||||
create table t2 (col1 varchar(768) primary key)
|
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
--error 1005
|
create table t3 (col1 text, index(col1(768)))
|
||||||
create table t3 (col1 varbinary(768) primary key)
|
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
--error 1005
|
create table t4 (col1 blob, index(col1(768)))
|
||||||
create table t4 (col1 text, index(col1(768)))
|
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
--error 1005
|
|
||||||
create table t5 (col1 blob, index(col1(768)))
|
show create table t1;
|
||||||
|
|
||||||
|
drop table t1, t2, t3, t4;
|
||||||
|
|
||||||
|
# these should be refused
|
||||||
|
--error 1071
|
||||||
|
create table t1 (col1 varchar(768) primary key)
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
--error 1071
|
||||||
|
create table t2 (col1 varbinary(768) primary key)
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
--error 1071
|
||||||
|
create table t3 (col1 text, primary key(col1(768)))
|
||||||
|
character set = latin1 engine = innodb;
|
||||||
|
--error 1071
|
||||||
|
create table t4 (col1 blob, primary key(col1(768)))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1752,6 +1766,56 @@ drop table t1;
|
|||||||
drop table t2;
|
drop table t2;
|
||||||
commit;
|
commit;
|
||||||
|
|
||||||
|
# tests for bugs #9802 and #13778
|
||||||
|
|
||||||
|
# test that FKs between invalid types are not accepted
|
||||||
|
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
|
||||||
|
-- error 1005
|
||||||
|
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
# test that FKs between different charsets are not accepted in CREATE even
|
||||||
|
# when f_k_c is 0
|
||||||
|
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
-- error 1005
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# test that invalid datatype conversions with ALTER are not allowed
|
||||||
|
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb;
|
||||||
|
-- error 1025,1025
|
||||||
|
alter table t1 modify column a int;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t1;
|
||||||
|
|
||||||
|
# test that charset conversions with ALTER are allowed when f_k_c is 0
|
||||||
|
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
alter table t1 convert to character set utf8;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t1;
|
||||||
|
|
||||||
|
# test that RENAME does not allow invalid charsets when f_k_c is 0
|
||||||
|
|
||||||
|
set foreign_key_checks=0;
|
||||||
|
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
|
||||||
|
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
|
||||||
|
-- error 1025
|
||||||
|
rename table t3 to t1;
|
||||||
|
set foreign_key_checks=1;
|
||||||
|
drop table t2,t3;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that we can create a large (>1K) key
|
# Test that we can create a large (>1K) key
|
||||||
#
|
#
|
||||||
|
124
mysql-test/t/sp-destruct.test
Normal file
124
mysql-test/t/sp-destruct.test
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#
|
||||||
|
# Destructive stored procedure tests
|
||||||
|
#
|
||||||
|
# We do horrible things to the mysql.proc table here, so any unexpected
|
||||||
|
# failures here might leave it in an undetermined state.
|
||||||
|
#
|
||||||
|
# In the case of trouble you might want to skip this.
|
||||||
|
#
|
||||||
|
|
||||||
|
# We're using --system things that probably doesn't work on Windows.
|
||||||
|
--source include/not_windows.inc
|
||||||
|
|
||||||
|
# Backup proc table
|
||||||
|
--system rm -rf var/master-data/mysql/backup
|
||||||
|
--system mkdir var/master-data/mysql/backup
|
||||||
|
--system cp var/master-data/mysql/proc.* var/master-data/mysql/backup/
|
||||||
|
|
||||||
|
use test;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
|
||||||
|
# Unsupported tampering with the mysql.proc definition
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Thrashing the .frm file
|
||||||
|
--system echo 'saljdlfa' > var/master-data/mysql/proc.frm
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Drop the mysql.proc table
|
||||||
|
--system rm var/master-data/mysql/proc.*
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Restore mysql.proc
|
||||||
|
--system mv var/master-data/mysql/backup/* var/master-data/mysql/
|
||||||
|
--system rmdir var/master-data/mysql/backup
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
|
||||||
|
# Unsupported editing of mysql.proc, circumventing checks in "create ..."
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_1();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_2();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233_3();
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Clean-up
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
@@ -13,6 +13,8 @@
|
|||||||
# Tests that require multiple connections, except security/privilege tests,
|
# Tests that require multiple connections, except security/privilege tests,
|
||||||
# go to sp-thread.
|
# go to sp-thread.
|
||||||
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
||||||
|
# Tests that destroys system tables (e.g. mysql.proc) for error testing
|
||||||
|
# go to sp-destruct.
|
||||||
|
|
||||||
use test;
|
use test;
|
||||||
|
|
||||||
@@ -4945,6 +4947,52 @@ begin
|
|||||||
end|
|
end|
|
||||||
call p1("a - stored procedure parameter")|
|
call p1("a - stored procedure parameter")|
|
||||||
|
|
||||||
|
#
|
||||||
|
# A test case for Bug#15392 "Server crashes during prepared statement
|
||||||
|
# execute": make sure that stored procedure check for error conditions
|
||||||
|
# properly and do not continue execution if an error has been set.
|
||||||
|
#
|
||||||
|
# It's necessary to use several DBs because in the original code
|
||||||
|
# the successful return of mysql_change_db overrode the error from
|
||||||
|
# execution.
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
create schema mysqltest1|
|
||||||
|
create schema mysqltest2|
|
||||||
|
create schema mysqltest3|
|
||||||
|
use mysqltest3|
|
||||||
|
|
||||||
|
create procedure mysqltest1.p1 (out prequestid varchar(100))
|
||||||
|
begin
|
||||||
|
call mysqltest2.p2('call mysqltest3.p3(1, 2)');
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure mysqltest2.p2(in psql text)
|
||||||
|
begin
|
||||||
|
declare lsql text;
|
||||||
|
set @lsql= psql;
|
||||||
|
prepare lstatement from @lsql;
|
||||||
|
execute lstatement;
|
||||||
|
deallocate prepare lstatement;
|
||||||
|
end|
|
||||||
|
|
||||||
|
create procedure mysqltest3.p3(in p1 int)
|
||||||
|
begin
|
||||||
|
select p1;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
--error ER_SP_WRONG_NO_OF_ARGS
|
||||||
|
call mysqltest1.p1(@rs)|
|
||||||
|
drop schema if exists mysqltest1|
|
||||||
|
drop schema if exists mysqltest2|
|
||||||
|
drop schema if exists mysqltest3|
|
||||||
|
use test|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
@@ -68,3 +68,27 @@ drop table t1;
|
|||||||
|
|
||||||
# check that cast appends trailing zeros
|
# check that cast appends trailing zeros
|
||||||
select hex(cast(0x10 as binary(2)));
|
select hex(cast(0x10 as binary(2)));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #14299: BINARY space truncation should cause warning or error
|
||||||
|
#
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (c char(2), vc varchar(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
insert into t1 values(0x412020, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
|
||||||
|
create table t1 (b binary(2), vb varbinary(2));
|
||||||
|
insert into t1 values(0x4120, 0x4120);
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
insert into t1 values(0x412020, NULL);
|
||||||
|
--error ER_DATA_TOO_LONG
|
||||||
|
insert into t1 values(NULL, 0x412020);
|
||||||
|
drop table t1;
|
||||||
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
23
sql/field.cc
23
sql/field.cc
@@ -5874,23 +5874,30 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
error= 2;
|
error= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Make sure we don't break a multibyte sequence or copy malformed data. */
|
||||||
Make sure we don't break a multibyte sequence
|
|
||||||
as well as don't copy a malformed data.
|
|
||||||
*/
|
|
||||||
copy_length= field_charset->cset->well_formed_len(field_charset,
|
copy_length= field_charset->cset->well_formed_len(field_charset,
|
||||||
from,from+length,
|
from,from+length,
|
||||||
field_length/
|
field_length/
|
||||||
field_charset->mbmaxlen,
|
field_charset->mbmaxlen,
|
||||||
&well_formed_error);
|
&well_formed_error);
|
||||||
memcpy(ptr,from,copy_length);
|
memcpy(ptr,from,copy_length);
|
||||||
if (copy_length < field_length) // Append spaces if shorter
|
|
||||||
|
/* Append spaces if the string was shorter than the field. */
|
||||||
|
if (copy_length < field_length)
|
||||||
field_charset->cset->fill(field_charset,ptr+copy_length,
|
field_charset->cset->fill(field_charset,ptr+copy_length,
|
||||||
field_length-copy_length,
|
field_length-copy_length,
|
||||||
field_charset->pad_char);
|
field_charset->pad_char);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if we lost any important data (anything in a binary string,
|
||||||
|
or any non-space in others).
|
||||||
|
*/
|
||||||
if ((copy_length < length) && table->in_use->count_cuted_fields)
|
if ((copy_length < length) && table->in_use->count_cuted_fields)
|
||||||
{ // Check if we loosed some info
|
{
|
||||||
|
if (binary())
|
||||||
|
error= 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
const char *end=from+length;
|
const char *end=from+length;
|
||||||
from+= copy_length;
|
from+= copy_length;
|
||||||
from+= field_charset->cset->scan(field_charset, from, end,
|
from+= field_charset->cset->scan(field_charset, from, end,
|
||||||
@@ -5898,6 +5905,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
if (from != end)
|
if (from != end)
|
||||||
error= 2;
|
error= 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
if (table->in_use->abort_on_warning)
|
if (table->in_use->abort_on_warning)
|
||||||
@@ -6297,6 +6305,8 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
// Check if we lost something other than just trailing spaces
|
// Check if we lost something other than just trailing spaces
|
||||||
if ((copy_length < length) && table->in_use->count_cuted_fields &&
|
if ((copy_length < length) && table->in_use->count_cuted_fields &&
|
||||||
!error_code)
|
!error_code)
|
||||||
|
{
|
||||||
|
if (!binary())
|
||||||
{
|
{
|
||||||
const char *end= from + length;
|
const char *end= from + length;
|
||||||
from+= copy_length;
|
from+= copy_length;
|
||||||
@@ -6304,6 +6314,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
/* If we lost only spaces then produce a NOTE, not a WARNING */
|
/* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||||
if (from == end)
|
if (from == end)
|
||||||
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
|
||||||
|
}
|
||||||
error_code= WARN_DATA_TRUNCATED;
|
error_code= WARN_DATA_TRUNCATED;
|
||||||
}
|
}
|
||||||
if (error_code)
|
if (error_code)
|
||||||
|
@@ -2540,6 +2540,12 @@ ha_innobase::open(
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
ha_innobase::max_supported_key_part_length() const
|
||||||
|
{
|
||||||
|
return(DICT_MAX_INDEX_COL_LEN - 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Closes a handle to an InnoDB table. */
|
Closes a handle to an InnoDB table. */
|
||||||
|
|
||||||
@@ -4698,6 +4704,9 @@ create_index(
|
|||||||
0, prefix_len);
|
0, prefix_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Even though we've defined max_supported_key_part_length, we
|
||||||
|
still do our own checking using field_lengths to be absolutely
|
||||||
|
sure we don't create too long indexes. */
|
||||||
error = row_create_index_for_mysql(index, trx, field_lengths);
|
error = row_create_index_for_mysql(index, trx, field_lengths);
|
||||||
|
|
||||||
error = convert_error_code_to_mysql(error, NULL);
|
error = convert_error_code_to_mysql(error, NULL);
|
||||||
|
@@ -110,7 +110,7 @@ class ha_innobase: public handler
|
|||||||
but currently MySQL does not work with keys
|
but currently MySQL does not work with keys
|
||||||
whose size is > MAX_KEY_LENGTH */
|
whose size is > MAX_KEY_LENGTH */
|
||||||
uint max_supported_key_length() const { return 3500; }
|
uint max_supported_key_length() const { return 3500; }
|
||||||
uint max_supported_key_part_length() const { return 3500; }
|
uint max_supported_key_part_length() const;
|
||||||
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
|
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
|
||||||
bool has_transactions() { return 1;}
|
bool has_transactions() { return 1;}
|
||||||
|
|
||||||
|
@@ -5597,6 +5597,8 @@ ER_OLD_FILE_FORMAT
|
|||||||
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
||||||
ER_SP_RECURSION_LIMIT
|
ER_SP_RECURSION_LIMIT
|
||||||
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
||||||
|
ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
|
||||||
ER_PARTITION_REQUIRES_VALUES_ERROR
|
ER_PARTITION_REQUIRES_VALUES_ERROR
|
||||||
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
|
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
|
||||||
swe "%s PARTITIONering kr<6B>ver definition av VALUES %s f<>r varje partition"
|
swe "%s PARTITIONering kr<6B>ver definition av VALUES %s f<>r varje partition"
|
||||||
|
95
sql/sp.cc
95
sql/sp.cc
@@ -1447,21 +1447,23 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
|
|||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
will be executed in non-prelocked mode.
|
will be executed in non-prelocked mode.
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
NOTE
|
NOTE
|
||||||
If some function is missing this won't be reported here.
|
If some function is missing this won't be reported here.
|
||||||
Instead this fact will be discovered during query execution.
|
Instead this fact will be discovered during query execution.
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static int
|
||||||
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
Sroutine_hash_entry *start,
|
Sroutine_hash_entry *start,
|
||||||
bool first_no_prelock)
|
bool first_no_prelock, bool *tabs_changed)
|
||||||
{
|
{
|
||||||
bool result= FALSE;
|
int ret= 0;
|
||||||
|
bool tabschnd= 0; /* Set if tables changed */
|
||||||
bool first= TRUE;
|
bool first= TRUE;
|
||||||
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
||||||
|
|
||||||
@@ -1482,25 +1484,66 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
name.m_name.str+= 1;
|
name.m_name.str+= 1;
|
||||||
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
||||||
|
|
||||||
if (db_find_routine(thd, type, &name, &sp) == SP_OK)
|
switch ((ret= db_find_routine(thd, type, &name, &sp)))
|
||||||
|
{
|
||||||
|
case SP_OK:
|
||||||
{
|
{
|
||||||
if (type == TYPE_ENUM_FUNCTION)
|
if (type == TYPE_ENUM_FUNCTION)
|
||||||
sp_cache_insert(&thd->sp_func_cache, sp);
|
sp_cache_insert(&thd->sp_func_cache, sp);
|
||||||
else
|
else
|
||||||
sp_cache_insert(&thd->sp_proc_cache, sp);
|
sp_cache_insert(&thd->sp_proc_cache, sp);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SP_KEY_NOT_FOUND:
|
||||||
|
ret= SP_OK;
|
||||||
|
break;
|
||||||
|
case SP_OPEN_TABLE_FAILED:
|
||||||
|
/*
|
||||||
|
Force it to attempt opening it again on subsequent calls;
|
||||||
|
otherwise we will get one error message the first time, and
|
||||||
|
then ER_SP_PROC_TABLE_CORRUPT (below) on subsequent tries.
|
||||||
|
*/
|
||||||
|
mysql_proc_table_exists= 1;
|
||||||
|
/* Fall through */
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
Any error when loading an existing routine is either some problem
|
||||||
|
with the mysql.proc table, or a parse error because the contents
|
||||||
|
has been tampered with (in which case we clear that error).
|
||||||
|
*/
|
||||||
|
if (ret == SP_PARSE_ERROR)
|
||||||
|
thd->clear_error();
|
||||||
|
/*
|
||||||
|
If we cleared the parse error, or when db_find_routine() flagged
|
||||||
|
an error with it's return value without calling my_error(), we
|
||||||
|
set the generic "mysql.proc table corrupt" error here.
|
||||||
|
*/
|
||||||
|
if (!thd->net.report_error)
|
||||||
|
{
|
||||||
|
char n[NAME_LEN*2+2];
|
||||||
|
|
||||||
|
/* m_qname.str is not always \0 terminated */
|
||||||
|
memcpy(n, name.m_qname.str, name.m_qname.length);
|
||||||
|
n[name.m_qname.length]= '\0';
|
||||||
|
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sp)
|
if (sp)
|
||||||
{
|
{
|
||||||
if (!(first && first_no_prelock))
|
if (!(first && first_no_prelock))
|
||||||
{
|
{
|
||||||
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
|
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
|
||||||
result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
tabschnd|=
|
||||||
|
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first= FALSE;
|
first= FALSE;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(result);
|
if (tabs_changed) /* it can be NULL */
|
||||||
|
*tabs_changed= tabschnd;
|
||||||
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1515,18 +1558,20 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
int
|
||||||
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
|
||||||
|
bool *tabs_changed)
|
||||||
{
|
{
|
||||||
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
||||||
first_no_prelock);
|
first_no_prelock, tabs_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1540,16 +1585,21 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
|||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
aux_lex - LEX representing view
|
aux_lex - LEX representing view
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
||||||
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
|
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr, FALSE);
|
*last_cached_routine_ptr, FALSE,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1563,12 +1613,18 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
|||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX respresenting statement
|
lex - LEX respresenting statement
|
||||||
triggers - triggers of the table
|
triggers - triggers of the table
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers)
|
Table_triggers_list *triggers)
|
||||||
{
|
{
|
||||||
|
int ret= 0;
|
||||||
|
|
||||||
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
@@ -1586,10 +1642,11 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr,
|
*last_cached_routine_ptr,
|
||||||
FALSE);
|
FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
8
sql/sp.h
8
sql/sp.h
@@ -84,11 +84,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
|||||||
sp_name *rt, char rt_type);
|
sp_name *rt, char rt_type);
|
||||||
void sp_remove_not_own_routines(LEX *lex);
|
void sp_remove_not_own_routines(LEX *lex);
|
||||||
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
||||||
bool sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
||||||
bool first_no_prelock);
|
bool first_no_prelock, bool *tabs_changed);
|
||||||
void sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
||||||
LEX *aux_lex);
|
LEX *aux_lex);
|
||||||
void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
||||||
|
@@ -1143,10 +1143,12 @@ int sp_head::execute(THD *thd)
|
|||||||
original thd->db will then have been freed */
|
original thd->db will then have been freed */
|
||||||
if (dbchanged)
|
if (dbchanged)
|
||||||
{
|
{
|
||||||
/* No access check when changing back to where we came from.
|
/*
|
||||||
(It would generate an error from mysql_change_db() when olddb=="") */
|
No access check when changing back to where we came from.
|
||||||
|
(It would generate an error from mysql_change_db() when olddb=="")
|
||||||
|
*/
|
||||||
if (! thd->killed)
|
if (! thd->killed)
|
||||||
ret= mysql_change_db(thd, olddb, 1);
|
ret|= (int) mysql_change_db(thd, olddb, 1);
|
||||||
}
|
}
|
||||||
m_flags&= ~IS_INVOKED;
|
m_flags&= ~IS_INVOKED;
|
||||||
DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
|
DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
|
||||||
@@ -1525,13 +1527,12 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||||||
|
|
||||||
suv= new Item_func_set_user_var(guv->get_name(), item);
|
suv= new Item_func_set_user_var(guv->get_name(), item);
|
||||||
/*
|
/*
|
||||||
we do not check suv->fixed, because it can't be fixed after
|
Item_func_set_user_var is not fixed after construction,
|
||||||
creation
|
call fix_fields().
|
||||||
*/
|
*/
|
||||||
suv->fix_fields(thd, &item);
|
if ((ret= test(!suv || suv->fix_fields(thd, &item) ||
|
||||||
suv->fix_length_and_dec();
|
suv->check() || suv->update())))
|
||||||
suv->check();
|
break;
|
||||||
suv->update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2103,7 +2104,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
|
|
||||||
cleanup_items() is called in sp_head::execute()
|
cleanup_items() is called in sp_head::execute()
|
||||||
*/
|
*/
|
||||||
return res;
|
return res || thd->net.report_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2616,15 +2616,25 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
||||||
thd->lex->sroutines_list.elements)
|
thd->lex->sroutines_list.elements)
|
||||||
{
|
{
|
||||||
bool first_no_prelocking, need_prelocking;
|
bool first_no_prelocking, need_prelocking, tabs_changed;
|
||||||
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
||||||
|
|
||||||
DBUG_ASSERT(thd->lex->query_tables == *start);
|
DBUG_ASSERT(thd->lex->query_tables == *start);
|
||||||
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
||||||
|
|
||||||
if ((sp_cache_routines_and_add_tables(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables(thd, thd->lex,
|
||||||
first_no_prelocking) ||
|
first_no_prelocking,
|
||||||
*start) && need_prelocking)
|
&tabs_changed))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if ((tabs_changed || *start) && need_prelocking)
|
||||||
{
|
{
|
||||||
query_tables_last_own= save_query_tables_last;
|
query_tables_last_own= save_query_tables_last;
|
||||||
*start= thd->lex->query_tables;
|
*start= thd->lex->query_tables;
|
||||||
@@ -2749,8 +2759,17 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
{
|
{
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
||||||
tables->table->triggers);
|
tables->table->triggers))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||||
}
|
}
|
||||||
@@ -2771,9 +2790,21 @@ process_view_routines:
|
|||||||
/* We have at least one table in TL here. */
|
/* We have at least one table in TL here. */
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables->view);
|
if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex,
|
||||||
|
tables->view))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
thd->proc_info=0;
|
thd->proc_info=0;
|
||||||
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
||||||
|
|
||||||
|
@@ -4122,14 +4122,6 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
|
|
||||||
!(lex->sphead->m_flags & sp_head::HAS_RETURN))
|
|
||||||
{
|
|
||||||
my_error(ER_SP_NORETURN, MYF(0), name);
|
|
||||||
delete lex->sphead;
|
|
||||||
lex->sphead= 0;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to copy name and db in order to use them for
|
We need to copy name and db in order to use them for
|
||||||
|
@@ -117,7 +117,7 @@ public:
|
|||||||
void set_table(TABLE *new_table);
|
void set_table(TABLE *new_table);
|
||||||
|
|
||||||
friend class Item_trigger_field;
|
friend class Item_trigger_field;
|
||||||
friend void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
friend int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -1434,6 +1434,11 @@ create_function_tail:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||||
sp->init_strings(YYTHD, lex, lex->spname);
|
sp->init_strings(YYTHD, lex, lex->spname);
|
||||||
|
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||||
|
{
|
||||||
|
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
/* Restore flag if it was cleared above */
|
/* Restore flag if it was cleared above */
|
||||||
if (sp->m_old_cmq)
|
if (sp->m_old_cmq)
|
||||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||||
|
@@ -904,6 +904,7 @@ btr_search_drop_page_hash_index(
|
|||||||
ulint* folds;
|
ulint* folds;
|
||||||
ulint i;
|
ulint i;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
|
dict_index_t* index;
|
||||||
ulint* offsets;
|
ulint* offsets;
|
||||||
|
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
@@ -932,11 +933,16 @@ btr_search_drop_page_hash_index(
|
|||||||
|
|
||||||
n_fields = block->curr_n_fields;
|
n_fields = block->curr_n_fields;
|
||||||
n_bytes = block->curr_n_bytes;
|
n_bytes = block->curr_n_bytes;
|
||||||
|
index = block->index;
|
||||||
|
|
||||||
ut_a(n_fields + n_bytes > 0);
|
/* NOTE: The fields of block must not be accessed after
|
||||||
|
releasing btr_search_latch, as the index page might only
|
||||||
|
be s-latched! */
|
||||||
|
|
||||||
rw_lock_s_unlock(&btr_search_latch);
|
rw_lock_s_unlock(&btr_search_latch);
|
||||||
|
|
||||||
|
ut_a(n_fields + n_bytes > 0);
|
||||||
|
|
||||||
n_recs = page_get_n_recs(page);
|
n_recs = page_get_n_recs(page);
|
||||||
|
|
||||||
/* Calculate and cache fold values into an array for fast deletion
|
/* Calculate and cache fold values into an array for fast deletion
|
||||||
@@ -949,14 +955,6 @@ btr_search_drop_page_hash_index(
|
|||||||
rec = page_get_infimum_rec(page);
|
rec = page_get_infimum_rec(page);
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next(rec);
|
||||||
|
|
||||||
if (!page_rec_is_supremum(rec)) {
|
|
||||||
ut_a(n_fields <= rec_get_n_fields(rec, block->index));
|
|
||||||
|
|
||||||
if (n_bytes > 0) {
|
|
||||||
ut_a(n_fields < rec_get_n_fields(rec, block->index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tree_id = btr_page_get_index_id(page);
|
tree_id = btr_page_get_index_id(page);
|
||||||
|
|
||||||
prev_fold = 0;
|
prev_fold = 0;
|
||||||
@@ -964,18 +962,12 @@ btr_search_drop_page_hash_index(
|
|||||||
heap = NULL;
|
heap = NULL;
|
||||||
offsets = NULL;
|
offsets = NULL;
|
||||||
|
|
||||||
if (block->index == NULL) {
|
|
||||||
|
|
||||||
mem_analyze_corruption((byte*)block);
|
|
||||||
|
|
||||||
ut_a(block->index != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!page_rec_is_supremum(rec)) {
|
while (!page_rec_is_supremum(rec)) {
|
||||||
/* FIXME: in a mixed tree, not all records may have enough
|
/* FIXME: in a mixed tree, not all records may have enough
|
||||||
ordering fields: */
|
ordering fields: */
|
||||||
offsets = rec_get_offsets(rec, block->index,
|
offsets = rec_get_offsets(rec, index, offsets,
|
||||||
offsets, n_fields + (n_bytes > 0), &heap);
|
n_fields + (n_bytes > 0), &heap);
|
||||||
|
ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
|
||||||
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
|
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
|
||||||
|
|
||||||
if (fold == prev_fold && prev_fold != 0) {
|
if (fold == prev_fold && prev_fold != 0) {
|
||||||
|
@@ -2104,8 +2104,11 @@ dict_foreign_find_index(
|
|||||||
dict_table_t* table, /* in: table */
|
dict_table_t* table, /* in: table */
|
||||||
const char** columns,/* in: array of column names */
|
const char** columns,/* in: array of column names */
|
||||||
ulint n_cols, /* in: number of columns */
|
ulint n_cols, /* in: number of columns */
|
||||||
dict_index_t* types_idx)/* in: NULL or an index to whose types the
|
dict_index_t* types_idx, /* in: NULL or an index to whose types the
|
||||||
column types must match */
|
column types must match */
|
||||||
|
ibool check_charsets) /* in: whether to check charsets.
|
||||||
|
only has an effect if types_idx !=
|
||||||
|
NULL. */
|
||||||
{
|
{
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
@@ -2135,7 +2138,8 @@ dict_foreign_find_index(
|
|||||||
|
|
||||||
if (types_idx && !cmp_types_are_equal(
|
if (types_idx && !cmp_types_are_equal(
|
||||||
dict_index_get_nth_type(index, i),
|
dict_index_get_nth_type(index, i),
|
||||||
dict_index_get_nth_type(types_idx, i))) {
|
dict_index_get_nth_type(types_idx, i),
|
||||||
|
check_charsets)) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2212,7 +2216,8 @@ dict_foreign_add_to_cache(
|
|||||||
/*======================*/
|
/*======================*/
|
||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
dict_foreign_t* foreign, /* in, own: foreign key constraint */
|
dict_foreign_t* foreign, /* in, own: foreign key constraint */
|
||||||
ibool check_types) /* in: TRUE=check type compatibility */
|
ibool check_charsets) /* in: TRUE=check charset
|
||||||
|
compatibility */
|
||||||
{
|
{
|
||||||
dict_table_t* for_table;
|
dict_table_t* for_table;
|
||||||
dict_table_t* ref_table;
|
dict_table_t* ref_table;
|
||||||
@@ -2248,16 +2253,10 @@ dict_foreign_add_to_cache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (for_in_cache->referenced_table == NULL && ref_table) {
|
if (for_in_cache->referenced_table == NULL && ref_table) {
|
||||||
dict_index_t* types_idx;
|
|
||||||
if (check_types) {
|
|
||||||
types_idx = for_in_cache->foreign_index;
|
|
||||||
} else {
|
|
||||||
types_idx = NULL;
|
|
||||||
}
|
|
||||||
index = dict_foreign_find_index(ref_table,
|
index = dict_foreign_find_index(ref_table,
|
||||||
(const char**) for_in_cache->referenced_col_names,
|
(const char**) for_in_cache->referenced_col_names,
|
||||||
for_in_cache->n_fields,
|
for_in_cache->n_fields,
|
||||||
types_idx);
|
for_in_cache->foreign_index, check_charsets);
|
||||||
|
|
||||||
if (index == NULL) {
|
if (index == NULL) {
|
||||||
dict_foreign_error_report(ef, for_in_cache,
|
dict_foreign_error_report(ef, for_in_cache,
|
||||||
@@ -2281,16 +2280,10 @@ dict_foreign_add_to_cache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (for_in_cache->foreign_table == NULL && for_table) {
|
if (for_in_cache->foreign_table == NULL && for_table) {
|
||||||
dict_index_t* types_idx;
|
|
||||||
if (check_types) {
|
|
||||||
types_idx = for_in_cache->referenced_index;
|
|
||||||
} else {
|
|
||||||
types_idx = NULL;
|
|
||||||
}
|
|
||||||
index = dict_foreign_find_index(for_table,
|
index = dict_foreign_find_index(for_table,
|
||||||
(const char**) for_in_cache->foreign_col_names,
|
(const char**) for_in_cache->foreign_col_names,
|
||||||
for_in_cache->n_fields,
|
for_in_cache->n_fields,
|
||||||
types_idx);
|
for_in_cache->referenced_index, check_charsets);
|
||||||
|
|
||||||
if (index == NULL) {
|
if (index == NULL) {
|
||||||
dict_foreign_error_report(ef, for_in_cache,
|
dict_foreign_error_report(ef, for_in_cache,
|
||||||
@@ -3097,7 +3090,7 @@ col_loop1:
|
|||||||
/* Try to find an index which contains the columns
|
/* Try to find an index which contains the columns
|
||||||
as the first fields and in the right order */
|
as the first fields and in the right order */
|
||||||
|
|
||||||
index = dict_foreign_find_index(table, column_names, i, NULL);
|
index = dict_foreign_find_index(table, column_names, i, NULL, TRUE);
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
@@ -3362,8 +3355,7 @@ try_find_index:
|
|||||||
|
|
||||||
if (referenced_table) {
|
if (referenced_table) {
|
||||||
index = dict_foreign_find_index(referenced_table,
|
index = dict_foreign_find_index(referenced_table,
|
||||||
column_names, i,
|
column_names, i, foreign->foreign_index, TRUE);
|
||||||
foreign->foreign_index);
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
dict_foreign_free(foreign);
|
dict_foreign_free(foreign);
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
|
@@ -1091,7 +1091,7 @@ dict_load_foreign(
|
|||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
const char* id, /* in: foreign constraint id as a
|
const char* id, /* in: foreign constraint id as a
|
||||||
null-terminated string */
|
null-terminated string */
|
||||||
ibool check_types)/* in: TRUE=check type compatibility */
|
ibool check_charsets)/* in: TRUE=check charset compatibility */
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
dict_table_t* sys_foreign;
|
dict_table_t* sys_foreign;
|
||||||
@@ -1204,7 +1204,7 @@ dict_load_foreign(
|
|||||||
a new foreign key constraint but loading one from the data
|
a new foreign key constraint but loading one from the data
|
||||||
dictionary. */
|
dictionary. */
|
||||||
|
|
||||||
return(dict_foreign_add_to_cache(foreign, check_types));
|
return(dict_foreign_add_to_cache(foreign, check_charsets));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@@ -1219,7 +1219,8 @@ dict_load_foreigns(
|
|||||||
/*===============*/
|
/*===============*/
|
||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
const char* table_name, /* in: table name */
|
const char* table_name, /* in: table name */
|
||||||
ibool check_types) /* in: TRUE=check type compatibility */
|
ibool check_charsets) /* in: TRUE=check charset
|
||||||
|
compatibility */
|
||||||
{
|
{
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
@@ -1319,7 +1320,7 @@ loop:
|
|||||||
|
|
||||||
/* Load the foreign constraint definition to the dictionary cache */
|
/* Load the foreign constraint definition to the dictionary cache */
|
||||||
|
|
||||||
err = dict_load_foreign(id, check_types);
|
err = dict_load_foreign(id, check_charsets);
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
btr_pcur_close(&pcur);
|
btr_pcur_close(&pcur);
|
||||||
|
@@ -745,8 +745,6 @@ struct buf_block_struct{
|
|||||||
buffer pool which are index pages,
|
buffer pool which are index pages,
|
||||||
but this flag is not set because
|
but this flag is not set because
|
||||||
we do not keep track of all pages */
|
we do not keep track of all pages */
|
||||||
dict_index_t* index; /* index for which the adaptive
|
|
||||||
hash index has been created */
|
|
||||||
/* 2. Page flushing fields */
|
/* 2. Page flushing fields */
|
||||||
|
|
||||||
UT_LIST_NODE_T(buf_block_t) flush_list;
|
UT_LIST_NODE_T(buf_block_t) flush_list;
|
||||||
@@ -833,7 +831,7 @@ struct buf_block_struct{
|
|||||||
records with the same prefix should be
|
records with the same prefix should be
|
||||||
indexed in the hash index */
|
indexed in the hash index */
|
||||||
|
|
||||||
/* The following 4 fields are protected by btr_search_latch: */
|
/* The following 6 fields are protected by btr_search_latch: */
|
||||||
|
|
||||||
ibool is_hashed; /* TRUE if hash index has already been
|
ibool is_hashed; /* TRUE if hash index has already been
|
||||||
built on this page; note that it does
|
built on this page; note that it does
|
||||||
@@ -850,6 +848,12 @@ struct buf_block_struct{
|
|||||||
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
|
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
|
||||||
BTR_SEARCH_RIGHT_SIDE in hash
|
BTR_SEARCH_RIGHT_SIDE in hash
|
||||||
indexing */
|
indexing */
|
||||||
|
dict_index_t* index; /* Index for which the adaptive
|
||||||
|
hash index has been created.
|
||||||
|
This field may only be modified
|
||||||
|
while holding an s-latch or x-latch
|
||||||
|
on block->lock and an x-latch on
|
||||||
|
btr_search_latch. */
|
||||||
/* 6. Debug fields */
|
/* 6. Debug fields */
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
rw_lock_t debug_latch; /* in the debug version, each thread
|
rw_lock_t debug_latch; /* in the debug version, each thread
|
||||||
|
@@ -197,7 +197,8 @@ dict_foreign_add_to_cache(
|
|||||||
/*======================*/
|
/*======================*/
|
||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
dict_foreign_t* foreign, /* in, own: foreign key constraint */
|
dict_foreign_t* foreign, /* in, own: foreign key constraint */
|
||||||
ibool check_types); /* in: TRUE=check type compatibility */
|
ibool check_charsets);/* in: TRUE=check charset
|
||||||
|
compatibility */
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Checks if a table is referenced by foreign keys. */
|
Checks if a table is referenced by foreign keys. */
|
||||||
|
|
||||||
|
@@ -82,7 +82,8 @@ dict_load_foreigns(
|
|||||||
/*===============*/
|
/*===============*/
|
||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
const char* table_name, /* in: table name */
|
const char* table_name, /* in: table name */
|
||||||
ibool check_types); /* in: TRUE=check type compatibility */
|
ibool check_charsets);/* in: TRUE=check charsets
|
||||||
|
compatibility */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Prints to the standard output information on all tables found in the data
|
Prints to the standard output information on all tables found in the data
|
||||||
dictionary system table. */
|
dictionary system table. */
|
||||||
|
@@ -24,7 +24,8 @@ cmp_types_are_equal(
|
|||||||
/* out: TRUE if the types are considered
|
/* out: TRUE if the types are considered
|
||||||
equal in comparisons */
|
equal in comparisons */
|
||||||
dtype_t* type1, /* in: type 1 */
|
dtype_t* type1, /* in: type 1 */
|
||||||
dtype_t* type2); /* in: type 2 */
|
dtype_t* type2, /* in: type 2 */
|
||||||
|
ibool check_charsets); /* in: whether to check charsets */
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
This function is used to compare two data fields for which we know the
|
This function is used to compare two data fields for which we know the
|
||||||
data type. */
|
data type. */
|
||||||
|
@@ -99,7 +99,8 @@ cmp_types_are_equal(
|
|||||||
/* out: TRUE if the types are considered
|
/* out: TRUE if the types are considered
|
||||||
equal in comparisons */
|
equal in comparisons */
|
||||||
dtype_t* type1, /* in: type 1 */
|
dtype_t* type1, /* in: type 1 */
|
||||||
dtype_t* type2) /* in: type 2 */
|
dtype_t* type2, /* in: type 2 */
|
||||||
|
ibool check_charsets) /* in: whether to check charsets */
|
||||||
{
|
{
|
||||||
if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
|
if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
|
||||||
&& dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
|
&& dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
|
||||||
@@ -107,12 +108,12 @@ cmp_types_are_equal(
|
|||||||
/* Both are non-binary string types: they can be compared if
|
/* Both are non-binary string types: they can be compared if
|
||||||
and only if the charset-collation is the same */
|
and only if the charset-collation is the same */
|
||||||
|
|
||||||
if (dtype_get_charset_coll(type1->prtype)
|
if (check_charsets) {
|
||||||
== dtype_get_charset_coll(type2->prtype)) {
|
return(dtype_get_charset_coll(type1->prtype)
|
||||||
|
== dtype_get_charset_coll(type2->prtype));
|
||||||
|
} else {
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
|
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
|
||||||
|
@@ -2132,7 +2132,7 @@ row_table_add_foreign_constraints(
|
|||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
/* Check that also referencing constraints are ok */
|
/* Check that also referencing constraints are ok */
|
||||||
err = dict_load_foreigns(name, trx->check_foreigns);
|
err = dict_load_foreigns(name, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
@@ -3591,6 +3591,7 @@ row_rename_table_for_mysql(
|
|||||||
const char** constraints_to_drop = NULL;
|
const char** constraints_to_drop = NULL;
|
||||||
ulint n_constraints_to_drop = 0;
|
ulint n_constraints_to_drop = 0;
|
||||||
ibool recovering_temp_table = FALSE;
|
ibool recovering_temp_table = FALSE;
|
||||||
|
ibool old_is_tmp, new_is_tmp;
|
||||||
ulint len;
|
ulint len;
|
||||||
ulint i;
|
ulint i;
|
||||||
ibool success;
|
ibool success;
|
||||||
@@ -3630,6 +3631,9 @@ row_rename_table_for_mysql(
|
|||||||
trx->op_info = "renaming table";
|
trx->op_info = "renaming table";
|
||||||
trx_start_if_not_started(trx);
|
trx_start_if_not_started(trx);
|
||||||
|
|
||||||
|
old_is_tmp = row_is_mysql_tmp_table_name(old_name);
|
||||||
|
new_is_tmp = row_is_mysql_tmp_table_name(new_name);
|
||||||
|
|
||||||
if (row_mysql_is_recovered_tmp_table(new_name)) {
|
if (row_mysql_is_recovered_tmp_table(new_name)) {
|
||||||
|
|
||||||
recovering_temp_table = TRUE;
|
recovering_temp_table = TRUE;
|
||||||
@@ -3676,7 +3680,7 @@ row_rename_table_for_mysql(
|
|||||||
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
|
len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4
|
||||||
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
|
+ ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\'');
|
||||||
|
|
||||||
if (row_is_mysql_tmp_table_name(new_name)) {
|
if (new_is_tmp) {
|
||||||
db_name_len = dict_get_db_name_len(old_name) + 1;
|
db_name_len = dict_get_db_name_len(old_name) + 1;
|
||||||
|
|
||||||
/* MySQL is doing an ALTER TABLE command and it renames the
|
/* MySQL is doing an ALTER TABLE command and it renames the
|
||||||
@@ -3829,7 +3833,7 @@ row_rename_table_for_mysql(
|
|||||||
the table is stored in a single-table tablespace */
|
the table is stored in a single-table tablespace */
|
||||||
|
|
||||||
success = dict_table_rename_in_cache(table, new_name,
|
success = dict_table_rename_in_cache(table, new_name,
|
||||||
!row_is_mysql_tmp_table_name(new_name));
|
!new_is_tmp);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||||
@@ -3846,19 +3850,16 @@ row_rename_table_for_mysql(
|
|||||||
goto funct_exit;
|
goto funct_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dict_load_foreigns(new_name, trx->check_foreigns);
|
/* We only want to switch off some of the type checking in
|
||||||
|
an ALTER, not in a RENAME. */
|
||||||
|
|
||||||
if (row_is_mysql_tmp_table_name(old_name)) {
|
err = dict_load_foreigns(new_name,
|
||||||
|
old_is_tmp ? trx->check_foreigns : TRUE);
|
||||||
/* MySQL is doing an ALTER TABLE command and it
|
|
||||||
renames the created temporary table to the name
|
|
||||||
of the original table. In the ALTER TABLE we maybe
|
|
||||||
created some FOREIGN KEY constraints for the temporary
|
|
||||||
table. But we want to load also the foreign key
|
|
||||||
constraint definitions for the original table name. */
|
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
|
if (old_is_tmp) {
|
||||||
fputs(" InnoDB: Error: in ALTER TABLE ",
|
fputs(" InnoDB: Error: in ALTER TABLE ",
|
||||||
stderr);
|
stderr);
|
||||||
ut_print_name(stderr, trx, new_name);
|
ut_print_name(stderr, trx, new_name);
|
||||||
@@ -3866,19 +3867,7 @@ row_rename_table_for_mysql(
|
|||||||
"InnoDB: has or is referenced in foreign key constraints\n"
|
"InnoDB: has or is referenced in foreign key constraints\n"
|
||||||
"InnoDB: which are not compatible with the new table definition.\n",
|
"InnoDB: which are not compatible with the new table definition.\n",
|
||||||
stderr);
|
stderr);
|
||||||
|
|
||||||
ut_a(dict_table_rename_in_cache(table,
|
|
||||||
old_name, FALSE));
|
|
||||||
trx->error_state = DB_SUCCESS;
|
|
||||||
trx_general_rollback_for_mysql(trx, FALSE,
|
|
||||||
NULL);
|
|
||||||
trx->error_state = DB_SUCCESS;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (err != DB_SUCCESS) {
|
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
|
||||||
|
|
||||||
fputs(
|
fputs(
|
||||||
" InnoDB: Error: in RENAME TABLE table ",
|
" InnoDB: Error: in RENAME TABLE table ",
|
||||||
stderr);
|
stderr);
|
||||||
@@ -3887,17 +3876,16 @@ row_rename_table_for_mysql(
|
|||||||
"InnoDB: is referenced in foreign key constraints\n"
|
"InnoDB: is referenced in foreign key constraints\n"
|
||||||
"InnoDB: which are not compatible with the new table definition.\n",
|
"InnoDB: which are not compatible with the new table definition.\n",
|
||||||
stderr);
|
stderr);
|
||||||
|
}
|
||||||
|
|
||||||
ut_a(dict_table_rename_in_cache(table,
|
ut_a(dict_table_rename_in_cache(table,
|
||||||
old_name, FALSE));
|
old_name, FALSE));
|
||||||
|
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
trx_general_rollback_for_mysql(trx, FALSE,
|
trx_general_rollback_for_mysql(trx, FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
funct_exit:
|
funct_exit:
|
||||||
if (!recovering_temp_table) {
|
if (!recovering_temp_table) {
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
@@ -2043,19 +2043,22 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) {
|
|||||||
|
|
||||||
ApiVersionConf * conf = (ApiVersionConf *)req;
|
ApiVersionConf * conf = (ApiVersionConf *)req;
|
||||||
if(getNodeInfo(nodeId).m_connected)
|
if(getNodeInfo(nodeId).m_connected)
|
||||||
|
{
|
||||||
conf->version = getNodeInfo(nodeId).m_version;
|
conf->version = getNodeInfo(nodeId).m_version;
|
||||||
else
|
|
||||||
conf->version = 0;
|
|
||||||
conf->nodeId = nodeId;
|
|
||||||
struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
|
struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
|
||||||
conf->inet_addr= in.s_addr;
|
conf->inet_addr= in.s_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conf->version = 0;
|
||||||
|
conf->inet_addr= 0;
|
||||||
|
}
|
||||||
|
conf->nodeId = nodeId;
|
||||||
|
|
||||||
sendSignal(senderRef,
|
sendSignal(senderRef,
|
||||||
GSN_API_VERSION_CONF,
|
GSN_API_VERSION_CONF,
|
||||||
signal,
|
signal,
|
||||||
ApiVersionConf::SignalLength, JBB);
|
ApiVersionConf::SignalLength, JBB);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user