-
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.
Sreeharsha Ramanavarapu authoredALIAS 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