Skip to content
  • Sreeharsha Ramanavarapu's avatar
    4e31be57
    Bug #25343335: DERIVED TABLE SELECT LIST'S REFERENCE TO · 4e31be57
    Sreeharsha Ramanavarapu authored
                   ALIAS CAUSES INCORRECT BEHAVIOR
    
    Issue 1:
    --------
    In the following query:
    
    SELECT *
    FROM (SELECT 1 AS alias1, (SELECT alias1 .... ) AS alias2
          FROM t1) X ;
    
    Notice that alias1 is created in the select list as the
    first column and is then referred to in the second column:
    alias2.
    
    This is not part of the SQL standard, but Mysql allows this.
    
    alias2 is resolved to the alias1 which is also part of the
    same select-list. Once the resolution is completed, the
    derived table is merged into the outer query. Derived
    tables don't have an outer context because they can't refer
    to an outer query. So during the merge, the derived table's
    outer context (which is null) is assigned to the subqueries
    in the select list of the derived table. This is harmless
    during conventional execution since the resolution is
    already complete.
    
    The problem arises during PREPARE/EXECUTE. The prepare
    phase completes the first round of resolution and then
    proceeds to merge the derived table, thus resultig in a
    loss of the outer contexts for alias2. But the EXECUTE
    step needs to redo the resolution. Since the outer context
    of alias2 has been set to NULL, it is unable to resolve the
    alias1 present in the inner-most subquery.
    
    
    Solution to Issue 1:
    --------------------
    In SELECT_LEX_UNIT::exclude_level(), while assigning outer
    context to the subqueries of a derived table, use the outer
    select's context, instead of the derived table's outer
    context.
    
    
    Issue 2:
    --------
    In the following query:
    
    SELECT alias2
    FROM (SELECT ... alias1, (SELECT alias1 .... ) AS alias2
          FROM t1) X ;
    
    Here only alias2 is referred to in the outer query's select
    list. This query works as expected in a conventional
    execution.
    
    But in a PREPARE/EXECUTE scenario, the EXECUTE step fails
    complaining that it is unable to resolve alias1. Notice
    that inorder to resolve alias2, alias1 is required. At the
    end of the PREPARE phase, the derived table is merged into
    the outer query. At the beginning of the EXECUTE phase, the
    context->first_name_resolution_table (which is where the
    query is first supposed to look to resolve a field) is
    mistakently changed to t1 instead of X. So, in order to
    resolve alias1, the table t1 is looked up unsuccessfully.
    Hence the failure.
    
    Solution to Issue 2 on mysql-trunk:
    -----------------------------------
    This problem was fixed by the refactoring in Bug#21522980.
    
    Solution to Issue 2 on mysql-5,7:
    ---------------------------------
    The change of
    context->first_name_resolution_table happens in
    setup_natural_join_row_types, which shouldn't actually be
    called since this is a single table query.
    
    The fix is a partial backport of Bug#21522980.
    
    
    A further problem was identified when the derived table
    contains a join. This will be addressed as part of
    Bug#25355534 . This issue occurs on both trunk and 5.7.
    4e31be57
    Bug #25343335: DERIVED TABLE SELECT LIST'S REFERENCE TO
    Sreeharsha Ramanavarapu authored
                   ALIAS CAUSES INCORRECT BEHAVIOR
    
    Issue 1:
    --------
    In the following query:
    
    SELECT *
    FROM (SELECT 1 AS alias1, (SELECT alias1 .... ) AS alias2
          FROM t1) X ;
    
    Notice that alias1 is created in the select list as the
    first column and is then referred to in the second column:
    alias2.
    
    This is not part of the SQL standard, but Mysql allows this.
    
    alias2 is resolved to the alias1 which is also part of the
    same select-list. Once the resolution is completed, the
    derived table is merged into the outer query. Derived
    tables don't have an outer context because they can't refer
    to an outer query. So during the merge, the derived table's
    outer context (which is null) is assigned to the subqueries
    in the select list of the derived table. This is harmless
    during conventional execution since the resolution is
    already complete.
    
    The problem arises during PREPARE/EXECUTE. The prepare
    phase completes the first round of resolution and then
    proceeds to merge the derived table, thus resultig in a
    loss of the outer contexts for alias2. But the EXECUTE
    step needs to redo the resolution. Since the outer context
    of alias2 has been set to NULL, it is unable to resolve the
    alias1 present in the inner-most subquery.
    
    
    Solution to Issue 1:
    --------------------
    In SELECT_LEX_UNIT::exclude_level(), while assigning outer
    context to the subqueries of a derived table, use the outer
    select's context, instead of the derived table's outer
    context.
    
    
    Issue 2:
    --------
    In the following query:
    
    SELECT alias2
    FROM (SELECT ... alias1, (SELECT alias1 .... ) AS alias2
          FROM t1) X ;
    
    Here only alias2 is referred to in the outer query's select
    list. This query works as expected in a conventional
    execution.
    
    But in a PREPARE/EXECUTE scenario, the EXECUTE step fails
    complaining that it is unable to resolve alias1. Notice
    that inorder to resolve alias2, alias1 is required. At the
    end of the PREPARE phase, the derived table is merged into
    the outer query. At the beginning of the EXECUTE phase, the
    context->first_name_resolution_table (which is where the
    query is first supposed to look to resolve a field) is
    mistakently changed to t1 instead of X. So, in order to
    resolve alias1, the table t1 is looked up unsuccessfully.
    Hence the failure.
    
    Solution to Issue 2 on mysql-trunk:
    -----------------------------------
    This problem was fixed by the refactoring in Bug#21522980.
    
    Solution to Issue 2 on mysql-5,7:
    ---------------------------------
    The change of
    context->first_name_resolution_table happens in
    setup_natural_join_row_types, which shouldn't actually be
    called since this is a single table query.
    
    The fix is a partial backport of Bug#21522980.
    
    
    A further problem was identified when the derived table
    contains a join. This will be addressed as part of
    Bug#25355534 . This issue occurs on both trunk and 5.7.
Loading