Bug #32400: Complex SELECT query returns correct result

 only on some occasions

Referencing an element from the SELECT list in a WHERE 
clause is not permitted. The namespace of the WHERE
clause is the table columns only. This was not enforced
correctly when resolving outer references in sub-queries.

Fixed by not allowing references to aliases in a 
sub-query in WHERE.
parent 7ab844c9
......@@ -434,8 +434,8 @@ execute stmt1 ;
let $1= 3 ;
while ($1)
{
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
deallocate prepare stmt1 ;
dec $1 ;
......
......@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -784,20 +784,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -826,20 +826,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......@@ -3848,20 +3848,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
......
......@@ -77,10 +77,9 @@ ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
a
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
a
1
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1,2,3) = ROW(1,2,3);
(SELECT 1,2,3) = ROW(1,2,3)
1
......@@ -2304,24 +2303,27 @@ drop table t1,t2;
CREATE TABLE t1 ( a int, b int );
CREATE TABLE t2 ( c int, d int );
INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
abc b
1 2
2 3
3 4
INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t2;
c d
1 2
2 3
3 4
CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t3;
abc b
1 2
2 3
3 4
prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
deallocate prepare stmt1;
select * from t2;
......@@ -2333,7 +2335,7 @@ c d
2 3
3 4
drop table t3;
prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
select * from t3;
abc b
......@@ -2515,7 +2517,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
SELECT DISTINCT Continent AS c FROM t1 outr WHERE
Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
Population < 200);
c
Oceania
drop table t1;
......@@ -4303,4 +4307,29 @@ LEFT(t1.a1,1)
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
a2
DROP TABLE t1, t2, t3;
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a;
ERROR 42S22: Unknown column 'out_a' in 'where clause'
SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a;
ERROR 42S22: Unknown column 'out_a' in 'where clause'
EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1 t1_outer
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
SELECT a AS out_a, MIN(b) FROM t1 t1_outer
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
GROUP BY a;
out_a MIN(b)
1 2
2 4
DROP TABLE t1;
End of 5.0 tests.
......@@ -32,7 +32,9 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error 1108
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
SELECT (SELECT 1,2,3) = ROW(1,2,3);
SELECT (SELECT 1,2,3) = ROW(1,2,1);
......@@ -1346,17 +1348,20 @@ drop table t1,t2;
CREATE TABLE t1 ( a int, b int );
CREATE TABLE t2 ( c int, d int );
INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t2;
CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t3;
prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
deallocate prepare stmt1;
select * from t2;
drop table t3;
prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
select * from t3;
deallocate prepare stmt1;
......@@ -1529,7 +1534,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
SELECT DISTINCT Continent AS c FROM t1 outr WHERE
Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
Population < 200);
drop table t1;
#
......@@ -3140,4 +3147,35 @@ SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
DROP TABLE t1, t2, t3;
#
# Bug #32400: Complex SELECT query returns correct result only on some
# occasions
#
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
--error ER_BAD_FIELD_ERROR
EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a;
--error ER_BAD_FIELD_ERROR
SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a;
EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1 t1_outer
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
GROUP BY a;
SELECT a AS out_a, MIN(b) FROM t1 t1_outer
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
GROUP BY a;
DROP TABLE t1;
--echo End of 5.0 tests.
......@@ -3641,7 +3641,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
}
/* Search in SELECT and GROUP lists of the outer select. */
if (outer_context->resolve_in_select_list)
if (place != IN_WHERE && place != IN_ON)
{
if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
return -1; /* Some error occurred (e.g. ambiguous names). */
......
......@@ -9283,7 +9283,7 @@ static void test_subqueries_ref()
{
MYSQL_STMT *stmt;
int rc, i;
const char *query= "SELECT a as ccc from t1 where a+1=(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1)";
const char *query= "SELECT a as ccc from t1 outr where a+1=(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1)";
myheader("test_subqueries_ref");
......
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