• Vicențiu Ciorbaru's avatar
    MDEV-14715: Assertion `!table || (!table->read_set... failed in Field_num::val_decimal · b20c3dc6
    Vicențiu Ciorbaru authored
    The assertion failure was caused by an incorrectly set read_set for
    functions in the ORDER BY clause in part of a union, when we are using
    a mergeable view and the order by clause can be skipped (removed).
    
    An order by clause can be skipped if it's part of one part of the UNION as
    the result set is not meaningful when multiple SELECT queries are UNIONed. The
    server is aware of this optimization and tries to remove the order by
    clause before JOIN::prepare. The problem is that we need to throw an
    error when the ORDER BY clause contains invalid columns. To do this, we
    attempt resolving the ORDER BY expressions, then subsequently drop them
    if resolution succeeded. However, ORDER BY resolution had the side
    effect of adding the expressions to the all_fields list, which is used
    to construct temporary tables to store the result. We may be ignoring
    the ORDER BY statement, but the tmp table still tried to compute the
    values for the expressions, even if the columns are never used.
    
    The assertion only shows itself if the order by clause contains members
    which were not previously in the select list, and are part of a
    function.
    
    There is an additional question as to why this only manifests when using
    VIEWS and not when using a regular table. The difference lies with the
    "reset" of the read_set for the temporary table during
    SELECT_LEX::update_used_tables() in JOIN::optimize(). The changes
    introduced in fdf789a7 cleared the
    read_set when a mergeable view is encountered in the TABLE_LIST
    defintion.
    
    Upon initial order_list resolution, the table's read_set is updated
    correctly. JOIN::optimize() will only reset the read_set if it
    encounters a VIEW. Since we no longer have ORDER BY clause in
    JOIN::optimize() we never get to correctly update the read_set again.
    
    Other relevant commit by Timour, which first introduced the order
    resolution when we "can_skip_sort_order":
    883af99e
    
    Solution:
    Don't add the resolved ORDER BY elements to all_fields. We only resolve
    them to check if an error should be returned for the query. Ignore them
    completely otherwise.
    b20c3dc6
union.result 56.3 KB