• unknown's avatar
    BUG#18492: mysqld reports ER_ILLEGAL_REFERENCE in --ps-protocol · 0e0d0d9d
    unknown authored
    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
    0e0d0d9d
ps_11bugs.test 5.49 KB