Commit b4a3083d authored by Martin Hansson's avatar Martin Hansson

Backport of Bug#33204 from mysql-pe to

mysql-next-mr-bugfixing.

Bug no 32858 was fixed in two different ways in what was
then called mysql 5.1 and 6.0. The fix in 6.0 was very
different since bugfix no 33204 was present.  Furthermore,
the two fixes were not compatible. Hence in order to
backport Bug#33204 to the 5.1-based mysql-next-mr-bugfixing,
it was necessary to remove the 5.1 fix of 32858 and apply
the 6.0 version of the fix.
parent d17f4d9d
...@@ -3562,9 +3562,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS ...@@ -3562,9 +3562,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
(SELECT i FROM t1) UNION (SELECT i FROM t1) UNION
(SELECT i FROM t1) (SELECT i FROM t1)
); );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION i
(SELECT i FROM t1)
)' at line 3
SELECT * FROM t1 SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT i FROM t1)))' at line 2 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT i FROM t1)))' at line 2
...@@ -3574,7 +3572,11 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp ...@@ -3574,7 +3572,11 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
from t1' at line 1 from t1' at line 1
explain select * from t1 where not exists explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12)); ((select t11.i from t1 t11) union (select t12.i from t1 t12));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select t12.i from t1 t12))' at line 2 id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b)); CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
insert into t1 (a) values (FLOOR(rand() * 100)); insert into t1 (a) values (FLOOR(rand() * 100));
...@@ -4279,8 +4281,15 @@ Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `te ...@@ -4279,8 +4281,15 @@ Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `te
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a)); (SELECT 1 FROM t2 WHERE t1.a = t2.a));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION id select_type table type possible_keys key key_len ref rows filtered Extra
(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 2 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1(f11 int, f12 int); create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
...@@ -4564,4 +4573,268 @@ id g v s ...@@ -4564,4 +4573,268 @@ id g v s
51 50 NULL l 51 50 NULL l
61 60 NULL l 61 60 NULL l
drop table t1, t2; drop table t1, t2;
#
# Bug#33204: INTO is allowed in subselect, causing inconsistent results
#
CREATE TABLE t1( a INT );
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @var FROM t1 WHERE a = 2
) t1a' at line 4
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a' at line 4
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a' at line 4
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
SELECT * FROM (
SELECT a FROM t1 WHERE a = 2
UNION
SELECT a FROM t1 WHERE a = 2
) t1a;
a
2
SELECT * FROM (
SELECT 1 a
UNION
SELECT a FROM t1 WHERE a = 2
UNION
SELECT a FROM t1 WHERE a = 2
) t1a;
a
1
2
SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias;
a
1
SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a)) t1a' at line 1
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )) t1a' at line 1
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a)) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a))) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' ))) t1a' at line 1
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' ))) t1a' at line 1
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a) t1a;
a
1
SELECT * FROM (SELECT 1 a UNION SELECT 1 a LIMIT 1) t1a;
a
1
SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a;
a
1
SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1;
a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
a a
1 1
2 1
1 2
2 2
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
a a
1 1
2 1
1 2
2 2
SELECT * FROM (t1 t1a);
a
1
2
SELECT * FROM ((t1 t1a));
a
1
2
SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 t1a)) alias ON 1;
a t1a
1 1
2 1
SELECT * FROM t1 JOIN (SELECT 1 a) a ON 1;
a a
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 a)) a ON 1;
a a
1 1
2 1
SELECT * FROM (t1 JOIN (SELECT 1) t1a1 ON 1) t1a2;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1a2' at line 1
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a)' at line 1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )' at line 1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a)' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @a)' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )' at line 1
SELECT ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
SELECT ( SELECT 1 INTO OUTFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )' at line 1
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )' at line 1
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO OUTFILE 'file' )' at line 1
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO DUMPFILE 'file' )' at line 1
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
1 2
SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ) a
1 1
1 2
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
SELECT 1 UNION ( SELECT 1 UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 )' at line 1
( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) UNION SELECT 1' at line 1
SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1' at line 1
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') UNION SELECT 1 )' at line 1
SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) )' at line 1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 )' at line 1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT 1 )' at line 1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @test)' at line 1
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
DROP TABLE t1, t2;
End of 5.1 tests. End of 5.1 tests.
...@@ -153,48 +153,6 @@ ERROR 42S22: Unknown column 'a' in 'field list' ...@@ -153,48 +153,6 @@ ERROR 42S22: Unknown column 'a' in 'field list'
1 3 1 3
1 3 1 3
2 1 2 1
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO @v FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1
) alias;
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1;
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO OUTFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO DUMPFILE '<MYSQLTEST_VARDIR>/tmp/union.out.file' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
DROP TABLE t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
`pseudo` char(35) NOT NULL default '', `pseudo` char(35) NOT NULL default '',
`pseudo1` char(35) NOT NULL default '', `pseudo1` char(35) NOT NULL default '',
...@@ -1588,3 +1546,39 @@ Warnings: ...@@ -1588,3 +1546,39 @@ Warnings:
Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a` Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a`
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
#
# Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
# subselects into account
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
# Tests fix in parser rule select_derived_union.
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
SELECT a INTO OUTFILE 'union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a INTO DUMPFILE 'union.out.file2' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
# Tests fix in parser rule query_expression_body.
SELECT ( SELECT a UNION SELECT a ) INTO @v FROM t1;
SELECT ( SELECT a UNION SELECT a ) INTO OUTFILE 'union.out.file3' FROM t1;
SELECT ( SELECT a UNION SELECT a ) INTO DUMPFILE 'union.out.file4' FROM t1;
DROP TABLE t1;
...@@ -2513,8 +2513,6 @@ DROP TABLE t1, t2; ...@@ -2513,8 +2513,6 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (i INT); CREATE TABLE t1 (i INT);
(SELECT i FROM t1) UNION (SELECT i FROM t1); (SELECT i FROM t1) UNION (SELECT i FROM t1);
#TODO:not supported
--error ER_PARSE_ERROR
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
( (
(SELECT i FROM t1) UNION (SELECT i FROM t1) UNION
...@@ -2531,8 +2529,6 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); ...@@ -2531,8 +2529,6 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1; from t1;
#TODO:not supported
--error ER_PARSE_ERROR
explain select * from t1 where not exists explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12)); ((select t11.i from t1 t11) union (select t12.i from t1 t12));
...@@ -3203,8 +3199,6 @@ EXPLAIN EXTENDED ...@@ -3203,8 +3199,6 @@ EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
#TODO:not supported
--error ER_PARSE_ERROR
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a)); (SELECT 1 FROM t2 WHERE t1.a = t2.a));
...@@ -3544,4 +3538,231 @@ where v in(select v ...@@ -3544,4 +3538,231 @@ where v in(select v
where t1.g=t2.g) is unknown; where t1.g=t2.g) is unknown;
drop table t1, t2; drop table t1, t2;
-- echo #
-- echo # Bug#33204: INTO is allowed in subselect, causing inconsistent results
-- echo #
CREATE TABLE t1( a INT );
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
--error ER_PARSE_ERROR
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
--error ER_PARSE_ERROR
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
--error ER_PARSE_ERROR
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
SELECT * FROM (
SELECT a FROM t1 WHERE a = 2
UNION
SELECT a FROM t1 WHERE a = 2
) t1a;
SELECT * FROM (
SELECT 1 a
UNION
SELECT a FROM t1 WHERE a = 2
UNION
SELECT a FROM t1 WHERE a = 2
) t1a;
# This was not allowed previously. Possibly, it should be allowed on the future.
# For now, the intent is to keep the fix as non-intrusive as possible.
--error ER_PARSE_ERROR
SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a);
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias;
SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
--error ER_PARSE_ERROR
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
--error ER_PARSE_ERROR
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
--error ER_PARSE_ERROR
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
--error ER_PARSE_ERROR
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a) t1a;
SELECT * FROM (SELECT 1 a UNION SELECT 1 a LIMIT 1) t1a;
SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a;
# Test of rule
# table_factor: '(' get_select_lex query_expression_body ')' opt_table_alias
# UNION should not be allowed inside the parentheses, nor should
# aliases after.
#
SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1;
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
SELECT * FROM (t1 t1a);
SELECT * FROM ((t1 t1a));
SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
SELECT * FROM t1 JOIN ((SELECT 1 t1a)) alias ON 1;
SELECT * FROM t1 JOIN (SELECT 1 a) a ON 1;
SELECT * FROM t1 JOIN ((SELECT 1 a)) a ON 1;
# For the join, TABLE_LIST::select_lex == NULL
# Check that we handle this.
--error ER_PARSE_ERROR
SELECT * FROM (t1 JOIN (SELECT 1) t1a1 ON 1) t1a2;
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 );
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
SELECT * FROM t1 WHERE a = ( SELECT 1 );
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 INTO @v );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 INTO OUTFILE 'file' );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
--error ER_PARSE_ERROR
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
# Make sure context is popped when we leave the nested select
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
# Make sure we have feature F561 (see .yy file)
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
# Make sure the parser does not allow nested UNIONs anywhere
--error ER_PARSE_ERROR
SELECT 1 UNION ( SELECT 1 UNION SELECT 1 );
--error ER_PARSE_ERROR
( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
--error ER_PARSE_ERROR
SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
--error ER_PARSE_ERROR
SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
SELECT EXISTS(SELECT 1+1);
--error ER_PARSE_ERROR
SELECT EXISTS(SELECT 1+1 INTO @test);
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
DROP TABLE t1, t2;
--echo End of 5.1 tests. --echo End of 5.1 tests.
...@@ -91,88 +91,6 @@ SELECT @a:=1 UNION SELECT @a:=@a+1; ...@@ -91,88 +91,6 @@ SELECT @a:=1 UNION SELECT @a:=@a+1;
(SELECT 1) UNION (SELECT 2) ORDER BY (SELECT a); (SELECT 1) UNION (SELECT 2) ORDER BY (SELECT a);
(SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2); (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
#
# Bug#32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects
# into account
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
--let $outfile = $MYSQLTEST_VARDIR/tmp/union.out.file
--error 0,1
--remove_file $outfile
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a INTO OUTFILE '$outfile' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
--remove_file $outfile
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a INTO DUMPFILE '$outfile' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
--remove_file $outfile
#
# INTO will not be allowed in subqueries in version 5.1 and above.
#
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO @v FROM t1
) alias;
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO OUTFILE '$outfile' FROM t1
) alias;
--remove_file $outfile
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO DUMPFILE '$outfile' FROM t1
) alias;
--remove_file $outfile
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a FROM t1 UNION SELECT a INTO OUTFILE '$outfile' FROM t1;
--remove_file $outfile
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
eval SELECT a FROM t1 UNION SELECT a INTO DUMPFILE '$outfile' FROM t1;
--remove_file $outfile
--error ER_WRONG_USAGE
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
--error ER_WRONG_USAGE
eval SELECT a INTO OUTFILE '$outfile' FROM t1 UNION SELECT a FROM t1;
--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
--error ER_WRONG_USAGE
eval SELECT a INTO DUMPFILE '$outfile' FROM t1 UNION SELECT a FROM t1;
DROP TABLE t1;
# #
# Test bug reported by joc@presence-pc.com # Test bug reported by joc@presence-pc.com
# #
...@@ -1102,3 +1020,45 @@ DROP TABLE t1; ...@@ -1102,3 +1020,45 @@ DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
-- echo #
-- echo # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
-- echo # subselects into account
-- echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
-- echo # Tests fix in parser rule select_derived_union.
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
SELECT a INTO OUTFILE 'union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a INTO DUMPFILE 'union.out.file2' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
-- echo # Tests fix in parser rule query_expression_body.
SELECT ( SELECT a UNION SELECT a ) INTO @v FROM t1;
SELECT ( SELECT a UNION SELECT a ) INTO OUTFILE 'union.out.file3' FROM t1;
SELECT ( SELECT a UNION SELECT a ) INTO DUMPFILE 'union.out.file4' FROM t1;
DROP TABLE t1;
...@@ -1626,7 +1626,6 @@ void THD::rollback_item_tree_changes() ...@@ -1626,7 +1626,6 @@ void THD::rollback_item_tree_changes()
select_result::select_result() select_result::select_result()
{ {
thd=current_thd; thd=current_thd;
nest_level= -1;
} }
void select_result::send_error(uint errcode,const char *err) void select_result::send_error(uint errcode,const char *err)
......
...@@ -2381,7 +2381,6 @@ class select_result :public Sql_alloc { ...@@ -2381,7 +2381,6 @@ class select_result :public Sql_alloc {
protected: protected:
THD *thd; THD *thd;
SELECT_LEX_UNIT *unit; SELECT_LEX_UNIT *unit;
uint nest_level;
public: public:
select_result(); select_result();
virtual ~select_result() {}; virtual ~select_result() {};
...@@ -2418,12 +2417,6 @@ class select_result :public Sql_alloc { ...@@ -2418,12 +2417,6 @@ class select_result :public Sql_alloc {
*/ */
virtual void cleanup(); virtual void cleanup();
void set_thd(THD *thd_arg) { thd= thd_arg; } void set_thd(THD *thd_arg) { thd= thd_arg; }
/**
The nest level, if supported.
@return
-1 if nest level is undefined, otherwise a positive integer.
*/
int get_nest_level() { return nest_level; }
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
virtual void begin_dataset() {} virtual void begin_dataset() {}
#else #else
...@@ -2518,14 +2511,6 @@ class select_export :public select_to_file { ...@@ -2518,14 +2511,6 @@ class select_export :public select_to_file {
CHARSET_INFO *write_cs; // output charset CHARSET_INFO *write_cs; // output charset
public: public:
select_export(sql_exchange *ex) :select_to_file(ex) {} select_export(sql_exchange *ex) :select_to_file(ex) {}
/**
Creates a select_export to represent INTO OUTFILE <filename> with a
defined level of subquery nesting.
*/
select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex)
{
nest_level= nest_level_arg;
}
~select_export(); ~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
...@@ -2535,15 +2520,6 @@ class select_export :public select_to_file { ...@@ -2535,15 +2520,6 @@ class select_export :public select_to_file {
class select_dump :public select_to_file { class select_dump :public select_to_file {
public: public:
select_dump(sql_exchange *ex) :select_to_file(ex) {} select_dump(sql_exchange *ex) :select_to_file(ex) {}
/**
Creates a select_export to represent INTO DUMPFILE <filename> with a
defined level of subquery nesting.
*/
select_dump(sql_exchange *ex, uint nest_level_arg) :
select_to_file(ex)
{
nest_level= nest_level_arg;
}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
}; };
...@@ -3014,16 +2990,6 @@ class select_dumpvar :public select_result_interceptor { ...@@ -3014,16 +2990,6 @@ class select_dumpvar :public select_result_interceptor {
public: public:
List<my_var> var_list; List<my_var> var_list;
select_dumpvar() { var_list.empty(); row_count= 0;} select_dumpvar() { var_list.empty(); row_count= 0;}
/**
Creates a select_dumpvar to represent INTO <variable> with a defined
level of subquery nesting.
*/
select_dumpvar(uint nest_level_arg)
{
var_list.empty();
row_count= 0;
nest_level= nest_level_arg;
}
~select_dumpvar() {} ~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
......
...@@ -468,6 +468,90 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, ...@@ -468,6 +468,90 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
DBUG_RETURN(result); DBUG_RETURN(result);
} }
/**
@brief Creates a new SELECT_LEX for a UNION branch.
Sets up and initializes a SELECT_LEX structure for a query once the parser
discovers a UNION token. The current SELECT_LEX is pushed on the stack and
the new SELECT_LEX becomes the current one.
@param lex The parser state.
@param is_union_distinct True if the union preceding the new select statement
uses UNION DISTINCT.
@param is_top_level This should be @c TRUE if the newly created SELECT_LEX
is a non-nested statement.
@return <code>false</code> if successful, <code>true</code> if an error was
reported. In the latter case parsing should stop.
*/
bool add_select_to_union_list(LEX *lex, bool is_union_distinct,
bool is_top_level)
{
/*
Only the last SELECT can have INTO. Since the grammar won't allow INTO in
a nested SELECT, we make this check only when creating a top-level SELECT.
*/
if (is_top_level && lex->result)
{
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
return TRUE;
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
return TRUE;
}
/* This counter shouldn't be incremented for UNION parts */
lex->nest_level--;
if (mysql_new_select(lex, 0))
return TRUE;
mysql_init_select(lex);
lex->current_select->linkage=UNION_TYPE;
if (is_union_distinct) /* UNION DISTINCT - remember position */
lex->current_select->master_unit()->union_distinct=
lex->current_select;
return FALSE;
}
/**
@brief Initializes a SELECT_LEX for a query within parentheses (aka
braces).
@return false if successful, true if an error was reported. In the latter
case parsing should stop.
*/
bool setup_select_in_parentheses(LEX *lex)
{
SELECT_LEX * sel= lex->current_select;
if (sel->set_braces(1))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
return TRUE;
}
if (sel->linkage == UNION_TYPE &&
!sel->master_unit()->first_select()->braces &&
sel->master_unit()->first_select()->linkage ==
UNION_TYPE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
return TRUE;
}
if (sel->linkage == UNION_TYPE &&
sel->olap != UNSPECIFIED_OLAP_TYPE &&
sel->master_unit()->fake_select_lex)
{
my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
return TRUE;
}
/* select in braces, can't contain global parameters */
if (sel->master_unit()->fake_select_lex)
sel->master_unit()->global_parameters=
sel->master_unit()->fake_select_lex;
return FALSE;
}
%} %}
%union { %union {
int num; int num;
...@@ -521,10 +605,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -521,10 +605,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */ %pure_parser /* We have threads */
/* /*
Currently there are 168 shift/reduce conflicts. Currently there are 174 shift/reduce conflicts.
We should not introduce new conflicts any more. We should not introduce new conflicts any more.
*/ */
%expect 168 %expect 174
/* /*
Comments for TOKENS. Comments for TOKENS.
...@@ -1240,6 +1324,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -1240,6 +1324,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
join_table_list join_table join_table_list join_table
table_factor table_ref esc_table_ref table_factor table_ref esc_table_ref
select_derived derived_table_list select_derived derived_table_list
select_derived_union
%type <date_time_type> date_time_type; %type <date_time_type> date_time_type;
%type <interval> interval %type <interval> interval
...@@ -1275,8 +1360,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -1275,8 +1360,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <variable> internal_variable_name %type <variable> internal_variable_name
%type <select_lex> subselect take_first_select %type <select_lex> subselect
get_select_lex get_select_lex query_specification
query_expression_body
%type <boolfunc2creator> comp_op %type <boolfunc2creator> comp_op
...@@ -6757,35 +6843,20 @@ select_init: ...@@ -6757,35 +6843,20 @@ select_init:
select_paren: select_paren:
SELECT_SYM select_part2 SELECT_SYM select_part2
{ {
LEX *lex= Lex; if (setup_select_in_parentheses(Lex))
SELECT_LEX * sel= lex->current_select;
if (sel->set_braces(1))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
if (sel->linkage == UNION_TYPE &&
!sel->master_unit()->first_select()->braces &&
sel->master_unit()->first_select()->linkage ==
UNION_TYPE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (sel->linkage == UNION_TYPE && | '(' select_paren ')'
sel->olap != UNSPECIFIED_OLAP_TYPE && ;
sel->master_unit()->fake_select_lex)
/* The equivalent of select_paren for nested queries. */
select_paren_derived:
SELECT_SYM select_part2_derived
{ {
my_error(ER_WRONG_USAGE, MYF(0), if (setup_select_in_parentheses(Lex))
"CUBE/ROLLUP", "ORDER BY");
MYSQL_YYABORT; MYSQL_YYABORT;
} }
/* select in braces, can't contain global parameters */ | '(' select_paren_derived ')'
if (sel->master_unit()->fake_select_lex)
sel->master_unit()->global_parameters=
sel->master_unit()->fake_select_lex;
}
| '(' select_paren ')'
; ;
select_init2: select_init2:
...@@ -8626,6 +8697,7 @@ when_list: ...@@ -8626,6 +8697,7 @@ when_list:
} }
; ;
/* Equivalent to <table reference> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */ /* Warning - may return NULL in case of incomplete SELECT */
table_ref: table_ref:
table_factor { $$=$1; } table_factor { $$=$1; }
...@@ -8653,6 +8725,7 @@ esc_table_ref: ...@@ -8653,6 +8725,7 @@ esc_table_ref:
| '{' ident table_ref '}' { $$=$3; } | '{' ident table_ref '}' { $$=$3; }
; ;
/* Equivalent to <table reference list> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */ /* Warning - may return NULL in case of incomplete SELECT */
derived_table_list: derived_table_list:
esc_table_ref { $$=$1; } esc_table_ref { $$=$1; }
...@@ -8806,6 +8879,13 @@ normal_join: ...@@ -8806,6 +8879,13 @@ normal_join:
| CROSS JOIN_SYM {} | CROSS JOIN_SYM {}
; ;
/*
This is a flattening of the rules <table factor> and <table primary>
in the SQL:2003 standard, since we don't have <sample clause>
I.e.
<table factor> ::= <table primary> [ <sample clause> ]
*/
/* Warning - may return NULL in case of incomplete SELECT */ /* Warning - may return NULL in case of incomplete SELECT */
table_factor: table_factor:
{ {
...@@ -8843,12 +8923,29 @@ table_factor: ...@@ -8843,12 +8923,29 @@ table_factor:
/* incomplete derived tables return NULL, we must be /* incomplete derived tables return NULL, we must be
nested in select_derived rule to be here. */ nested in select_derived rule to be here. */
} }
| '(' get_select_lex select_derived union_opt ')' opt_table_alias /*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
<table primary> ::= ... | <derived table> [ AS ] <correlation name>
The following rules have been flattened into query_expression_body
(since we have no <with clause>).
<derived table> ::= <table subquery>
<table subquery> ::= <subquery>
<subquery> ::= <left paren> <query expression> <right paren>
<query expression> ::= [ <with clause> ] <query expression body>
For the time being we use the non-standard rule
select_derived_union which is a compromise between the standard
and our parser. Possibly this rule could be replaced by our
query_expression_body.
*/
| '(' get_select_lex select_derived_union ')' opt_table_alias
{ {
/* Use $2 instead of Lex->current_select as derived table will /* Use $2 instead of Lex->current_select as derived table will
alter value of Lex->current_select. */ alter value of Lex->current_select. */
if (!($3 || $5) && $2->embedding &&
if (!($3 || $6) && $2->embedding &&
!$2->embedding->nested_join->join_list.elements) !$2->embedding->nested_join->join_list.elements)
{ {
/* we have a derived table ($3 == NULL) but no alias, /* we have a derived table ($3 == NULL) but no alias,
...@@ -8870,7 +8967,7 @@ table_factor: ...@@ -8870,7 +8967,7 @@ table_factor:
if (ti == NULL) if (ti == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
if (!($$= sel->add_table_to_list(lex->thd, if (!($$= sel->add_table_to_list(lex->thd,
ti, $6, 0, new Table_ident(unit), $5, 0,
TL_READ))) TL_READ)))
MYSQL_YYABORT; MYSQL_YYABORT;
...@@ -8878,7 +8975,8 @@ table_factor: ...@@ -8878,7 +8975,8 @@ table_factor:
lex->pop_context(); lex->pop_context();
lex->nest_level--; lex->nest_level--;
} }
else if ($4 || $6) else if ($3->select_lex &&
$3->select_lex->master_unit()->is_union() || $5)
{ {
/* simple nested joins cannot have aliases or unions */ /* simple nested joins cannot have aliases or unions */
my_parse_error(ER(ER_SYNTAX_ERROR)); my_parse_error(ER(ER_SYNTAX_ERROR));
...@@ -8893,6 +8991,62 @@ table_factor: ...@@ -8893,6 +8991,62 @@ table_factor:
} }
; ;
select_derived_union:
select_derived opt_order_clause opt_limit_clause
| select_derived_union
UNION_SYM
union_option
{
if (add_select_to_union_list(Lex, (bool)$3, FALSE))
MYSQL_YYABORT;
}
query_specification
{
/*
Remove from the name resolution context stack the context of the
last select in the union.
*/
Lex->pop_context();
}
opt_order_clause opt_limit_clause
;
/* The equivalent of select_init2 for nested queries. */
select_init2_derived:
select_part2_derived
{
LEX *lex= Lex;
SELECT_LEX * sel= lex->current_select;
if (lex->current_select->set_braces(0))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
if (sel->linkage == UNION_TYPE &&
sel->master_unit()->first_select()->braces)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
}
;
/* The equivalent of select_part2 for nested queries. */
select_part2_derived:
{
LEX *lex= Lex;
SELECT_LEX *sel= lex->current_select;
if (sel->linkage != UNION_TYPE)
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
}
select_options select_item_list
{
Select->parsing_place= NO_MATTER;
}
opt_select_from select_lock_type
;
/* handle contents of parentheses in join expression */ /* handle contents of parentheses in join expression */
select_derived: select_derived:
get_select_lex get_select_lex
...@@ -9508,8 +9662,7 @@ procedure_item: ...@@ -9508,8 +9662,7 @@ procedure_item:
select_var_list_init: select_var_list_init:
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->describe && if (!lex->describe && (!(lex->result= new select_dumpvar())))
(!(lex->result= new select_dumpvar(lex->nest_level))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
select_var_list select_var_list
...@@ -9590,7 +9743,7 @@ into_destination: ...@@ -9590,7 +9743,7 @@ into_destination:
LEX *lex= Lex; LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT); lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($2.str, 0)) || if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
!(lex->result= new select_export(lex->exchange, lex->nest_level))) !(lex->result= new select_export(lex->exchange)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
opt_load_data_charset opt_load_data_charset
...@@ -9604,7 +9757,7 @@ into_destination: ...@@ -9604,7 +9757,7 @@ into_destination:
lex->uncacheable(UNCACHEABLE_SIDEEFFECT); lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($2.str,1))) if (!(lex->exchange= new sql_exchange($2.str,1)))
MYSQL_YYABORT; MYSQL_YYABORT;
if (!(lex->result= new select_dump(lex->exchange, lex->nest_level))) if (!(lex->result= new select_dump(lex->exchange)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
} }
...@@ -13223,34 +13376,9 @@ union_clause: ...@@ -13223,34 +13376,9 @@ union_clause:
union_list: union_list:
UNION_SYM union_option UNION_SYM union_option
{ {
LEX *lex=Lex; if (add_select_to_union_list(Lex, (bool)$2, TRUE))
if (lex->result &&
(lex->result->get_nest_level() == -1 ||
lex->result->get_nest_level() == lex->nest_level))
{
/*
Only the last SELECT can have INTO unless the INTO and UNION
are at different nest levels. In version 5.1 and above, INTO
will onle be allowed at top level.
*/
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
/* This counter shouldn't be incremented for UNION parts */
Lex->nest_level--;
if (mysql_new_select(lex, 0))
MYSQL_YYABORT;
mysql_init_select(lex);
lex->current_select->linkage=UNION_TYPE;
if ($2) /* UNION DISTINCT - remember position */
lex->current_select->master_unit()->union_distinct=
lex->current_select;
}
select_init select_init
{ {
/* /*
...@@ -13302,22 +13430,39 @@ union_option: ...@@ -13302,22 +13430,39 @@ union_option:
| ALL { $$=0; } | ALL { $$=0; }
; ;
take_first_select: /* empty */ query_specification:
SELECT_SYM select_init2_derived
{ {
$$= Lex->current_select->master_unit()->first_select(); $$= Lex->current_select->master_unit()->first_select();
}; }
| '(' select_paren_derived ')'
{
$$= Lex->current_select->master_unit()->first_select();
}
;
subselect: query_expression_body:
SELECT_SYM subselect_start select_init2 take_first_select query_specification
subselect_end | query_expression_body
UNION_SYM union_option
{ {
$$= $4; if (add_select_to_union_list(Lex, (bool)$3, FALSE))
MYSQL_YYABORT;
} }
| '(' subselect_start select_paren take_first_select query_specification
subselect_end ')'
{ {
$$= $4; Lex->pop_context();
}; $$= $1;
}
;
/* Corresponds to <query expression> in the SQL:2003 standard. */
subselect:
subselect_start query_expression_body subselect_end
{
$$= $2;
}
;
subselect_start: subselect_start:
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment