• Georgi Kodinov's avatar
    Bug #45807: crash accessing partitioned table and sql_mode · 5572f8e7
    Georgi Kodinov authored
    contains ONLY_FULL_GROUP_BY
    
    The partitioning code needs to issue a Item::fix_fields()
    on the partitioning expression in order to prepare 
    it for being evaluated.
    It does this by creating a special table and a table list 
    for the scope of the partitioning expression.
    But when checking ONLY_FULL_GROUP_BY the 
    Item_field::fix_fields() was relying that there always be
    cached_table set and was trying to use it to get the 
    select_lex of the SELECT the field's table is in.
    But the cached_table was not set by the partitioning code
    that creates the artificial TABLE_LIST used to resolve the
    partitioning expression and this resulted in a crash.
     
    Fixed by rectifying the following errors :
    1. Item_field::fix_fields() : the code that check for 
    ONLY_FULL_GROUP_BY relies on having tables with 
    cacheable_table set. This is mostly true, the only 
    two exceptions being the partitioning context table
    and the trigger context table.
    Fixed by taking the current parsing context if no pointer
    to the TABLE_LIST instance is present in the cached_table.
    
    2. fix_fields_part_func() : 
    
    2a. The code that adds the table being created to the 
    scope for the partitioning expression is mostly a copy 
    of the add_table_to_list and friends with one exception :
    it was not marking the table as cacheable (something that
    normal add_table_to_list is doing). This caused the 
    problem in the check for ONLY_FULL_GROUP_BY in 
    Item_field::fix_fields() to appear.
    Fixed by setting the correct members to make the table
    cacheable.
    The ideal structural fix for this is to use a unified 
    interface for adding a table to a table list 
    (add_table_to_list?) : noted in a TODO comment
    
    2b. The Item::fix_fields() was called with a NULL destination
    pointer. This causes uninitalized memory reads in the 
    overloaded ::fix_fields() function (namely 
    Item_field::fix_fields()) as it expects a non-zero pointer 
    there. Fixed by passing the source pointer similarly to how 
    it's done in JOIN::prepare().
    5572f8e7
partition.result 59 KB