mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Merge tsmith@bk-internal.mysql.com:/home/bk/mysql-5.0-runtime
into quadxeon.mysql.com:/benchmarks/ext3/TOSAVE/tsmith/bk/maint/mrg0306/50
This commit is contained in:
commit
a15fe85de2
55 changed files with 2117 additions and 210 deletions
|
@ -3043,6 +3043,7 @@ language = $path_language
|
|||
character-sets-dir = $path_charsetsdir
|
||||
basedir = $path_my_basedir
|
||||
server_id = $server_id
|
||||
shutdown-delay = 10
|
||||
skip-stack-trace
|
||||
skip-innodb
|
||||
skip-ndbcluster
|
||||
|
|
|
@ -128,3 +128,6 @@ f1 f2 if(f1, 40.0, 5.00)
|
|||
0 0 5.00
|
||||
1 1 40.00
|
||||
drop table t1;
|
||||
select if(0, 18446744073709551610, 18446744073709551610);
|
||||
if(0, 18446744073709551610, 18446744073709551610)
|
||||
18446744073709551610
|
||||
|
|
|
@ -141,4 +141,48 @@ t1 CREATE TABLE `t1` (
|
|||
`a` bigint(21) unsigned default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
drop table if exists table_26093;
|
||||
drop function if exists func_26093_a;
|
||||
drop function if exists func_26093_b;
|
||||
create table table_26093(a int);
|
||||
insert into table_26093 values
|
||||
(1), (2), (3), (4), (5),
|
||||
(6), (7), (8), (9), (10);
|
||||
create function func_26093_a(x int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
create function func_26093_b(x int, y int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
select avg(a) from table_26093;
|
||||
avg(a)
|
||||
5.5000
|
||||
select benchmark(100, (select avg(a) from table_26093));
|
||||
benchmark(100, (select avg(a) from table_26093))
|
||||
0
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
|
||||
benchmark(100, (select avg(func_26093_a(a)) from table_26093))
|
||||
0
|
||||
select @invoked;
|
||||
@invoked
|
||||
10
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
|
||||
benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093))
|
||||
0
|
||||
select @invoked;
|
||||
@invoked
|
||||
1000
|
||||
select benchmark(100, (select (a) from table_26093));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
select benchmark(100, (select 1, 1));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop table table_26093;
|
||||
drop function func_26093_a;
|
||||
drop function func_26093_b;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -21,6 +21,6 @@ Success: the process was restarted.
|
|||
Success: server is ready to accept connection on socket.
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
instance_name status version
|
||||
mysqld1 online VERSION
|
||||
mysqld1 STATE VERSION
|
||||
STOP INSTANCE mysqld2;
|
||||
Success: the process has been stopped.
|
||||
|
|
|
@ -87,13 +87,13 @@ where table_schema='test';
|
|||
table_name table_type table_comment
|
||||
t1 BASE TABLE
|
||||
v1 VIEW VIEW
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
v2 VIEW VIEW
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
table_name table_type table_comment
|
||||
v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
v1 VIEW VIEW
|
||||
v2 VIEW VIEW
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop view v1, v2;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
SELECT * INTO @X FROM init_file.startup limit 0,1;
|
||||
SELECT * INTO @Y FROM init_file.startup limit 1,1;
|
||||
SELECT YEAR(@X)-YEAR(@Y);
|
||||
YEAR(@X)-YEAR(@Y)
|
||||
0
|
||||
DROP DATABASE init_file;
|
||||
ok
|
||||
end of 4.1 tests
|
||||
select * from t1;
|
||||
|
|
|
@ -1128,9 +1128,9 @@ drop view if exists v1, v2, v3, v4;
|
|||
create function bug11555_1() returns int return (select max(i) from t1);
|
||||
create function bug11555_2() returns int return bug11555_1();
|
||||
create view v1 as select bug11555_1();
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
drop view v1;
|
||||
create view v2 as select bug11555_2();
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
drop view v2;
|
||||
create table t1 (i int);
|
||||
create view v1 as select bug11555_1();
|
||||
create view v2 as select bug11555_2();
|
||||
|
@ -1143,8 +1143,7 @@ ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function
|
|||
select * from v3;
|
||||
ERROR HY000: View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
create view v4 as select * from v1;
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
drop view v1, v2, v3;
|
||||
drop view v1, v2, v3, v4;
|
||||
drop function bug11555_1;
|
||||
drop function bug11555_2;
|
||||
create table t1 (i int);
|
||||
|
@ -1153,12 +1152,12 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new.
|
|||
create view v1 as select * from t1;
|
||||
drop table t2;
|
||||
insert into v1 values (1);
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
||||
drop trigger t1_ai;
|
||||
create function bug11555_1() returns int return (select max(i) from t2);
|
||||
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
|
||||
insert into v1 values (2);
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
||||
drop function bug11555_1;
|
||||
drop table t1;
|
||||
drop view v1;
|
||||
|
@ -1269,3 +1268,135 @@ call bug24491();
|
|||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f2;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p1;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p2;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE PROCEDURE bug18914_p1() CREATE TABLE t2 (i INT);
|
||||
CREATE PROCEDURE bug18914_p2() DROP TABLE IF EXISTS no_such_table;
|
||||
CREATE FUNCTION bug18914_f1() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p1();
|
||||
RETURN 1;
|
||||
END |
|
||||
CREATE FUNCTION bug18914_f2() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p2();
|
||||
RETURN 1;
|
||||
END |
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL bug18914_p1();
|
||||
INSERT INTO t1 VALUES (1);
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT bug18914_f1();
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT bug18914_f2();
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT * FROM t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
DROP FUNCTION bug18914_f1;
|
||||
DROP FUNCTION bug18914_f2;
|
||||
DROP PROCEDURE bug18914_p1;
|
||||
DROP PROCEDURE bug18914_p2;
|
||||
DROP TABLE t1;
|
||||
drop table if exists bogus_table_20713;
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
create table bogus_table_20713( id int(10) not null primary key);
|
||||
insert into bogus_table_20713 values (1), (2), (3);
|
||||
create function func_20713_a() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
declare continue handler for sqlexception set id=null;
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
return id;
|
||||
end//
|
||||
create function func_20713_b() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
declare continue handler for sqlstate value '42S02' set id=null;
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
return id;
|
||||
end//
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
func_20713_a()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
func_20713_b()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
drop table bogus_table_20713;
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
func_20713_a()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
func_20713_b()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
drop table if exists table_25345_a;
|
||||
drop table if exists table_25345_b;
|
||||
drop procedure if exists proc_25345;
|
||||
drop function if exists func_25345;
|
||||
drop function if exists func_25345_b;
|
||||
create table table_25345_a (a int);
|
||||
create table table_25345_b (b int);
|
||||
create procedure proc_25345()
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
select 1 as result;
|
||||
end ||
|
||||
create function func_25345() returns int(11)
|
||||
begin
|
||||
call proc_25345();
|
||||
return 1;
|
||||
end ||
|
||||
create function func_25345_b() returns int(11)
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
return 1;
|
||||
end ||
|
||||
call proc_25345();
|
||||
result
|
||||
1
|
||||
select func_25345();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
select func_25345_b();
|
||||
func_25345_b()
|
||||
1
|
||||
drop table table_25345_a;
|
||||
call proc_25345();
|
||||
result
|
||||
1
|
||||
select func_25345();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
select func_25345_b();
|
||||
func_25345_b()
|
||||
1
|
||||
drop table table_25345_b;
|
||||
drop procedure proc_25345;
|
||||
drop function func_25345;
|
||||
drop function func_25345_b;
|
||||
|
|
|
@ -431,17 +431,17 @@ SELECT HEX(v10);
|
|||
END|
|
||||
CALL p1();
|
||||
HEX(v1)
|
||||
01
|
||||
1
|
||||
HEX(v2)
|
||||
00
|
||||
0
|
||||
HEX(v3)
|
||||
05
|
||||
5
|
||||
HEX(v4)
|
||||
5555555555555555
|
||||
HEX(v5)
|
||||
07
|
||||
7
|
||||
HEX(v6)
|
||||
0000000000000005
|
||||
5
|
||||
HEX(v7)
|
||||
80
|
||||
HEX(v8)
|
||||
|
@ -748,12 +748,60 @@ HEX(b) b = 0 b = FALSE b IS FALSE b = 1 b = TRUE b IS TRUE
|
|||
1 0 0 0 1 1 1
|
||||
call p2();
|
||||
HEX(vb) vb = 0 vb = FALSE vb IS FALSE vb = 1 vb = TRUE vb IS TRUE
|
||||
00 1 1 1 0 0 0
|
||||
0 1 1 1 0 0 0
|
||||
HEX(vb) vb = 0 vb = FALSE vb IS FALSE vb = 1 vb = TRUE vb IS TRUE
|
||||
01 0 0 1 1 1 0
|
||||
1 0 0 0 1 1 1
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
DROP TABLE IF EXISTS table_12976_a;
|
||||
DROP TABLE IF EXISTS table_12976_b;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_a;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_b;
|
||||
CREATE TABLE table_12976_a (val bit(1));
|
||||
CREATE TABLE table_12976_b(
|
||||
appname varchar(15),
|
||||
emailperm bit not null default 1,
|
||||
phoneperm bit not null default 0);
|
||||
insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0');
|
||||
CREATE PROCEDURE proc_12976_a()
|
||||
BEGIN
|
||||
declare localvar bit(1);
|
||||
SELECT val INTO localvar FROM table_12976_a;
|
||||
SELECT coalesce(localvar, 1)+1, coalesce(val, 1)+1 FROM table_12976_a;
|
||||
END||
|
||||
CREATE PROCEDURE proc_12976_b(
|
||||
name varchar(15),
|
||||
out ep bit,
|
||||
out msg varchar(10))
|
||||
BEGIN
|
||||
SELECT emailperm into ep FROM table_12976_b where (appname = name);
|
||||
IF ep is true THEN
|
||||
SET msg = 'True';
|
||||
ELSE
|
||||
SET msg = 'False';
|
||||
END IF;
|
||||
END||
|
||||
INSERT table_12976_a VALUES (0);
|
||||
call proc_12976_a();
|
||||
coalesce(localvar, 1)+1 coalesce(val, 1)+1
|
||||
1 1
|
||||
UPDATE table_12976_a set val=1;
|
||||
call proc_12976_a();
|
||||
coalesce(localvar, 1)+1 coalesce(val, 1)+1
|
||||
2 2
|
||||
call proc_12976_b('A', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
@ep @msg
|
||||
1 True
|
||||
call proc_12976_b('B', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
@ep @msg
|
||||
0 False
|
||||
DROP TABLE table_12976_a;
|
||||
DROP TABLE table_12976_b;
|
||||
DROP PROCEDURE proc_12976_a;
|
||||
DROP PROCEDURE proc_12976_b;
|
||||
|
||||
---------------------------------------------------------------
|
||||
BUG#9572
|
||||
|
|
|
@ -1155,9 +1155,13 @@ create function f12_2() returns int
|
|||
return (select count(*) from t3)|
|
||||
drop temporary table t3|
|
||||
select f12_1()|
|
||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||
f12_1()
|
||||
3
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't3'
|
||||
select f12_1() from t1 limit 1|
|
||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||
f12_1()
|
||||
3
|
||||
drop function f0|
|
||||
drop function f1|
|
||||
drop function f2|
|
||||
|
@ -5727,4 +5731,38 @@ END|
|
|||
CALL bug24117()|
|
||||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
drop function if exists func_8407_a|
|
||||
drop function if exists func_8407_b|
|
||||
create function func_8407_a() returns int
|
||||
begin
|
||||
declare x int;
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
end;
|
||||
select 1 from no_such_view limit 1 into x;
|
||||
return x;
|
||||
end|
|
||||
create function func_8407_b() returns int
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S02'
|
||||
begin
|
||||
set x:= x+1000;
|
||||
end;
|
||||
case (select 1 from no_such_view limit 1)
|
||||
when 1 then set x:= x+1;
|
||||
when 2 then set x:= x+2;
|
||||
else set x:= x+100;
|
||||
end case;
|
||||
set x:=x + 500;
|
||||
return x;
|
||||
end|
|
||||
select func_8407_a()|
|
||||
func_8407_a()
|
||||
NULL
|
||||
select func_8407_b()|
|
||||
func_8407_b()
|
||||
1500
|
||||
drop function func_8407_a|
|
||||
drop function func_8407_b|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -3095,7 +3095,7 @@ SELECT a FROM t1 GROUP BY a
|
|||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
|
@ -3103,11 +3103,11 @@ a
|
|||
4
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
|
@ -3115,7 +3115,7 @@ a
|
|||
1
|
||||
3
|
||||
4
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
|
@ -3683,16 +3683,16 @@ CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
|||
CREATE TABLE t2 (c int);
|
||||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
|
@ -3702,9 +3702,9 @@ dd 1
|
|||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
INSERT INTO t3 VALUES (1);
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
|
@ -3754,3 +3754,116 @@ a MAX(b) test
|
|||
2 3 h
|
||||
3 4 i
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t1xt2;
|
||||
CREATE TABLE t1 (
|
||||
id_1 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id_2 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE t1xt2 (
|
||||
id_1 int(5) NOT NULL,
|
||||
id_2 int(5) NOT NULL
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
|
||||
INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
|
||||
INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
insert INTO t1xt2 VALUES (1, 12);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
insert INTO t1xt2 VALUES (2, 12);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1xt2;
|
||||
|
|
|
@ -1335,4 +1335,41 @@ SELECT fubar_id FROM t2;
|
|||
fubar_id
|
||||
1
|
||||
DROP TABLE t1,t2;
|
||||
DROP TABLE IF EXISTS bug21825_A;
|
||||
DROP TABLE IF EXISTS bug21825_B;
|
||||
CREATE TABLE bug21825_A (id int(10));
|
||||
CREATE TABLE bug21825_B (id int(10));
|
||||
CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO bug21825_B (id) values (1);
|
||||
END//
|
||||
INSERT INTO bug21825_A (id) VALUES (10);
|
||||
INSERT INTO bug21825_A (id) VALUES (20);
|
||||
DROP TABLE bug21825_B;
|
||||
DELETE FROM bug21825_A WHERE id = 20;
|
||||
DROP TABLE bug21825_A;
|
||||
DROP TABLE IF EXISTS bug22580_t1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_2;
|
||||
CREATE TABLE bug22580_t1 (a INT, b INT);
|
||||
CREATE PROCEDURE bug22580_proc_2()
|
||||
BEGIN
|
||||
DROP TABLE IF EXISTS bug22580_tmp;
|
||||
CREATE TEMPORARY TABLE bug22580_tmp (a INT);
|
||||
DROP TABLE bug22580_tmp;
|
||||
END||
|
||||
CREATE PROCEDURE bug22580_proc_1()
|
||||
BEGIN
|
||||
CALL bug22580_proc_2();
|
||||
END||
|
||||
CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL bug22580_proc_1();
|
||||
END||
|
||||
INSERT INTO bug22580_t1 VALUES (1,1);
|
||||
DROP TABLE bug22580_t1;
|
||||
DROP PROCEDURE bug22580_proc_1;
|
||||
DROP PROCEDURE bug22580_proc_2;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -834,14 +834,16 @@ show create view v1;
|
|||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
|
||||
drop view v1;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
cü
|
||||
ü
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names utf8;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
cü
|
||||
ü
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names latin1;
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
||||
create view v1(c) as select a+1 from t1 where b >= 4;
|
||||
|
@ -1933,11 +1935,11 @@ create function f1 () returns int return (select max(col1) from t1);
|
|||
DROP TABLE t1;
|
||||
CHECK TABLE v1, v2, v3, v4, v5, v6;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v1 check status OK
|
||||
test.v2 check status OK
|
||||
test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v3 check status OK
|
||||
test.v4 check status OK
|
||||
test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v5 check status OK
|
||||
test.v6 check status OK
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
|
@ -3035,7 +3037,7 @@ View Create View
|
|||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
|
||||
DROP VIEW v1;
|
||||
CREATE TABLE t1 (mydate DATETIME);
|
||||
INSERT INTO t1 VALUES
|
||||
INSERT INTO t1 VALUES
|
||||
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||
SELECT * FROM t1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||
|
@ -3135,4 +3137,139 @@ code COUNT(DISTINCT country)
|
|||
100 2
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
SELECT * FROM (SELECT 1) AS t;
|
||||
1
|
||||
1
|
||||
CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t;
|
||||
ERROR HY000: View's SELECT contains a subquery in the FROM clause
|
||||
# Previously the following would fail.
|
||||
SELECT * FROM (SELECT 1) AS t;
|
||||
1
|
||||
1
|
||||
drop view if exists view_24532_a;
|
||||
drop view if exists view_24532_b;
|
||||
drop table if exists table_24532;
|
||||
create table table_24532 (
|
||||
a int,
|
||||
b bigint,
|
||||
c int(4),
|
||||
d bigint(48)
|
||||
);
|
||||
create view view_24532_a as
|
||||
select
|
||||
a IS TRUE,
|
||||
a IS NOT TRUE,
|
||||
a IS FALSE,
|
||||
a IS NOT FALSE,
|
||||
a IS UNKNOWN,
|
||||
a IS NOT UNKNOWN,
|
||||
a is NULL,
|
||||
a IS NOT NULL,
|
||||
ISNULL(a),
|
||||
b IS TRUE,
|
||||
b IS NOT TRUE,
|
||||
b IS FALSE,
|
||||
b IS NOT FALSE,
|
||||
b IS UNKNOWN,
|
||||
b IS NOT UNKNOWN,
|
||||
b is NULL,
|
||||
b IS NOT NULL,
|
||||
ISNULL(b),
|
||||
c IS TRUE,
|
||||
c IS NOT TRUE,
|
||||
c IS FALSE,
|
||||
c IS NOT FALSE,
|
||||
c IS UNKNOWN,
|
||||
c IS NOT UNKNOWN,
|
||||
c is NULL,
|
||||
c IS NOT NULL,
|
||||
ISNULL(c),
|
||||
d IS TRUE,
|
||||
d IS NOT TRUE,
|
||||
d IS FALSE,
|
||||
d IS NOT FALSE,
|
||||
d IS UNKNOWN,
|
||||
d IS NOT UNKNOWN,
|
||||
d is NULL,
|
||||
d IS NOT NULL,
|
||||
ISNULL(d)
|
||||
from table_24532;
|
||||
describe view_24532_a;
|
||||
Field Type Null Key Default Extra
|
||||
a IS TRUE int(1) NO 0
|
||||
a IS NOT TRUE int(1) NO 0
|
||||
a IS FALSE int(1) NO 0
|
||||
a IS NOT FALSE int(1) NO 0
|
||||
a IS UNKNOWN int(1) NO 0
|
||||
a IS NOT UNKNOWN int(1) NO 0
|
||||
a is NULL int(1) NO 0
|
||||
a IS NOT NULL int(1) NO 0
|
||||
ISNULL(a) int(1) NO 0
|
||||
b IS TRUE int(1) NO 0
|
||||
b IS NOT TRUE int(1) NO 0
|
||||
b IS FALSE int(1) NO 0
|
||||
b IS NOT FALSE int(1) NO 0
|
||||
b IS UNKNOWN int(1) NO 0
|
||||
b IS NOT UNKNOWN int(1) NO 0
|
||||
b is NULL int(1) NO 0
|
||||
b IS NOT NULL int(1) NO 0
|
||||
ISNULL(b) int(1) NO 0
|
||||
c IS TRUE int(1) NO 0
|
||||
c IS NOT TRUE int(1) NO 0
|
||||
c IS FALSE int(1) NO 0
|
||||
c IS NOT FALSE int(1) NO 0
|
||||
c IS UNKNOWN int(1) NO 0
|
||||
c IS NOT UNKNOWN int(1) NO 0
|
||||
c is NULL int(1) NO 0
|
||||
c IS NOT NULL int(1) NO 0
|
||||
ISNULL(c) int(1) NO 0
|
||||
d IS TRUE int(1) NO 0
|
||||
d IS NOT TRUE int(1) NO 0
|
||||
d IS FALSE int(1) NO 0
|
||||
d IS NOT FALSE int(1) NO 0
|
||||
d IS UNKNOWN int(1) NO 0
|
||||
d IS NOT UNKNOWN int(1) NO 0
|
||||
d is NULL int(1) NO 0
|
||||
d IS NOT NULL int(1) NO 0
|
||||
ISNULL(d) int(1) NO 0
|
||||
create view view_24532_b as
|
||||
select
|
||||
a IS TRUE,
|
||||
if(ifnull(a, 0), 1, 0) as old_istrue,
|
||||
a IS NOT TRUE,
|
||||
if(ifnull(a, 0), 0, 1) as old_isnottrue,
|
||||
a IS FALSE,
|
||||
if(ifnull(a, 1), 0, 1) as old_isfalse,
|
||||
a IS NOT FALSE,
|
||||
if(ifnull(a, 1), 1, 0) as old_isnotfalse
|
||||
from table_24532;
|
||||
describe view_24532_b;
|
||||
Field Type Null Key Default Extra
|
||||
a IS TRUE int(1) NO 0
|
||||
old_istrue int(1) NO 0
|
||||
a IS NOT TRUE int(1) NO 0
|
||||
old_isnottrue int(1) NO 0
|
||||
a IS FALSE int(1) NO 0
|
||||
old_isfalse int(1) NO 0
|
||||
a IS NOT FALSE int(1) NO 0
|
||||
old_isnotfalse int(1) NO 0
|
||||
show create view view_24532_b;
|
||||
View Create View
|
||||
view_24532_b CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_24532_b` AS select (`table_24532`.`a` is true) AS `a IS TRUE`,if(ifnull(`table_24532`.`a`,0),1,0) AS `old_istrue`,(`table_24532`.`a` is not true) AS `a IS NOT TRUE`,if(ifnull(`table_24532`.`a`,0),0,1) AS `old_isnottrue`,(`table_24532`.`a` is false) AS `a IS FALSE`,if(ifnull(`table_24532`.`a`,1),0,1) AS `old_isfalse`,(`table_24532`.`a` is not false) AS `a IS NOT FALSE`,if(ifnull(`table_24532`.`a`,1),1,0) AS `old_isnotfalse` from `table_24532`
|
||||
insert into table_24532 values (0, 0, 0, 0);
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
0 0 1 1 1 1 0 0
|
||||
update table_24532 set a=1;
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
1 1 0 0 0 0 1 1
|
||||
update table_24532 set a=NULL;
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
0 0 1 1 0 0 1 1
|
||||
drop view view_24532_a;
|
||||
drop view view_24532_b;
|
||||
drop table table_24532;
|
||||
End of 5.0 tests.
|
||||
|
|
|
@ -27,3 +27,12 @@ insert into t2 values (11), (13);
|
|||
drop procedure p1;
|
||||
drop function f1;
|
||||
drop view v1;
|
||||
|
||||
#
|
||||
# Bug#23240 --init-file statements with NOW() reports '1970-01-01 11:00:00'as the date time
|
||||
#
|
||||
CREATE DATABASE IF NOT EXISTS init_file;
|
||||
CREATE TABLE IF NOT EXISTS init_file.startup ( startdate DATETIME );
|
||||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
im_daemon_life_cycle : Bug#24415 see note: [19 Dec 23:17] Trudy Pelzer
|
||||
ndb_load : Bug#17233
|
||||
user_limits : Bug#23921 random failure of user_limits.test
|
||||
|
|
|
@ -97,3 +97,14 @@ create table t1 (f1 int, f2 int);
|
|||
insert into t1 values(1,1),(0,0);
|
||||
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#24532 (The return data type of IS TRUE is different from similar
|
||||
# operations)
|
||||
#
|
||||
# IF(x, unsigned, unsigned) should be unsigned.
|
||||
#
|
||||
|
||||
select if(0, 18446744073709551610, 18446744073709551610);
|
||||
|
||||
|
||||
|
|
|
@ -132,4 +132,61 @@ set global query_cache_size=default;
|
|||
create table t1 select INET_ATON('255.255.0.1') as `a`;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce
|
||||
# valid results)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists table_26093;
|
||||
drop function if exists func_26093_a;
|
||||
drop function if exists func_26093_b;
|
||||
--enable_warnings
|
||||
|
||||
create table table_26093(a int);
|
||||
insert into table_26093 values
|
||||
(1), (2), (3), (4), (5),
|
||||
(6), (7), (8), (9), (10);
|
||||
|
||||
delimiter //;
|
||||
|
||||
create function func_26093_a(x int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
|
||||
create function func_26093_b(x int, y int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
select avg(a) from table_26093;
|
||||
|
||||
select benchmark(100, (select avg(a) from table_26093));
|
||||
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
|
||||
# Returns only 10, since intermediate results are cached.
|
||||
select @invoked;
|
||||
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
|
||||
# Returns 1000, due to rand() preventing caching.
|
||||
select @invoked;
|
||||
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
select benchmark(100, (select (a) from table_26093));
|
||||
|
||||
--error ER_OPERAND_COLUMNS
|
||||
select benchmark(100, (select 1, 1));
|
||||
|
||||
drop table table_26093;
|
||||
drop function func_26093_a;
|
||||
drop function func_26093_b;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -23,15 +23,20 @@
|
|||
# - wait for IM-main to start accepting connections before continue test
|
||||
# case;
|
||||
#
|
||||
# NOTE: timeout is 55 seconds. Timeout should be more than shutdown-delay
|
||||
# specified for managed MySQL instance. Now shutdown-delay is 10 seconds
|
||||
# (set in mysql-test-run.pl). So, 55 seconds should be enough to make 5
|
||||
# attempts.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Main-test: starting...
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Killing IM-main...
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Main-test: done.
|
||||
|
||||
|
@ -58,23 +63,23 @@
|
|||
START INSTANCE mysqld2;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: waiting to start...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 started im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: started.
|
||||
|
||||
# 2. Restart IM-main;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Killing IM-main...
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
|
||||
|
||||
# 3. Issue some statement -- connection should be re-established.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Checking that IM-main processing commands...
|
||||
|
||||
--replace_column 3 VERSION
|
||||
--replace_column 2 STATE 3 VERSION
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
|
||||
# 4. Stop mysqld2, because it will not be stopped by IM, as it is nonguarded.
|
||||
|
@ -85,7 +90,7 @@ SHOW INSTANCE STATUS mysqld1;
|
|||
STOP INSTANCE mysqld2;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: waiting to stop...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 stopped im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: stopped.
|
||||
|
||||
###########################################################################
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
# mysql-test/t/init_file-master.opt for the actual test
|
||||
#
|
||||
|
||||
#
|
||||
# Bug#23240 --init-file statements with NOW() reports '1970-01-01 11:00:00'as the date time
|
||||
#
|
||||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
SELECT * INTO @X FROM init_file.startup limit 0,1;
|
||||
SELECT * INTO @Y FROM init_file.startup limit 1,1;
|
||||
SELECT YEAR(@X)-YEAR(@Y);
|
||||
DROP DATABASE init_file;
|
||||
|
||||
--echo ok
|
||||
--echo end of 4.1 tests
|
||||
#
|
||||
|
|
|
@ -53,7 +53,7 @@ pid_path="$1"
|
|||
expected_result="$2"
|
||||
total_timeout="$3"
|
||||
test_id="$4"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "pid_path: '$pid_path'"
|
||||
|
|
|
@ -17,7 +17,7 @@ if [ $# -lt 2 ]; then
|
|||
fi
|
||||
|
||||
test_id="$1"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
shift
|
||||
|
||||
|
|
|
@ -1607,10 +1607,12 @@ create function bug11555_1() returns int return (select max(i) from t1);
|
|||
create function bug11555_2() returns int return bug11555_1();
|
||||
# It is OK to report name of implicitly used table which is missing
|
||||
# when we create view.
|
||||
--error ER_NO_SUCH_TABLE
|
||||
# For stored functions however, because of exceptions handlers, there is
|
||||
# no easy way to find out if a missing table makes the view invalid.
|
||||
create view v1 as select bug11555_1();
|
||||
--error ER_NO_SUCH_TABLE
|
||||
drop view v1;
|
||||
create view v2 as select bug11555_2();
|
||||
drop view v2;
|
||||
# But we should hide name of missing implicitly used table when we use view
|
||||
create table t1 (i int);
|
||||
create view v1 as select bug11555_1();
|
||||
|
@ -1625,9 +1627,8 @@ select * from v2;
|
|||
select * from v3;
|
||||
# Note that creation of view which depends on broken view is yet
|
||||
# another form of view usage.
|
||||
--error ER_VIEW_INVALID
|
||||
create view v4 as select * from v1;
|
||||
drop view v1, v2, v3;
|
||||
drop view v1, v2, v3, v4;
|
||||
# We also should hide details about broken triggers which are
|
||||
# invoked for view.
|
||||
drop function bug11555_1;
|
||||
|
@ -1637,12 +1638,14 @@ create table t2 (i int);
|
|||
create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i);
|
||||
create view v1 as select * from t1;
|
||||
drop table t2;
|
||||
--error ER_VIEW_INVALID
|
||||
# Limitation, the desired error is ER_VIEW_INVALID
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
insert into v1 values (1);
|
||||
drop trigger t1_ai;
|
||||
create function bug11555_1() returns int return (select max(i) from t2);
|
||||
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
|
||||
--error ER_VIEW_INVALID
|
||||
# Limitation, the desired error is ER_VIEW_INVALID
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
insert into v1 values (2);
|
||||
drop function bug11555_1;
|
||||
drop table t1;
|
||||
|
@ -1839,6 +1842,184 @@ call bug24491();
|
|||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
|
||||
#
|
||||
# BUG#18914: Calling certain SPs from triggers fail
|
||||
#
|
||||
# Failing to call a procedure that does implicit commit from a trigger
|
||||
# is a correct behaviour, however the error message was misleading.
|
||||
#
|
||||
# DROP TABLE IF EXISTS is also fixed to give correct error instead of
|
||||
# "Table doesn't exist".
|
||||
#
|
||||
--disable_warnings
|
||||
DROP FUNCTION IF EXISTS bug18914_f1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f2;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p1;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p2;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
|
||||
CREATE PROCEDURE bug18914_p1() CREATE TABLE t2 (i INT);
|
||||
CREATE PROCEDURE bug18914_p2() DROP TABLE IF EXISTS no_such_table;
|
||||
|
||||
delimiter |;
|
||||
CREATE FUNCTION bug18914_f1() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p1();
|
||||
RETURN 1;
|
||||
END |
|
||||
|
||||
CREATE FUNCTION bug18914_f2() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p2();
|
||||
RETURN 1;
|
||||
END |
|
||||
delimiter ;|
|
||||
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL bug18914_p1();
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
SELECT bug18914_f1();
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
SELECT bug18914_f2();
|
||||
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SELECT * FROM t2;
|
||||
|
||||
DROP FUNCTION bug18914_f1;
|
||||
DROP FUNCTION bug18914_f2;
|
||||
DROP PROCEDURE bug18914_p1;
|
||||
DROP PROCEDURE bug18914_p2;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#20713 (Functions will not not continue for SQLSTATE VALUE '42S02')
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists bogus_table_20713;
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
--enable_warnings
|
||||
|
||||
create table bogus_table_20713( id int(10) not null primary key);
|
||||
insert into bogus_table_20713 values (1), (2), (3);
|
||||
|
||||
delimiter //;
|
||||
|
||||
create function func_20713_a() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
|
||||
declare continue handler for sqlexception set id=null;
|
||||
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
|
||||
return id;
|
||||
end//
|
||||
|
||||
create function func_20713_b() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
|
||||
declare continue handler for sqlstate value '42S02' set id=null;
|
||||
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
|
||||
return id;
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
select @in_func;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
select @in_func;
|
||||
|
||||
drop table bogus_table_20713;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
select @in_func;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
select @in_func;
|
||||
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
|
||||
#
|
||||
# Bug#25345 (Cursors from Functions)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists table_25345_a;
|
||||
drop table if exists table_25345_b;
|
||||
drop procedure if exists proc_25345;
|
||||
drop function if exists func_25345;
|
||||
drop function if exists func_25345_b;
|
||||
--enable_warnings
|
||||
|
||||
create table table_25345_a (a int);
|
||||
create table table_25345_b (b int);
|
||||
|
||||
delimiter ||;
|
||||
|
||||
create procedure proc_25345()
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
|
||||
select 1 as result;
|
||||
end ||
|
||||
|
||||
create function func_25345() returns int(11)
|
||||
begin
|
||||
call proc_25345();
|
||||
return 1;
|
||||
end ||
|
||||
|
||||
create function func_25345_b() returns int(11)
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
|
||||
return 1;
|
||||
end ||
|
||||
|
||||
delimiter ;||
|
||||
|
||||
call proc_25345();
|
||||
--error ER_SP_NO_RETSET
|
||||
select func_25345();
|
||||
select func_25345_b();
|
||||
|
||||
drop table table_25345_a;
|
||||
|
||||
call proc_25345();
|
||||
--error ER_SP_NO_RETSET
|
||||
select func_25345();
|
||||
select func_25345_b();
|
||||
|
||||
drop table table_25345_b;
|
||||
drop procedure proc_25345;
|
||||
drop function func_25345;
|
||||
drop function func_25345_b;
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
|
|
|
@ -500,8 +500,6 @@ DROP PROCEDURE p1;
|
|||
#
|
||||
# Test case for BUG#12976: Boolean values reversed in stored procedures?
|
||||
#
|
||||
# TODO: test case failed.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
|
@ -566,13 +564,8 @@ BEGIN
|
|||
END|
|
||||
delimiter ;|
|
||||
|
||||
# The expected and correct result.
|
||||
|
||||
call p1();
|
||||
|
||||
# The wrong result. Note that only hex(vb) works, but is printed with two
|
||||
# digits for some reason in this case.
|
||||
|
||||
call p2();
|
||||
|
||||
#
|
||||
|
@ -583,6 +576,64 @@ DROP TABLE t1;
|
|||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
|
||||
# Additional tests for Bug#12976
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS table_12976_a;
|
||||
DROP TABLE IF EXISTS table_12976_b;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_a;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_b;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE table_12976_a (val bit(1));
|
||||
|
||||
CREATE TABLE table_12976_b(
|
||||
appname varchar(15),
|
||||
emailperm bit not null default 1,
|
||||
phoneperm bit not null default 0);
|
||||
|
||||
insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0');
|
||||
|
||||
delimiter ||;
|
||||
CREATE PROCEDURE proc_12976_a()
|
||||
BEGIN
|
||||
declare localvar bit(1);
|
||||
SELECT val INTO localvar FROM table_12976_a;
|
||||
SELECT coalesce(localvar, 1)+1, coalesce(val, 1)+1 FROM table_12976_a;
|
||||
END||
|
||||
|
||||
CREATE PROCEDURE proc_12976_b(
|
||||
name varchar(15),
|
||||
out ep bit,
|
||||
out msg varchar(10))
|
||||
BEGIN
|
||||
SELECT emailperm into ep FROM table_12976_b where (appname = name);
|
||||
IF ep is true THEN
|
||||
SET msg = 'True';
|
||||
ELSE
|
||||
SET msg = 'False';
|
||||
END IF;
|
||||
END||
|
||||
|
||||
delimiter ;||
|
||||
|
||||
INSERT table_12976_a VALUES (0);
|
||||
call proc_12976_a();
|
||||
UPDATE table_12976_a set val=1;
|
||||
call proc_12976_a();
|
||||
|
||||
call proc_12976_b('A', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
|
||||
call proc_12976_b('B', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
|
||||
DROP TABLE table_12976_a;
|
||||
DROP TABLE table_12976_b;
|
||||
DROP PROCEDURE proc_12976_a;
|
||||
DROP PROCEDURE proc_12976_b;
|
||||
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Test case for BUG#9572: Stored procedures: variable type declarations
|
||||
|
|
|
@ -1370,7 +1370,7 @@ end|
|
|||
select f11()|
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
select f11() from t1|
|
||||
# We don't handle temporary tables used by nested functions well
|
||||
# Test that using a single table instance at a time works
|
||||
create function f12_1() returns int
|
||||
begin
|
||||
drop temporary table if exists t3;
|
||||
|
@ -1380,11 +1380,9 @@ begin
|
|||
end|
|
||||
create function f12_2() returns int
|
||||
return (select count(*) from t3)|
|
||||
# We need clean start to get error
|
||||
|
||||
drop temporary table t3|
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select f12_1()|
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select f12_1() from t1 limit 1|
|
||||
|
||||
# Cleanup
|
||||
|
@ -6693,6 +6691,53 @@ CALL bug24117()|
|
|||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
|
||||
#
|
||||
# Bug#8407(Stored functions/triggers ignore exception handler)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop function if exists func_8407_a|
|
||||
drop function if exists func_8407_b|
|
||||
--enable_warnings
|
||||
|
||||
create function func_8407_a() returns int
|
||||
begin
|
||||
declare x int;
|
||||
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
end;
|
||||
|
||||
select 1 from no_such_view limit 1 into x;
|
||||
|
||||
return x;
|
||||
end|
|
||||
|
||||
create function func_8407_b() returns int
|
||||
begin
|
||||
declare x int default 0;
|
||||
|
||||
declare continue handler for sqlstate '42S02'
|
||||
begin
|
||||
set x:= x+1000;
|
||||
end;
|
||||
|
||||
case (select 1 from no_such_view limit 1)
|
||||
when 1 then set x:= x+1;
|
||||
when 2 then set x:= x+2;
|
||||
else set x:= x+100;
|
||||
end case;
|
||||
set x:=x + 500;
|
||||
|
||||
return x;
|
||||
end|
|
||||
|
||||
select func_8407_a()|
|
||||
select func_8407_b()|
|
||||
|
||||
drop function func_8407_a|
|
||||
drop function func_8407_b|
|
||||
|
||||
#
|
||||
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
|
||||
# at the end of the file!
|
||||
|
|
|
@ -2002,7 +2002,7 @@ EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
|
|||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 24653: sorting by expressions containing subselects
|
||||
# Bug 24653: sorting by expressions containing subselects
|
||||
# that return more than one row
|
||||
#
|
||||
|
||||
|
@ -2014,12 +2014,12 @@ INSERT INTO t2 VALUES
|
|||
(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
|
||||
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
|
||||
--error 1242
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
|
||||
--error 1242
|
||||
--error 1242
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
|
||||
--error 1242
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
|
||||
|
||||
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
|
||||
--error 1242
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
|
||||
|
@ -2036,28 +2036,28 @@ SELECT a FROM t1 GROUP BY a
|
|||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
--error 1242
|
||||
--error 1242
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
|
||||
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
@ -2571,7 +2571,7 @@ DROP TABLE t1,t2;
|
|||
#
|
||||
# Bug #25219: EXIST subquery with UNION over a mix of
|
||||
# correlated and uncorrelated selects
|
||||
#
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
||||
CREATE TABLE t2 (c int);
|
||||
|
@ -2579,28 +2579,29 @@ CREATE TABLE t2 (c int);
|
|||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
|
||||
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
INSERT INTO t3 VALUES (1);
|
||||
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug#23800: Outer fields in correlated subqueries is used in a temporary
|
||||
# table created for sorting.
|
||||
|
@ -2628,3 +2629,103 @@ SELECT a, MAX(b),
|
|||
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
|
||||
FROM t1 GROUP BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#21904 (parser problem when using IN with a double "(())")
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t1xt2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id_1 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id_2 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE t1xt2 (
|
||||
id_1 int(5) NOT NULL,
|
||||
id_2 int(5) NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
|
||||
|
||||
INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
|
||||
|
||||
INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
|
||||
|
||||
# subselect returns 0 rows
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
insert INTO t1xt2 VALUES (1, 12);
|
||||
|
||||
# subselect returns 1 row
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
insert INTO t1xt2 VALUES (2, 12);
|
||||
|
||||
# subselect returns more than 1 row
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1xt2;
|
||||
|
||||
|
|
|
@ -1625,4 +1625,78 @@ SELECT fubar_id FROM t2;
|
|||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug#21285 (Incorrect message error deleting records in a table with a
|
||||
# trigger for inserting)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug21825_A;
|
||||
DROP TABLE IF EXISTS bug21825_B;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug21825_A (id int(10));
|
||||
CREATE TABLE bug21825_B (id int(10));
|
||||
|
||||
delimiter //;
|
||||
|
||||
CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO bug21825_B (id) values (1);
|
||||
END//
|
||||
delimiter ;//
|
||||
|
||||
INSERT INTO bug21825_A (id) VALUES (10);
|
||||
INSERT INTO bug21825_A (id) VALUES (20);
|
||||
|
||||
DROP TABLE bug21825_B;
|
||||
|
||||
# Must pass, the missing table in the insert trigger should not matter.
|
||||
DELETE FROM bug21825_A WHERE id = 20;
|
||||
|
||||
DROP TABLE bug21825_A;
|
||||
|
||||
#
|
||||
# Bug#22580 (DROP TABLE in nested stored procedure causes strange dependancy
|
||||
# error)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug22580_t1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug22580_t1 (a INT, b INT);
|
||||
|
||||
DELIMITER ||;
|
||||
|
||||
CREATE PROCEDURE bug22580_proc_2()
|
||||
BEGIN
|
||||
DROP TABLE IF EXISTS bug22580_tmp;
|
||||
CREATE TEMPORARY TABLE bug22580_tmp (a INT);
|
||||
DROP TABLE bug22580_tmp;
|
||||
END||
|
||||
|
||||
CREATE PROCEDURE bug22580_proc_1()
|
||||
BEGIN
|
||||
CALL bug22580_proc_2();
|
||||
END||
|
||||
|
||||
CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL bug22580_proc_1();
|
||||
END||
|
||||
|
||||
DELIMITER ;||
|
||||
|
||||
# Must pass, the actions of the update trigger should not matter
|
||||
INSERT INTO bug22580_t1 VALUES (1,1);
|
||||
|
||||
DROP TABLE bug22580_t1;
|
||||
DROP PROCEDURE bug22580_proc_1;
|
||||
DROP PROCEDURE bug22580_proc_2;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -748,12 +748,14 @@ drop view v1;
|
|||
#
|
||||
# VIEWs with national characters
|
||||
#
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names utf8;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names latin1;
|
||||
|
||||
#
|
||||
# problem with used_tables() of outer reference resolved in VIEW
|
||||
|
@ -2991,7 +2993,7 @@ DROP VIEW v1;
|
|||
#
|
||||
|
||||
CREATE TABLE t1 (mydate DATETIME);
|
||||
INSERT INTO t1 VALUES
|
||||
INSERT INTO t1 VALUES
|
||||
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||
|
||||
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||
|
@ -3039,7 +3041,7 @@ drop view v1;
|
|||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#26209: queries with GROUP BY and ORDER BY using views
|
||||
# Bug#26209: queries with GROUP BY and ORDER BY using views
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
|
@ -3058,4 +3060,107 @@ SELECT code, COUNT(DISTINCT country) FROM v1 GROUP BY code ORDER BY MAX(id);
|
|||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#25897: Some queries are no longer possible after a CREATE VIEW
|
||||
# fails
|
||||
#
|
||||
--disable_warnings
|
||||
DROP VIEW IF EXISTS v1;
|
||||
--enable_warnings
|
||||
|
||||
let $query = SELECT * FROM (SELECT 1) AS t;
|
||||
|
||||
eval $query;
|
||||
--error ER_VIEW_SELECT_DERIVED
|
||||
eval CREATE VIEW v1 AS $query;
|
||||
--echo # Previously the following would fail.
|
||||
eval $query;
|
||||
|
||||
#
|
||||
# Bug#24532: The return data type of IS TRUE is different from similar
|
||||
# operations
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop view if exists view_24532_a;
|
||||
drop view if exists view_24532_b;
|
||||
drop table if exists table_24532;
|
||||
--enable_warnings
|
||||
|
||||
create table table_24532 (
|
||||
a int,
|
||||
b bigint,
|
||||
c int(4),
|
||||
d bigint(48)
|
||||
);
|
||||
|
||||
create view view_24532_a as
|
||||
select
|
||||
a IS TRUE,
|
||||
a IS NOT TRUE,
|
||||
a IS FALSE,
|
||||
a IS NOT FALSE,
|
||||
a IS UNKNOWN,
|
||||
a IS NOT UNKNOWN,
|
||||
a is NULL,
|
||||
a IS NOT NULL,
|
||||
ISNULL(a),
|
||||
b IS TRUE,
|
||||
b IS NOT TRUE,
|
||||
b IS FALSE,
|
||||
b IS NOT FALSE,
|
||||
b IS UNKNOWN,
|
||||
b IS NOT UNKNOWN,
|
||||
b is NULL,
|
||||
b IS NOT NULL,
|
||||
ISNULL(b),
|
||||
c IS TRUE,
|
||||
c IS NOT TRUE,
|
||||
c IS FALSE,
|
||||
c IS NOT FALSE,
|
||||
c IS UNKNOWN,
|
||||
c IS NOT UNKNOWN,
|
||||
c is NULL,
|
||||
c IS NOT NULL,
|
||||
ISNULL(c),
|
||||
d IS TRUE,
|
||||
d IS NOT TRUE,
|
||||
d IS FALSE,
|
||||
d IS NOT FALSE,
|
||||
d IS UNKNOWN,
|
||||
d IS NOT UNKNOWN,
|
||||
d is NULL,
|
||||
d IS NOT NULL,
|
||||
ISNULL(d)
|
||||
from table_24532;
|
||||
|
||||
describe view_24532_a;
|
||||
|
||||
create view view_24532_b as
|
||||
select
|
||||
a IS TRUE,
|
||||
if(ifnull(a, 0), 1, 0) as old_istrue,
|
||||
a IS NOT TRUE,
|
||||
if(ifnull(a, 0), 0, 1) as old_isnottrue,
|
||||
a IS FALSE,
|
||||
if(ifnull(a, 1), 0, 1) as old_isfalse,
|
||||
a IS NOT FALSE,
|
||||
if(ifnull(a, 1), 1, 0) as old_isnotfalse
|
||||
from table_24532;
|
||||
|
||||
describe view_24532_b;
|
||||
|
||||
show create view view_24532_b;
|
||||
|
||||
insert into table_24532 values (0, 0, 0, 0);
|
||||
select * from view_24532_b;
|
||||
update table_24532 set a=1;
|
||||
select * from view_24532_b;
|
||||
update table_24532 set a=NULL;
|
||||
select * from view_24532_b;
|
||||
|
||||
drop view view_24532_a;
|
||||
drop view view_24532_b;
|
||||
drop table table_24532;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
|
|
@ -63,7 +63,7 @@ pid_path="$1"
|
|||
total_attempts="$2"
|
||||
event="$3"
|
||||
test_id="$4"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "pid_path: '$pid_path'"
|
||||
|
|
|
@ -30,7 +30,7 @@ password="$4"
|
|||
db="$5"
|
||||
total_timeout="$6"
|
||||
test_id="$7"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "client_exe: '$client_exe'"
|
||||
|
|
|
@ -508,7 +508,7 @@ int Instance_options::add_option(const char* option)
|
|||
{"--pid-file=", 11, &mysqld_pid_file, SAVE_WHOLE_AND_ADD},
|
||||
{"--mysqld-path=", 14, &mysqld_path, SAVE_VALUE},
|
||||
{"--nonguarded", 9, &nonguarded, SAVE_WHOLE},
|
||||
{"--shutdown_delay", 9, &shutdown_delay, SAVE_VALUE},
|
||||
{"--shutdown-delay", 9, &shutdown_delay, SAVE_VALUE},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
struct selected_options_st *selected_options;
|
||||
|
|
|
@ -210,10 +210,13 @@ void Listener_thread::run()
|
|||
return;
|
||||
|
||||
err:
|
||||
log_error("Listener: failed to initialize. Initiate shutdown...");
|
||||
|
||||
// we have to close the ip sockets in case of error
|
||||
for (i= 0; i < num_sockets; i++)
|
||||
closesocket(sockets[i]);
|
||||
|
||||
thread_registry.set_error_status();
|
||||
thread_registry.unregister_thread(&thread_info);
|
||||
thread_registry.request_shutdown();
|
||||
my_thread_end();
|
||||
|
|
|
@ -114,6 +114,9 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
|||
pthread_cond_signal(&guardian->COND_guardian);
|
||||
/* stop all threads */
|
||||
registry->deliver_shutdown();
|
||||
|
||||
/* Set error status in the thread registry. */
|
||||
registry->set_error_status();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -123,7 +126,7 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
|||
architecture.
|
||||
*/
|
||||
|
||||
void manager(const Options &options)
|
||||
int manager(const Options &options)
|
||||
{
|
||||
Thread_registry thread_registry;
|
||||
/*
|
||||
|
@ -145,10 +148,10 @@ void manager(const Options &options)
|
|||
instance_map.guardian= &guardian_thread;
|
||||
|
||||
if (instance_map.init() || user_map.init())
|
||||
return;
|
||||
return 1;
|
||||
|
||||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
return 1;
|
||||
|
||||
/* write Instance Manager pid file */
|
||||
|
||||
|
@ -157,7 +160,7 @@ void manager(const Options &options)
|
|||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(options.pid_file_name, manager_pid))
|
||||
return;
|
||||
return 1;
|
||||
|
||||
/*
|
||||
Initialize signals and alarm-infrastructure.
|
||||
|
@ -301,5 +304,6 @@ err:
|
|||
end_thr_alarm(1);
|
||||
/* don't pthread_exit to kill all threads who did not shut down in time */
|
||||
#endif
|
||||
}
|
||||
|
||||
return thread_registry.get_error_status() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
struct Options;
|
||||
|
||||
void manager(const Options &options);
|
||||
int manager(const Options &options);
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
|
|
|
@ -110,8 +110,7 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
#endif
|
||||
|
||||
manager(options);
|
||||
return_value= 0;
|
||||
return_value= manager(options);
|
||||
|
||||
err:
|
||||
options.cleanup();
|
||||
|
@ -254,26 +253,23 @@ static void daemonize(const char *log_file_name)
|
|||
enum { CHILD_OK= 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL };
|
||||
|
||||
static volatile sig_atomic_t child_status= CHILD_OK;
|
||||
static volatile sig_atomic_t child_exit_code= 0;
|
||||
|
||||
/*
|
||||
Signal handler for SIGCHLD: reap child, analyze child exit status, and set
|
||||
Signal handler for SIGCHLD: reap child, analyze child exit code, and set
|
||||
child_status appropriately.
|
||||
*/
|
||||
|
||||
void reap_child(int __attribute__((unused)) signo)
|
||||
{
|
||||
int child_exit_status;
|
||||
/* As we have only one child, no need to cycle waitpid */
|
||||
if (waitpid(0, &child_exit_status, WNOHANG) > 0)
|
||||
/* NOTE: As we have only one child, no need to cycle waitpid(). */
|
||||
|
||||
int exit_code;
|
||||
|
||||
if (waitpid(0, &exit_code, WNOHANG) > 0)
|
||||
{
|
||||
if (WIFSIGNALED(child_exit_status))
|
||||
child_status= CHILD_NEED_RESPAWN;
|
||||
else
|
||||
/*
|
||||
As reap_child is not called for SIGSTOP, we should be here only
|
||||
if the child exited normally.
|
||||
*/
|
||||
child_status= CHILD_EXIT_ANGEL;
|
||||
child_exit_code= exit_code;
|
||||
child_status= exit_code ? CHILD_NEED_RESPAWN : CHILD_EXIT_ANGEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,10 +349,16 @@ spawn:
|
|||
else if (child_status == CHILD_NEED_RESPAWN)
|
||||
{
|
||||
child_status= CHILD_OK;
|
||||
log_error("angel(): mysqlmanager exited abnormally: respawning...");
|
||||
log_error("angel(): mysqlmanager exited abnormally (exit code: %d):"
|
||||
"respawning...",
|
||||
(int) child_exit_code);
|
||||
sleep(1); /* don't respawn too fast */
|
||||
goto spawn;
|
||||
}
|
||||
|
||||
/* Delete IM-angel pid file. */
|
||||
my_delete(Options::angel_pid_file_name, MYF(0));
|
||||
|
||||
/*
|
||||
mysqlmanager successfully exited, let's silently evaporate
|
||||
If we return to main we fall into the manager() function, so let's
|
||||
|
|
|
@ -53,6 +53,7 @@ Thread_info::Thread_info(pthread_t thread_id_arg) :
|
|||
Thread_registry::Thread_registry() :
|
||||
shutdown_in_progress(false)
|
||||
,sigwait_thread_pid(pthread_self())
|
||||
,error_status(FALSE)
|
||||
{
|
||||
pthread_mutex_init(&LOCK_thread_registry, 0);
|
||||
pthread_cond_init(&COND_thread_registry_is_empty, 0);
|
||||
|
@ -243,3 +244,23 @@ void Thread_registry::request_shutdown()
|
|||
{
|
||||
pthread_kill(sigwait_thread_pid, SIGTERM);
|
||||
}
|
||||
|
||||
|
||||
int Thread_registry::get_error_status()
|
||||
{
|
||||
int ret_error_status;
|
||||
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
ret_error_status= error_status;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
|
||||
return ret_error_status;
|
||||
}
|
||||
|
||||
|
||||
void Thread_registry::set_error_status()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
error_status= TRUE;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
}
|
||||
|
|
|
@ -97,12 +97,16 @@ public:
|
|||
pthread_mutex_t *mutex);
|
||||
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex, struct timespec *wait_time);
|
||||
int get_error_status();
|
||||
void set_error_status();
|
||||
|
||||
private:
|
||||
Thread_info head;
|
||||
bool shutdown_in_progress;
|
||||
pthread_mutex_t LOCK_thread_registry;
|
||||
pthread_cond_t COND_thread_registry_is_empty;
|
||||
pthread_t sigwait_thread_pid;
|
||||
bool error_status;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -793,6 +793,59 @@ int Arg_comparator::compare_e_row()
|
|||
}
|
||||
|
||||
|
||||
void Item_func_truth::fix_length_and_dec()
|
||||
{
|
||||
maybe_null= 0;
|
||||
null_value= 0;
|
||||
decimals= 0;
|
||||
max_length= 1;
|
||||
}
|
||||
|
||||
|
||||
void Item_func_truth::print(String *str)
|
||||
{
|
||||
str->append('(');
|
||||
args[0]->print(str);
|
||||
str->append(STRING_WITH_LEN(" is "));
|
||||
if (! affirmative)
|
||||
str->append(STRING_WITH_LEN("not "));
|
||||
if (value)
|
||||
str->append(STRING_WITH_LEN("true"));
|
||||
else
|
||||
str->append(STRING_WITH_LEN("false"));
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_truth::val_bool()
|
||||
{
|
||||
bool val= args[0]->val_bool();
|
||||
if (args[0]->null_value)
|
||||
{
|
||||
/*
|
||||
NULL val IS {TRUE, FALSE} --> FALSE
|
||||
NULL val IS NOT {TRUE, FALSE} --> TRUE
|
||||
*/
|
||||
return (! affirmative);
|
||||
}
|
||||
|
||||
if (affirmative)
|
||||
{
|
||||
/* {TRUE, FALSE} val IS {TRUE, FALSE} value */
|
||||
return (val == value);
|
||||
}
|
||||
|
||||
/* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
|
||||
return (val != value);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_truth::val_int()
|
||||
{
|
||||
return (val_bool() ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
|
||||
{
|
||||
if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
|
||||
|
@ -1529,6 +1582,7 @@ Item_func_if::fix_length_and_dec()
|
|||
{
|
||||
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
|
||||
decimals= max(args[1]->decimals, args[2]->decimals);
|
||||
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
|
||||
|
||||
enum Item_result arg1_type=args[1]->result_type();
|
||||
enum Item_result arg2_type=args[2]->result_type();
|
||||
|
@ -1558,12 +1612,20 @@ Item_func_if::fix_length_and_dec()
|
|||
collation.set(&my_charset_bin); // Number
|
||||
}
|
||||
}
|
||||
max_length=
|
||||
(cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ?
|
||||
(max(args[1]->max_length - args[1]->decimals,
|
||||
args[2]->max_length - args[2]->decimals) + decimals +
|
||||
(unsigned_flag ? 0 : 1) ) :
|
||||
max(args[1]->max_length, args[2]->max_length);
|
||||
|
||||
if ((cached_result_type == DECIMAL_RESULT )
|
||||
|| (cached_result_type == INT_RESULT))
|
||||
{
|
||||
int len1= args[1]->max_length - args[1]->decimals
|
||||
- (args[1]->unsigned_flag ? 0 : 1);
|
||||
|
||||
int len2= args[2]->max_length - args[2]->decimals
|
||||
- (args[2]->unsigned_flag ? 0 : 1);
|
||||
|
||||
max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
|
||||
}
|
||||
else
|
||||
max_length= max(args[1]->max_length, args[2]->max_length);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,92 @@ public:
|
|||
uint decimal_precision() const { return 1; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
|
||||
boolean predicates.
|
||||
*/
|
||||
|
||||
class Item_func_truth : public Item_bool_func
|
||||
{
|
||||
public:
|
||||
virtual bool val_bool();
|
||||
virtual longlong val_int();
|
||||
virtual void fix_length_and_dec();
|
||||
virtual void print(String *str);
|
||||
|
||||
protected:
|
||||
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
|
||||
: Item_bool_func(a), value(a_value), affirmative(a_affirmative)
|
||||
{}
|
||||
|
||||
~Item_func_truth()
|
||||
{}
|
||||
private:
|
||||
/**
|
||||
True for <code>X IS [NOT] TRUE</code>,
|
||||
false for <code>X IS [NOT] FALSE</code> predicates.
|
||||
*/
|
||||
const bool value;
|
||||
/**
|
||||
True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
|
||||
*/
|
||||
const bool affirmative;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS TRUE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_istrue : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
|
||||
~Item_func_istrue() {}
|
||||
virtual const char* func_name() const { return "istrue"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isnottrue : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
|
||||
~Item_func_isnottrue() {}
|
||||
virtual const char* func_name() const { return "isnottrue"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS FALSE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isfalse : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
|
||||
~Item_func_isfalse() {}
|
||||
virtual const char* func_name() const { return "isfalse"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isnotfalse : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
|
||||
~Item_func_isnotfalse() {}
|
||||
virtual const char* func_name() const { return "isnotfalse"; }
|
||||
};
|
||||
|
||||
|
||||
class Item_cache;
|
||||
#define UNKNOWN ((my_bool)-1)
|
||||
|
||||
|
|
|
@ -3459,6 +3459,7 @@ longlong Item_func_benchmark::val_int()
|
|||
DBUG_ASSERT(fixed == 1);
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff), &my_charset_bin);
|
||||
my_decimal tmp_decimal;
|
||||
THD *thd=current_thd;
|
||||
|
||||
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
|
||||
|
@ -3473,6 +3474,9 @@ longlong Item_func_benchmark::val_int()
|
|||
case STRING_RESULT:
|
||||
(void) args[0]->val_str(&tmp);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
(void) args[0]->val_decimal(&tmp_decimal);
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
// This case should never be chosen
|
||||
|
|
|
@ -51,6 +51,10 @@ Item_subselect::Item_subselect():
|
|||
void Item_subselect::init(st_select_lex *select_lex,
|
||||
select_subselect *result)
|
||||
{
|
||||
/*
|
||||
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
|
||||
which depends on alterations to the parse tree implemented here.
|
||||
*/
|
||||
|
||||
DBUG_ENTER("Item_subselect::init");
|
||||
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
|
||||
|
@ -91,6 +95,12 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
st_select_lex *
|
||||
Item_subselect::get_select_lex()
|
||||
{
|
||||
return unit->first_select();
|
||||
}
|
||||
|
||||
void Item_subselect::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::cleanup");
|
||||
|
@ -268,6 +278,26 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
st_select_lex *
|
||||
Item_singlerow_subselect::invalidate_and_restore_select_lex()
|
||||
{
|
||||
DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
|
||||
st_select_lex *result= get_select_lex();
|
||||
|
||||
DBUG_ASSERT(result);
|
||||
|
||||
/*
|
||||
This code restore the parse tree in it's state before the execution of
|
||||
Item_singlerow_subselect::Item_singlerow_subselect(),
|
||||
and in particular decouples this object from the SELECT_LEX,
|
||||
so that the SELECT_LEX can be used with a different flavor
|
||||
or Item_subselect instead, as part of query rewriting.
|
||||
*/
|
||||
unit->item= NULL;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
|
||||
Item_subselect *parent,
|
||||
st_select_lex *select_lex,
|
||||
|
|
|
@ -126,6 +126,12 @@ public:
|
|||
virtual void reset_value_registration() {}
|
||||
enum_parsing_place place() { return parsing_place; }
|
||||
|
||||
/**
|
||||
Get the SELECT_LEX structure associated with this Item.
|
||||
@return the SELECT_LEX structure associated with this Item
|
||||
*/
|
||||
st_select_lex* get_select_lex();
|
||||
|
||||
friend class select_subselect;
|
||||
friend class Item_in_optimizer;
|
||||
friend bool Item_field::fix_fields(THD *, Item **);
|
||||
|
@ -169,6 +175,20 @@ public:
|
|||
bool null_inside();
|
||||
void bring_value();
|
||||
|
||||
/**
|
||||
This method is used to implement a special case of semantic tree
|
||||
rewriting, mandated by a SQL:2003 exception in the specification.
|
||||
The only caller of this method is handle_sql2003_note184_exception(),
|
||||
see the code there for more details.
|
||||
Note that this method breaks the object internal integrity, by
|
||||
removing it's association with the corresponding SELECT_LEX,
|
||||
making this object orphan from the parse tree.
|
||||
No other method, beside the destructor, should be called on this
|
||||
object, as it is now invalid.
|
||||
@return the SELECT_LEX structure that was given in the constructor.
|
||||
*/
|
||||
st_select_lex* invalidate_and_restore_select_lex();
|
||||
|
||||
friend class select_singlerow_subselect;
|
||||
};
|
||||
|
||||
|
|
|
@ -566,7 +566,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||
|
||||
for (; haystack; haystack= haystack->next_global)
|
||||
{
|
||||
if (haystack->placeholder() || haystack->schema_table)
|
||||
if (haystack->placeholder())
|
||||
continue;
|
||||
table2= haystack->table;
|
||||
if (table2->s->tmp_table == TMP_TABLE)
|
||||
|
|
|
@ -2448,6 +2448,14 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||
*/
|
||||
if ((thd= current_thd))
|
||||
{
|
||||
/*
|
||||
TODO: There are two exceptions mechanism (THD and sp_rcontext),
|
||||
this could be improved by having a common stack of handlers.
|
||||
*/
|
||||
if (thd->handle_error(error,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (thd->spcont &&
|
||||
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ Item_result
|
|||
sp_map_result_type(enum enum_field_types type)
|
||||
{
|
||||
switch (type) {
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
|
@ -58,6 +59,7 @@ Item::Type
|
|||
sp_map_item_type(enum enum_field_types type)
|
||||
{
|
||||
switch (type) {
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
|
@ -2388,16 +2390,11 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reinit_stmt_before_use(thd, m_lex);
|
||||
/*
|
||||
If requested check whenever we have access to tables in LEX's table list
|
||||
and open and lock them before executing instructtions core function.
|
||||
*/
|
||||
if (open_tables &&
|
||||
(check_table_access(thd, SELECT_ACL, m_lex->query_tables, 0) ||
|
||||
open_and_lock_tables(thd, m_lex->query_tables)))
|
||||
res= -1;
|
||||
|
||||
if (open_tables)
|
||||
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables, nextp);
|
||||
|
||||
if (!res)
|
||||
res= instr->exec_core(thd, nextp);
|
||||
|
@ -2446,6 +2443,33 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
sp_instr class functions
|
||||
*/
|
||||
|
||||
int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables,
|
||||
uint *nextp)
|
||||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
Check whenever we have access to tables for this statement
|
||||
and open and lock them before executing instructions core function.
|
||||
*/
|
||||
if (check_table_access(thd, SELECT_ACL, tables, 0)
|
||||
|| open_and_lock_tables(thd, tables))
|
||||
{
|
||||
get_cont_dest(nextp);
|
||||
result= -1;
|
||||
}
|
||||
else
|
||||
result= 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void sp_instr::get_cont_dest(uint *nextp)
|
||||
{
|
||||
*nextp= m_ip+1;
|
||||
}
|
||||
|
||||
|
||||
int sp_instr::exec_core(THD *thd, uint *nextp)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
|
@ -2626,6 +2650,15 @@ sp_instr_set_trigger_field::print(String *str)
|
|||
value->print(str);
|
||||
}
|
||||
|
||||
/*
|
||||
sp_instr_opt_meta
|
||||
*/
|
||||
|
||||
void sp_instr_opt_meta::get_cont_dest(uint *nextp)
|
||||
{
|
||||
*nextp= m_cont_dest;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
sp_instr_jump class functions
|
||||
|
|
|
@ -458,6 +458,28 @@ public:
|
|||
|
||||
virtual int execute(THD *thd, uint *nextp) = 0;
|
||||
|
||||
/**
|
||||
Execute <code>open_and_lock_tables()</code> for this statement.
|
||||
Open and lock the tables used by this statement, as a pre-requisite
|
||||
to execute the core logic of this instruction with
|
||||
<code>exec_core()</code>.
|
||||
If this statement fails, the next instruction to execute is also returned.
|
||||
This is useful when a user defined SQL continue handler needs to be
|
||||
executed.
|
||||
@param thd the current thread
|
||||
@param tables the list of tables to open and lock
|
||||
@param nextp the continuation instruction, returned to the caller if this
|
||||
method fails.
|
||||
@return zero on success, non zero on failure.
|
||||
*/
|
||||
int exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint *nextp);
|
||||
|
||||
/**
|
||||
Get the continuation destination of this instruction.
|
||||
@param nextp the continuation destination (output)
|
||||
*/
|
||||
virtual void get_cont_dest(uint *nextp);
|
||||
|
||||
/*
|
||||
Execute core function of instruction after all preparations (e.g.
|
||||
setting of proper LEX, saving part of the thread context have been
|
||||
|
@ -722,6 +744,8 @@ public:
|
|||
virtual void set_destination(uint old_dest, uint new_dest)
|
||||
= 0;
|
||||
|
||||
virtual void get_cont_dest(uint *nextp);
|
||||
|
||||
protected:
|
||||
|
||||
sp_instr *m_optdest; // Used during optimization
|
||||
|
|
216
sql/sql_base.cc
216
sql/sql_base.cc
|
@ -28,6 +28,59 @@
|
|||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
This internal handler is used to trap internally
|
||||
errors that can occur when executing open table
|
||||
during the prelocking phase.
|
||||
*/
|
||||
class Prelock_error_handler : public Internal_error_handler
|
||||
{
|
||||
public:
|
||||
Prelock_error_handler()
|
||||
: m_handled_errors(0), m_unhandled_errors(0)
|
||||
{}
|
||||
|
||||
virtual ~Prelock_error_handler() {}
|
||||
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
THD *thd);
|
||||
|
||||
bool safely_trapped_errors();
|
||||
|
||||
private:
|
||||
int m_handled_errors;
|
||||
int m_unhandled_errors;
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
Prelock_error_handler::handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level /* level */,
|
||||
THD * /* thd */)
|
||||
{
|
||||
if (sql_errno == ER_NO_SUCH_TABLE)
|
||||
{
|
||||
m_handled_errors++;
|
||||
return TRUE; // 'TRUE', as per coding style
|
||||
}
|
||||
|
||||
m_unhandled_errors++;
|
||||
return FALSE; // 'FALSE', as per coding style
|
||||
}
|
||||
|
||||
|
||||
bool Prelock_error_handler::safely_trapped_errors()
|
||||
{
|
||||
/*
|
||||
If m_unhandled_errors != 0, something else, unanticipated, happened,
|
||||
so the error is not trapped but returned to the caller.
|
||||
Multiple ER_NO_SUCH_TABLE can be raised in case of views.
|
||||
*/
|
||||
return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
|
||||
}
|
||||
|
||||
|
||||
TABLE *unused_tables; /* Used by mysql_test */
|
||||
HASH open_cache; /* Used by mysql_test */
|
||||
|
||||
|
@ -1210,6 +1263,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
int4store(key + key_length, thd->server_id);
|
||||
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
|
||||
|
||||
/*
|
||||
Unless requested otherwise, try to resolve this table in the list
|
||||
of temporary tables of this thread. In MySQL temporary tables
|
||||
are always thread-local and "shadow" possible base tables with the
|
||||
same name. This block implements the behaviour.
|
||||
TODO: move this block into a separate function.
|
||||
*/
|
||||
if (!table_list->skip_temporary)
|
||||
{
|
||||
for (table= thd->temporary_tables; table ; table=table->next)
|
||||
|
@ -1218,6 +1278,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
!memcmp(table->s->table_cache_key, key,
|
||||
key_length + TMP_TABLE_KEY_EXTRA))
|
||||
{
|
||||
/*
|
||||
We're trying to use the same temporary table twice in a query.
|
||||
Right now we don't support this because a temporary table
|
||||
is always represented by only one TABLE object in THD, and
|
||||
it can not be cloned. Emit an error for an unsupported behaviour.
|
||||
*/
|
||||
if (table->query_id == thd->query_id ||
|
||||
thd->prelocked_mode && table->query_id)
|
||||
{
|
||||
|
@ -1233,6 +1299,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The table is not temporary - if we're in pre-locked or LOCK TABLES
|
||||
mode, let's try to find the requested table in the list of pre-opened
|
||||
and locked tables. If the table is not there, return an error - we can't
|
||||
open not pre-opened tables in pre-locked/LOCK TABLES mode.
|
||||
TODO: move this block into a separate function.
|
||||
*/
|
||||
if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
|
||||
(thd->locked_tables || thd->prelocked_mode))
|
||||
{ // Using table locks
|
||||
|
@ -1304,7 +1377,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
goto reset;
|
||||
}
|
||||
/*
|
||||
is it view?
|
||||
Is this table a view and not a base table?
|
||||
(it is work around to allow to open view with locked tables,
|
||||
real fix will be made after definition cache will be made)
|
||||
*/
|
||||
|
@ -1334,12 +1407,39 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
}
|
||||
}
|
||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||
if ((thd->locked_tables) && (thd->locked_tables->lock_count > 0))
|
||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||
else
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Non pre-locked/LOCK TABLES mode, and the table is not temporary:
|
||||
this is the normal use case.
|
||||
Now we should:
|
||||
- try to find the table in the table cache.
|
||||
- if one of the discovered TABLE instances is name-locked
|
||||
(table->s->version == 0) or some thread has started FLUSH TABLES
|
||||
(refresh_version > table->s->version), back off -- we have to wait
|
||||
until no one holds a name lock on the table.
|
||||
- if there is no such TABLE in the name cache, read the table definition
|
||||
and insert it into the cache.
|
||||
We perform all of the above under LOCK_open which currently protects
|
||||
the open cache (also known as table cache) and table definitions stored
|
||||
on disk.
|
||||
*/
|
||||
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
|
||||
/*
|
||||
If it's the first table from a list of tables used in a query,
|
||||
remember refresh_version (the version of open_cache state).
|
||||
If the version changes while we're opening the remaining tables,
|
||||
we will have to back off, close all the tables opened-so-far,
|
||||
and try to reopen them.
|
||||
Note: refresh_version is currently changed only during FLUSH TABLES.
|
||||
*/
|
||||
if (!thd->open_tables)
|
||||
thd->version=refresh_version;
|
||||
else if ((thd->version != refresh_version) &&
|
||||
|
@ -1356,12 +1456,39 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
if (thd->handler_tables)
|
||||
mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE);
|
||||
|
||||
/*
|
||||
Actually try to find the table in the open_cache.
|
||||
The cache may contain several "TABLE" instances for the same
|
||||
physical table. The instances that are currently "in use" by
|
||||
some thread have their "in_use" member != NULL.
|
||||
There is no good reason for having more than one entry in the
|
||||
hash for the same physical table, except that we use this as
|
||||
an implicit "pending locks queue" - see
|
||||
wait_for_locked_table_names for details.
|
||||
*/
|
||||
for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length,
|
||||
&state);
|
||||
table && table->in_use ;
|
||||
table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
|
||||
&state))
|
||||
{
|
||||
/*
|
||||
Normally, table->s->version contains the value of
|
||||
refresh_version from the moment when this table was
|
||||
(re-)opened and added to the cache.
|
||||
If since then we did (or just started) FLUSH TABLES
|
||||
statement, refresh_version has been increased.
|
||||
For "name-locked" TABLE instances, table->s->version is set
|
||||
to 0 (see lock_table_name for details).
|
||||
In case there is a pending FLUSH TABLES or a name lock, we
|
||||
need to back off and re-start opening tables.
|
||||
If we do not back off now, we may dead lock in case of lock
|
||||
order mismatch with some other thread:
|
||||
c1: name lock t1; -- sort of exclusive lock
|
||||
c2: open t2; -- sort of shared lock
|
||||
c1: name lock t2; -- blocks
|
||||
c2: open t1; -- blocks
|
||||
*/
|
||||
if (table->s->version != refresh_version)
|
||||
{
|
||||
DBUG_PRINT("note",
|
||||
|
@ -1375,16 +1502,35 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
|
||||
/*
|
||||
There is a refresh in progress for this table
|
||||
Wait until the table is freed or the thread is killed.
|
||||
Back off, part 1: mark the table as "unused" for the
|
||||
purpose of name-locking by setting table->db_stat to 0. Do
|
||||
that only for the tables in this thread that have an old
|
||||
table->s->version (this is an optimization (?)).
|
||||
table->db_stat == 0 signals wait_for_locked_table_names
|
||||
that the tables in question are not used any more. See
|
||||
table_is_used call for details.
|
||||
*/
|
||||
close_old_data_files(thd,thd->open_tables,0,0);
|
||||
/*
|
||||
Back-off part 2: try to avoid "busy waiting" on the table:
|
||||
if the table is in use by some other thread, we suspend
|
||||
and wait till the operation is complete: when any
|
||||
operation that juggles with table->s->version completes,
|
||||
it broadcasts COND_refresh condition variable.
|
||||
*/
|
||||
if (table->in_use != thd)
|
||||
{
|
||||
wait_for_refresh(thd);
|
||||
/* wait_for_refresh will unlock LOCK_open for us */
|
||||
}
|
||||
else
|
||||
{
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
}
|
||||
/*
|
||||
There is a refresh in progress for this table.
|
||||
Signal the caller that it has to try again.
|
||||
*/
|
||||
if (refresh)
|
||||
*refresh=1;
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1392,6 +1538,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
if (table)
|
||||
{
|
||||
/* Unlink the table from "unused_tables" list. */
|
||||
if (table == unused_tables)
|
||||
{ // First unused
|
||||
unused_tables=unused_tables->next; // Remove from link
|
||||
|
@ -1404,6 +1551,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Insert a new TABLE instance into the open cache */
|
||||
TABLE_SHARE *share;
|
||||
int error;
|
||||
/* Free cache if too big */
|
||||
|
@ -2092,6 +2240,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
MEM_ROOT new_frm_mem;
|
||||
/* Also used for indicating that prelocking is need */
|
||||
TABLE_LIST **query_tables_last_own;
|
||||
bool safe_to_ignore_table;
|
||||
|
||||
DBUG_ENTER("open_tables");
|
||||
/*
|
||||
temporary mem_root for new .frm parsing.
|
||||
|
@ -2145,8 +2295,13 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
For every table in the list of tables to open, try to find or open
|
||||
a table.
|
||||
*/
|
||||
for (tables= *start; tables ;tables= tables->next_global)
|
||||
{
|
||||
safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
|
||||
/*
|
||||
Ignore placeholders for derived tables. After derived tables
|
||||
processing, link to created temporary table will be put here.
|
||||
|
@ -2159,6 +2314,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
goto process_view_routines;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
If this TABLE_LIST object is a placeholder for an information_schema
|
||||
table, create a temporary table to represent the information_schema
|
||||
table in the query. Do not fill it yet - will be filled during
|
||||
execution.
|
||||
*/
|
||||
if (tables->schema_table)
|
||||
{
|
||||
if (!mysql_schema_table(thd, thd->lex, tables))
|
||||
|
@ -2166,9 +2327,32 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
(*counter)++;
|
||||
|
||||
if (!tables->table &&
|
||||
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags)))
|
||||
|
||||
/*
|
||||
Not a placeholder: must be a base table or a view, and the table is
|
||||
not opened yet. Try to open the table.
|
||||
*/
|
||||
if (!tables->table)
|
||||
{
|
||||
if (tables->prelocking_placeholder)
|
||||
{
|
||||
/*
|
||||
For the tables added by the pre-locking code, attempt to open
|
||||
the table but fail silently if the table does not exist.
|
||||
The real failure will occur when/if a statement attempts to use
|
||||
that table.
|
||||
*/
|
||||
Prelock_error_handler prelock_handler;
|
||||
thd->push_internal_handler(& prelock_handler);
|
||||
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||
thd->pop_internal_handler();
|
||||
safe_to_ignore_table= prelock_handler.safely_trapped_errors();
|
||||
}
|
||||
else
|
||||
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||
}
|
||||
|
||||
if (!tables->table)
|
||||
{
|
||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||
|
||||
|
@ -2219,6 +2403,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
close_tables_for_reopen(thd, start);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (safe_to_ignore_table)
|
||||
{
|
||||
DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'",
|
||||
tables->db, tables->alias));
|
||||
continue;
|
||||
}
|
||||
|
||||
result= -1; // Fatal error
|
||||
break;
|
||||
}
|
||||
|
@ -2273,7 +2465,7 @@ process_view_routines:
|
|||
{
|
||||
/*
|
||||
Serious error during reading stored routines from mysql.proc table.
|
||||
Something's wrong with the table or its contents, and an error has
|
||||
Something is wrong with the table or its contents, and an error has
|
||||
been emitted; we must abort.
|
||||
*/
|
||||
result= -1;
|
||||
|
@ -2522,7 +2714,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
|
|||
static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
|
||||
{
|
||||
for (; table; table= table->next_global)
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
table->table->query_id= 0;
|
||||
}
|
||||
|
||||
|
@ -2594,7 +2786,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
DBUG_RETURN(-1);
|
||||
for (table= tables; table; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
*(ptr++)= table->table;
|
||||
}
|
||||
|
||||
|
@ -2636,7 +2828,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
|
||||
for (table= tables; table != first_not_own; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
{
|
||||
table->table->query_id= thd->query_id;
|
||||
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||
|
@ -2663,7 +2855,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
|
||||
for (table= tables; table != first_not_own; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table &&
|
||||
if (!table->placeholder() &&
|
||||
check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||
{
|
||||
ha_rollback_stmt(thd);
|
||||
|
|
|
@ -1765,8 +1765,18 @@ void Query_cache::free_cache()
|
|||
{
|
||||
DBUG_ENTER("Query_cache::free_cache");
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
flush_cache();
|
||||
/*
|
||||
There may be two free_cache() calls in progress, because we
|
||||
release 'structure_guard_mutex' in flush_cache(). When the second
|
||||
flush_cache() wakes up from the wait on 'COND_flush_finished', the
|
||||
first call to free_cache() has done its job. So we have to test
|
||||
'query_cache_size > 0' the second time to see if the cache wasn't
|
||||
reset by other thread, or if it was reset and was re-enabled then.
|
||||
If the cache was reset, then we have nothing to do here.
|
||||
*/
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
if (bins[0].free_blocks == 0)
|
||||
{
|
||||
|
@ -1808,6 +1818,12 @@ void Query_cache::free_cache()
|
|||
flush_in_progress flag and releases the lock, so other threads may
|
||||
proceed skipping the cache as if it is disabled. Concurrent
|
||||
flushes are performed in turn.
|
||||
|
||||
After flush_cache() call, the cache is flushed, all the freed
|
||||
memory is accumulated in bin[0], and the 'structure_guard_mutex'
|
||||
is locked. However, since we could release the mutex during
|
||||
execution, the rest of the cache state could have been changed,
|
||||
and should not be relied on.
|
||||
*/
|
||||
|
||||
void Query_cache::flush_cache()
|
||||
|
|
|
@ -277,6 +277,38 @@ THD::THD()
|
|||
substitute_null_with_insert_id = FALSE;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||
|
||||
m_internal_handler= NULL;
|
||||
}
|
||||
|
||||
|
||||
void THD::push_internal_handler(Internal_error_handler *handler)
|
||||
{
|
||||
/*
|
||||
TODO: The current implementation is limited to 1 handler at a time only.
|
||||
THD and sp_rcontext need to be modified to use a common handler stack.
|
||||
*/
|
||||
DBUG_ASSERT(m_internal_handler == NULL);
|
||||
m_internal_handler= handler;
|
||||
}
|
||||
|
||||
|
||||
bool THD::handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level)
|
||||
{
|
||||
if (m_internal_handler)
|
||||
{
|
||||
return m_internal_handler->handle_error(sql_errno, level, this);
|
||||
}
|
||||
|
||||
return FALSE; // 'FALSE', as per coding style
|
||||
}
|
||||
|
||||
|
||||
void THD::pop_internal_handler()
|
||||
{
|
||||
DBUG_ASSERT(m_internal_handler != NULL);
|
||||
m_internal_handler= NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,6 +353,7 @@ void THD::init(void)
|
|||
|
||||
void THD::init_for_queries()
|
||||
{
|
||||
set_time();
|
||||
ha_enable_transaction(this,TRUE);
|
||||
|
||||
reset_root_defaults(mem_root, variables.query_alloc_block_size,
|
||||
|
|
|
@ -1071,6 +1071,48 @@ public:
|
|||
SAVEPOINT *savepoints;
|
||||
};
|
||||
|
||||
/**
|
||||
This class represents the interface for internal error handlers.
|
||||
Internal error handlers are exception handlers used by the server
|
||||
implementation.
|
||||
*/
|
||||
class Internal_error_handler
|
||||
{
|
||||
protected:
|
||||
Internal_error_handler() {}
|
||||
virtual ~Internal_error_handler() {}
|
||||
|
||||
public:
|
||||
/**
|
||||
Handle an error condition.
|
||||
This method can be implemented by a subclass to achieve any of the
|
||||
following:
|
||||
- mask an error internally, prevent exposing it to the user,
|
||||
- mask an error and throw another one instead.
|
||||
When this method returns true, the error condition is considered
|
||||
'handled', and will not be propagated to upper layers.
|
||||
It is the responsability of the code installing an internal handler
|
||||
to then check for trapped conditions, and implement logic to recover
|
||||
from the anticipated conditions trapped during runtime.
|
||||
|
||||
This mechanism is similar to C++ try/throw/catch:
|
||||
- 'try' correspond to <code>THD::push_internal_handler()</code>,
|
||||
- 'throw' correspond to <code>my_error()</code>,
|
||||
which invokes <code>my_message_sql()</code>,
|
||||
- 'catch' correspond to checking how/if an internal handler was invoked,
|
||||
before removing it from the exception stack with
|
||||
<code>THD::pop_internal_handler()</code>.
|
||||
|
||||
@param sql_errno the error number
|
||||
@param level the error level
|
||||
@param thd the calling thread
|
||||
@return true if the error is handled
|
||||
*/
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
THD *thd) = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
For each client connection we create a separate thread with THD serving as
|
||||
|
@ -1659,6 +1701,31 @@ public:
|
|||
*p_db_length= db_length;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
Add an internal error handler to the thread execution context.
|
||||
@param handler the exception handler to add
|
||||
*/
|
||||
void push_internal_handler(Internal_error_handler *handler);
|
||||
|
||||
/**
|
||||
Handle an error condition.
|
||||
@param sql_errno the error number
|
||||
@param level the error level
|
||||
@return true if the error is handled
|
||||
*/
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level);
|
||||
|
||||
/**
|
||||
Remove the error handler last pushed.
|
||||
*/
|
||||
void pop_internal_handler();
|
||||
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -99,6 +99,16 @@ void lex_free(void)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
st_parsing_options::reset()
|
||||
{
|
||||
allows_variable= TRUE;
|
||||
allows_select_into= TRUE;
|
||||
allows_select_procedure= TRUE;
|
||||
allows_derived= TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is called before every query that is to be parsed.
|
||||
Because of this, it's critical to not do too much things here.
|
||||
|
@ -149,6 +159,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
|
|||
lex->safe_to_cache_query= 1;
|
||||
lex->time_zone_tables_used= 0;
|
||||
lex->leaf_tables_insert= 0;
|
||||
lex->parsing_options.reset();
|
||||
lex->empty_field_list_on_rset= 0;
|
||||
lex->select_lex.select_number= 1;
|
||||
lex->next_state=MY_LEX_START;
|
||||
|
|
|
@ -891,10 +891,8 @@ struct st_parsing_options
|
|||
bool allows_select_procedure;
|
||||
bool allows_derived;
|
||||
|
||||
st_parsing_options()
|
||||
: allows_variable(TRUE), allows_select_into(TRUE),
|
||||
allows_select_procedure(TRUE), allows_derived(TRUE)
|
||||
{}
|
||||
st_parsing_options() { reset(); }
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1162,7 +1162,6 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||
thd->version= refresh_version;
|
||||
thd->proc_info= 0;
|
||||
thd->command= COM_SLEEP;
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
|
||||
if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
|
||||
|
@ -1178,7 +1177,6 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||
sql_print_warning("%s", net->last_error);
|
||||
}
|
||||
thd->proc_info=0;
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
}
|
||||
|
||||
|
@ -1313,6 +1311,7 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||
mode we have only one thread.
|
||||
*/
|
||||
thd->query_id=next_query_id();
|
||||
thd->set_time();
|
||||
mysql_parse(thd,thd->query,length);
|
||||
close_thread_tables(thd); // Free tables
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ reopen_tables:
|
|||
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
||||
tl->updating= 0;
|
||||
/* Update TABLE::lock_type accordingly. */
|
||||
if (!tl->placeholder() && !tl->schema_table && !using_lock_tables)
|
||||
if (!tl->placeholder() && !using_lock_tables)
|
||||
tl->table->reginfo.lock_type= tl->lock_type;
|
||||
}
|
||||
}
|
||||
|
|
186
sql/sql_yacc.yy
186
sql/sql_yacc.yy
|
@ -52,22 +52,13 @@ const LEX_STRING null_lex_str={0,0};
|
|||
ER_WARN_DEPRECATED_SYNTAX, \
|
||||
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
|
||||
|
||||
#define YYERROR_UNLESS(A) \
|
||||
#define YYABORT_UNLESS(A) \
|
||||
if (!(A)) \
|
||||
{ \
|
||||
yyerror(ER(ER_SYNTAX_ERROR)); \
|
||||
YYABORT; \
|
||||
}
|
||||
|
||||
/* Helper for parsing "IS [NOT] truth_value" */
|
||||
inline Item *is_truth_value(Item *A, bool v1, bool v2)
|
||||
{
|
||||
return new Item_func_if(create_func_ifnull(A,
|
||||
new Item_int((char *) (v2 ? "TRUE" : "FALSE"), v2, 1)),
|
||||
new Item_int((char *) (v1 ? "TRUE" : "FALSE"), v1, 1),
|
||||
new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1));
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
#define YYDEBUG 1
|
||||
#else
|
||||
|
@ -277,6 +268,81 @@ void case_stmt_action_end_case(LEX *lex, bool simple)
|
|||
lex->sphead->do_cont_backpatch();
|
||||
}
|
||||
|
||||
/**
|
||||
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
|
||||
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
|
||||
This function returns the proper item for the SQL expression
|
||||
<code>left [NOT] IN ( expr )</code>
|
||||
@param thd the current thread
|
||||
@param left the in predicand
|
||||
@param equal true for IN predicates, false for NOT IN predicates
|
||||
@param expr first and only expression of the in value list
|
||||
@return an expression representing the IN predicate.
|
||||
*/
|
||||
Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
|
||||
Item *expr)
|
||||
{
|
||||
/*
|
||||
Relevant references for this issue:
|
||||
- SQL:2003, Part 2, section 8.4 <in predicate>, page 383,
|
||||
- SQL:2003, Part 2, section 7.2 <row value expression>, page 296,
|
||||
- SQL:2003, Part 2, section 6.3 <value expression primary>, page 174,
|
||||
- SQL:2003, Part 2, section 7.15 <subquery>, page 370,
|
||||
- SQL:2003 Feature F561, "Full value expressions".
|
||||
|
||||
The exception in SQL:2003 Note 184 means:
|
||||
Item_singlerow_subselect, which corresponds to a <scalar subquery>,
|
||||
should be re-interpreted as an Item_in_subselect, which corresponds
|
||||
to a <table subquery> when used inside an <in predicate>.
|
||||
|
||||
Our reading of Note 184 is reccursive, so that all:
|
||||
- IN (( <subquery> ))
|
||||
- IN ((( <subquery> )))
|
||||
- IN '('^N <subquery> ')'^N
|
||||
- etc
|
||||
should be interpreted as a <table subquery>, no matter how deep in the
|
||||
expression the <subquery> is.
|
||||
*/
|
||||
|
||||
Item *result;
|
||||
|
||||
DBUG_ENTER("handle_sql2003_note184_exception");
|
||||
|
||||
if (expr->type() == Item::SUBSELECT_ITEM)
|
||||
{
|
||||
Item_subselect *expr2 = (Item_subselect*) expr;
|
||||
|
||||
if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
|
||||
{
|
||||
Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
|
||||
st_select_lex *subselect;
|
||||
|
||||
/*
|
||||
Implement the mandated change, by altering the semantic tree:
|
||||
left IN Item_singlerow_subselect(subselect)
|
||||
is modified to
|
||||
left IN (subselect)
|
||||
which is represented as
|
||||
Item_in_subselect(left, subselect)
|
||||
*/
|
||||
subselect= expr3->invalidate_and_restore_select_lex();
|
||||
result= new (thd->mem_root) Item_in_subselect(left, subselect);
|
||||
|
||||
if (! equal)
|
||||
result = negate_expression(thd, result);
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (equal)
|
||||
result= new (thd->mem_root) Item_func_eq(left, expr);
|
||||
else
|
||||
result= new (thd->mem_root) Item_func_ne(left, expr);
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
%}
|
||||
%union {
|
||||
int num;
|
||||
|
@ -323,6 +389,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%}
|
||||
|
||||
%pure_parser /* We have threads */
|
||||
/*
|
||||
Currently there is 251 shift/reduce conflict. We should not introduce
|
||||
new conflicts any more.
|
||||
*/
|
||||
%expect 251
|
||||
|
||||
%token END_OF_INPUT
|
||||
|
||||
|
@ -4393,13 +4464,18 @@ bool_factor:
|
|||
| bool_test ;
|
||||
|
||||
bool_test:
|
||||
bool_pri IS TRUE_SYM { $$= is_truth_value($1,1,0); }
|
||||
| bool_pri IS not TRUE_SYM { $$= is_truth_value($1,0,0); }
|
||||
| bool_pri IS FALSE_SYM { $$= is_truth_value($1,0,1); }
|
||||
| bool_pri IS not FALSE_SYM { $$= is_truth_value($1,1,1); }
|
||||
| bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
|
||||
| bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
|
||||
| bool_pri ;
|
||||
bool_pri IS TRUE_SYM
|
||||
{ $$= new (YYTHD->mem_root) Item_func_istrue($1); }
|
||||
| bool_pri IS not TRUE_SYM
|
||||
{ $$= new (YYTHD->mem_root) Item_func_isnottrue($1); }
|
||||
| bool_pri IS FALSE_SYM
|
||||
{ $$= new (YYTHD->mem_root) Item_func_isfalse($1); }
|
||||
| bool_pri IS not FALSE_SYM
|
||||
{ $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); }
|
||||
| bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
|
||||
| bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
|
||||
| bool_pri
|
||||
;
|
||||
|
||||
bool_pri:
|
||||
bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); }
|
||||
|
@ -4412,31 +4488,37 @@ bool_pri:
|
|||
| predicate ;
|
||||
|
||||
predicate:
|
||||
bit_expr IN_SYM '(' subselect ')'
|
||||
{ $$= new Item_in_subselect($1, $4); }
|
||||
| bit_expr not IN_SYM '(' subselect ')'
|
||||
{ $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); }
|
||||
bit_expr IN_SYM '(' subselect ')'
|
||||
{
|
||||
$$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
|
||||
}
|
||||
| bit_expr not IN_SYM '(' subselect ')'
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
|
||||
$$= negate_expression(thd, item);
|
||||
}
|
||||
| bit_expr IN_SYM '(' expr ')'
|
||||
{
|
||||
$$= new Item_func_eq($1, $4);
|
||||
$$= handle_sql2003_note184_exception(YYTHD, $1, true, $4);
|
||||
}
|
||||
| bit_expr IN_SYM '(' expr ',' expr_list ')'
|
||||
{
|
||||
$6->push_front($4);
|
||||
$6->push_front($1);
|
||||
$$= new Item_func_in(*$6);
|
||||
| bit_expr IN_SYM '(' expr ',' expr_list ')'
|
||||
{
|
||||
$6->push_front($4);
|
||||
$6->push_front($1);
|
||||
$$= new (YYTHD->mem_root) Item_func_in(*$6);
|
||||
}
|
||||
| bit_expr not IN_SYM '(' expr ')'
|
||||
{
|
||||
$$= new Item_func_ne($1, $5);
|
||||
$$= handle_sql2003_note184_exception(YYTHD, $1, false, $5);
|
||||
}
|
||||
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
|
||||
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
|
||||
{
|
||||
$7->push_front($5);
|
||||
$7->push_front($1);
|
||||
Item_func_in *item = new Item_func_in(*$7);
|
||||
item->negate();
|
||||
$$= item;
|
||||
$7->push_front($5);
|
||||
$7->push_front($1);
|
||||
Item_func_in *item = new (YYTHD->mem_root) Item_func_in(*$7);
|
||||
item->negate();
|
||||
$$= item;
|
||||
}
|
||||
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
|
||||
{ $$= new Item_func_between($1,$3,$5); }
|
||||
|
@ -5408,7 +5490,7 @@ table_ref:
|
|||
;
|
||||
|
||||
join_table_list:
|
||||
derived_table_list { YYERROR_UNLESS($$=$1); }
|
||||
derived_table_list { YYABORT_UNLESS($$=$1); }
|
||||
;
|
||||
|
||||
/* Warning - may return NULL in case of incomplete SELECT */
|
||||
|
@ -5416,7 +5498,7 @@ derived_table_list:
|
|||
table_ref { $$=$1; }
|
||||
| derived_table_list ',' table_ref
|
||||
{
|
||||
YYERROR_UNLESS($1 && ($$=$3));
|
||||
YYABORT_UNLESS($1 && ($$=$3));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -5435,13 +5517,13 @@ join_table:
|
|||
left-associative joins.
|
||||
*/
|
||||
table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
|
||||
{ YYERROR_UNLESS($1 && ($$=$3)); }
|
||||
{ YYABORT_UNLESS($1 && ($$=$3)); }
|
||||
| table_ref STRAIGHT_JOIN table_factor
|
||||
{ YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; }
|
||||
{ YYABORT_UNLESS($1 && ($$=$3)); $3->straight=1; }
|
||||
| table_ref normal_join table_ref
|
||||
ON
|
||||
{
|
||||
YYERROR_UNLESS($1 && $3);
|
||||
YYABORT_UNLESS($1 && $3);
|
||||
/* Change the current name resolution context to a local context. */
|
||||
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||
YYABORT;
|
||||
|
@ -5456,7 +5538,7 @@ join_table:
|
|||
| table_ref STRAIGHT_JOIN table_factor
|
||||
ON
|
||||
{
|
||||
YYERROR_UNLESS($1 && $3);
|
||||
YYABORT_UNLESS($1 && $3);
|
||||
/* Change the current name resolution context to a local context. */
|
||||
if (push_new_name_resolution_context(YYTHD, $1, $3))
|
||||
YYABORT;
|
||||
|
@ -5472,13 +5554,13 @@ join_table:
|
|||
| table_ref normal_join table_ref
|
||||
USING
|
||||
{
|
||||
YYERROR_UNLESS($1 && $3);
|
||||
YYABORT_UNLESS($1 && $3);
|
||||
}
|
||||
'(' using_list ')'
|
||||
{ add_join_natural($1,$3,$7,Select); $$=$3; }
|
||||
| table_ref NATURAL JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && ($$=$4));
|
||||
YYABORT_UNLESS($1 && ($$=$4));
|
||||
add_join_natural($1,$4,NULL,Select);
|
||||
}
|
||||
|
||||
|
@ -5486,7 +5568,7 @@ join_table:
|
|||
| table_ref LEFT opt_outer JOIN_SYM table_ref
|
||||
ON
|
||||
{
|
||||
YYERROR_UNLESS($1 && $5);
|
||||
YYABORT_UNLESS($1 && $5);
|
||||
/* Change the current name resolution context to a local context. */
|
||||
if (push_new_name_resolution_context(YYTHD, $1, $5))
|
||||
YYABORT;
|
||||
|
@ -5502,7 +5584,7 @@ join_table:
|
|||
}
|
||||
| table_ref LEFT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $5);
|
||||
YYABORT_UNLESS($1 && $5);
|
||||
}
|
||||
USING '(' using_list ')'
|
||||
{
|
||||
|
@ -5512,7 +5594,7 @@ join_table:
|
|||
}
|
||||
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $6);
|
||||
YYABORT_UNLESS($1 && $6);
|
||||
add_join_natural($1,$6,NULL,Select);
|
||||
$6->outer_join|=JOIN_TYPE_LEFT;
|
||||
$$=$6;
|
||||
|
@ -5522,7 +5604,7 @@ join_table:
|
|||
| table_ref RIGHT opt_outer JOIN_SYM table_ref
|
||||
ON
|
||||
{
|
||||
YYERROR_UNLESS($1 && $5);
|
||||
YYABORT_UNLESS($1 && $5);
|
||||
/* Change the current name resolution context to a local context. */
|
||||
if (push_new_name_resolution_context(YYTHD, $1, $5))
|
||||
YYABORT;
|
||||
|
@ -5539,7 +5621,7 @@ join_table:
|
|||
}
|
||||
| table_ref RIGHT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $5);
|
||||
YYABORT_UNLESS($1 && $5);
|
||||
}
|
||||
USING '(' using_list ')'
|
||||
{
|
||||
|
@ -5550,7 +5632,7 @@ join_table:
|
|||
}
|
||||
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $6);
|
||||
YYABORT_UNLESS($1 && $6);
|
||||
add_join_natural($6,$1,NULL,Select);
|
||||
LEX *lex= Lex;
|
||||
if (!($$= lex->current_select->convert_right_join()))
|
||||
|
@ -5593,7 +5675,7 @@ table_factor:
|
|||
expr '}'
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
YYERROR_UNLESS($3 && $7);
|
||||
YYABORT_UNLESS($3 && $7);
|
||||
add_join_on($7,$10);
|
||||
Lex->pop_context();
|
||||
$7->outer_join|=JOIN_TYPE_LEFT;
|
||||
|
@ -9645,21 +9727,21 @@ xa: XA_SYM begin_or_start xid opt_join_or_resume
|
|||
|
||||
xid: text_string
|
||||
{
|
||||
YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE);
|
||||
YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
|
||||
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
|
||||
YYABORT;
|
||||
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
|
||||
}
|
||||
| text_string ',' text_string
|
||||
{
|
||||
YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
|
||||
YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
|
||||
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
|
||||
YYABORT;
|
||||
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
|
||||
}
|
||||
| text_string ',' text_string ',' ulong_num
|
||||
{
|
||||
YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
|
||||
YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
|
||||
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
|
||||
YYABORT;
|
||||
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
|
||||
|
|
|
@ -2080,7 +2080,9 @@ void st_table_list::hide_view_error(THD *thd)
|
|||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
|
||||
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR)
|
||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_TABLE_NOT_LOCKED ||
|
||||
thd->net.last_errno == ER_NO_SUCH_TABLE)
|
||||
{
|
||||
TABLE_LIST *top= top_table();
|
||||
thd->clear_error();
|
||||
|
|
|
@ -649,7 +649,7 @@ typedef struct st_table_list
|
|||
int view_check_option(THD *thd, bool ignore_failure);
|
||||
bool setup_underlying(THD *thd);
|
||||
void cleanup_items();
|
||||
bool placeholder() {return derived || view; }
|
||||
bool placeholder() {return derived || view || schema_table || !table; }
|
||||
void print(THD *thd, String *str);
|
||||
bool check_single_table(st_table_list **table, table_map map,
|
||||
st_table_list *view);
|
||||
|
|
Loading…
Add table
Reference in a new issue