diff options
author | unknown <gkodinov@lsmy3.wdf.sap.corp> | 2006-04-28 11:23:31 +0200 |
---|---|---|
committer | unknown <gkodinov@lsmy3.wdf.sap.corp> | 2006-04-28 11:23:31 +0200 |
commit | 3a0d0b4ce55671c59d45d9a3806fd5fd5f274b3b (patch) | |
tree | ad0835ff59ed8abac179ed0b17bcb9e9198b6466 /mysql-test/r/ps_11bugs.result | |
parent | f0e7abfcc13cb006868aaee140a3c232bdcb1714 (diff) | |
download | mariadb-git-3a0d0b4ce55671c59d45d9a3806fd5fd5f274b3b.tar.gz |
BUG#18492: mysqld reports ER_ILLEGAL_REFERENCE in --ps-protocol
In the code that converts IN predicates to EXISTS predicates it is changing
the select list elements to constant 1. Example :
SELECT ... FROM ... WHERE a IN (SELECT c FROM ...)
is transformed to :
SELECT ... FROM ... WHERE EXISTS (SELECT 1 FROM ... HAVING a = c)
However there can be no FROM clause in the IN subquery and it may not be
a simple select : SELECT ... FROM ... WHERE a IN (SELECT f(..) AS
c UNION SELECT ...) This query is transformed to : SELECT ... FROM ...
WHERE EXISTS (SELECT 1 FROM (SELECT f(..) AS c UNION SELECT ...)
x HAVING a = c) In the above query c in the HAVING clause is made to be
an Item_null_helper (a subclass of Item_ref) pointing to the real
Item_field (which is not referenced anywhere else in the query anymore).
This is done because Item_ref_null_helper collects information whether
there are NULL values in the result. This is OK for directly executed
statements, because the Item_field pointed by the Item_null_helper is
already fixed when the transformation is done. But when executed as
a prepared statement all the Item instances are "un-fixed" before the
recompilation of the prepared statement. So when the Item_null_helper
gets fixed it discovers that the Item_field it points to is not fixed
and issues an error. The remedy is to keep the original select list
references when there are no tables in the FROM clause. So the above
becomes : SELECT ... FROM ... WHERE EXISTS (SELECT c FROM (SELECT f(..)
AS c UNION SELECT ...) x HAVING a = c) In this way c is referenced
directly in the select list as well as by reference in the HAVING
clause. So it gets correctly fixed even with prepared statements. And
since the Item_null_helper subclass of Item_ref_null_helper is not used
anywhere else it's taken out.
mysql-test/r/ps_11bugs.result:
Test case for the bug
mysql-test/r/subselect.result:
Explain updated because of the tranformation
mysql-test/t/ps_11bugs.test:
Testcase for the bug
sql/item.cc:
Taking out Item_null_helper as it's no longer needed
sql/item.h:
Taking out Item_null_helper as it's no longer needed
sql/item_subselect.cc:
The described change to the IN->EXISTS transformation
Diffstat (limited to 'mysql-test/r/ps_11bugs.result')
-rw-r--r-- | mysql-test/r/ps_11bugs.result | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index c0d7fe502af..c849c25d646 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -116,3 +116,17 @@ execute st_1676 using @arg0, @arg1, @arg2; cola colb cold aaaa yyyy R drop table t1, t2; +create table t1 (a int primary key); +insert into t1 values (1); +explain select * from t1 where 3 in (select (1+1) union select 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +select * from t1 where 3 in (select (1+1) union select 1); +a +prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)'; +execute st_18492; +a +drop table t1; |