-
Gleb Shchepa authored
This patch is for 5.7. Issue 1 ======= A quoted identifier name consisting of a single asterisk character could recognized as an unquoted asterisk, i.e. SELECT `*` ... was parsed as SELECT * ... Issue 2 ======= A qualified quoted identifier with a name starting with the asterisk character could recognized as as unquoted asterisk if the same select list contained an unquoted asterisk symbol, i.e. SELECT a.`*`, ... b.* ... was parsed as SELECT a.*, ... b.`*` ... Analysis for issue 1 ==================== After the WL7200, a special processing of qualified [<schema>].table.* and unqualified * in a select list has diverged: the unqualified one has went to Item_field::itemize(), but the qualified has become PTI_table_wild. As well as it's impossible to mistake quoted and unquoted asterisk inside PTI_table_wild, it is also impossible (too late) to distinguish quoted and unquoted names inside Item_field::itemize(). Thus, the code for the unqualified asterisk in Item_field::itemize() has failed to recognize identifiers like a back-quoted `*` as identifiers. Analysis for issue 2 ==================== From the beginning, the resolver (see setup_wild()) has been designed to recognize asterisks in a select list with a help of: 1. an Item_field placeholder objects with "*" in place of their column names, 2. a counter of asterisk select list items in SELECT_LIST::with_wild local to each query block, Thus, a loop in setup_wild() has searched over all select list items checking all Item_field objects (including either placeholders for * or regular column reference items) for the 1st character of Item_field::field_name until it reached SELECT_LIST::with_wild of such objects. So, if a select list contained unquoted asterisk items before column names containing "*" at their start, everything worked fine. However, if there was a column name starting with "*" before an unquoted asterisk in a select list, the former recognized as an unquoted asterisk, while the latest recognized as a quoted column name. Solution ======== 1. The code branch in Item_field::itemize() that processed asterisks has been removed. 2. The Item_asterisk class has been introduced to replace PTI_table_wild. Reasoning: * unlike PTI_table_wild, that disappears after the PTI_table_wild::itemize() call leaving Item_field in its place, the new Item_asterisk class can survive till the setup_wild() call to be distinguished there from other Item_field objects those represent regular column references. * minus one MEM_ROOT allocation * the new name Item_asterisk is closer to the standard 3. All direct allocations of Item_field for the unquoted asterisk thing have been replaced with allocations of Item_asterisk. 4. setup_wild() has been updated to recognize asterisk items using Item_field::is_asterisk() instead of looking into Item_field::field_name. Change-Id: Id0e5eea03608ed6140901e32d840dc3190a67bee
Gleb Shchepa authoredThis patch is for 5.7. Issue 1 ======= A quoted identifier name consisting of a single asterisk character could recognized as an unquoted asterisk, i.e. SELECT `*` ... was parsed as SELECT * ... Issue 2 ======= A qualified quoted identifier with a name starting with the asterisk character could recognized as as unquoted asterisk if the same select list contained an unquoted asterisk symbol, i.e. SELECT a.`*`, ... b.* ... was parsed as SELECT a.*, ... b.`*` ... Analysis for issue 1 ==================== After the WL7200, a special processing of qualified [<schema>].table.* and unqualified * in a select list has diverged: the unqualified one has went to Item_field::itemize(), but the qualified has become PTI_table_wild. As well as it's impossible to mistake quoted and unquoted asterisk inside PTI_table_wild, it is also impossible (too late) to distinguish quoted and unquoted names inside Item_field::itemize(). Thus, the code for the unqualified asterisk in Item_field::itemize() has failed to recognize identifiers like a back-quoted `*` as identifiers. Analysis for issue 2 ==================== From the beginning, the resolver (see setup_wild()) has been designed to recognize asterisks in a select list with a help of: 1. an Item_field placeholder objects with "*" in place of their column names, 2. a counter of asterisk select list items in SELECT_LIST::with_wild local to each query block, Thus, a loop in setup_wild() has searched over all select list items checking all Item_field objects (including either placeholders for * or regular column reference items) for the 1st character of Item_field::field_name until it reached SELECT_LIST::with_wild of such objects. So, if a select list contained unquoted asterisk items before column names containing "*" at their start, everything worked fine. However, if there was a column name starting with "*" before an unquoted asterisk in a select list, the former recognized as an unquoted asterisk, while the latest recognized as a quoted column name. Solution ======== 1. The code branch in Item_field::itemize() that processed asterisks has been removed. 2. The Item_asterisk class has been introduced to replace PTI_table_wild. Reasoning: * unlike PTI_table_wild, that disappears after the PTI_table_wild::itemize() call leaving Item_field in its place, the new Item_asterisk class can survive till the setup_wild() call to be distinguished there from other Item_field objects those represent regular column references. * minus one MEM_ROOT allocation * the new name Item_asterisk is closer to the standard 3. All direct allocations of Item_field for the unquoted asterisk thing have been replaced with allocations of Item_asterisk. 4. setup_wild() has been updated to recognize asterisk items using Item_field::is_asterisk() instead of looking into Item_field::field_name. Change-Id: Id0e5eea03608ed6140901e32d840dc3190a67bee
Loading