Skip to content
  • Roy Lyseng's avatar
    b851dff4
    Bug#16177639: Crash due to uninitialized value for field->is_null() · b851dff4
    Roy Lyseng authored
    The problem query outer-joins a regular table with a derived table that
    is an implicitly grouped table (it selects the row count from a join of
    two inner tables). Before make_join_statistics() is called for the
    outer query, the derived table is materialized. The derived table's join
    is determined to have zero rows (due to the ON FALSE condition), and
    this row count is propagated in join->best_rowcount.
    
    In st_select_lex_unit::optimize(), this value is used to populate
    result->estimated_rowcount, which make_join_statistics() later uses
    to determine that the derived table is empty, and in case label
    extract_empty_table, the table is extracted. However, due to the
    derived table being implicitly grouped, one row is contained in the
    table, and when join_read_const_table() is called for the table, a row
    is found and the condition for it is evaluated. This condition refers to
    table t1 which is not yet read, and a valgrind exception or other bad
    things may happen.
    
    The fix is to notice in st_select_lex_unit::optimize() that the row count
    for an implicitly grouped table is exactly 1 (or, if HAVING is also
    present, 0 or 1 rows).
    
    mysql-test/r/derived.result
      Plan is changed from ref access to ALL because the row count is
      increased from 0 to 1.
    
    mysql-test/r/heap.result
      Plan is changed from ref access to ALL because the row count is
      reduced from 2 to 1.
    
    sql/sql_union.cc
      In st_select_lex_unit::optimize(), notice that the row count for
      an implicitly grouped query is (maximum) 1.
    b851dff4
    Bug#16177639: Crash due to uninitialized value for field->is_null()
    Roy Lyseng authored
    The problem query outer-joins a regular table with a derived table that
    is an implicitly grouped table (it selects the row count from a join of
    two inner tables). Before make_join_statistics() is called for the
    outer query, the derived table is materialized. The derived table's join
    is determined to have zero rows (due to the ON FALSE condition), and
    this row count is propagated in join->best_rowcount.
    
    In st_select_lex_unit::optimize(), this value is used to populate
    result->estimated_rowcount, which make_join_statistics() later uses
    to determine that the derived table is empty, and in case label
    extract_empty_table, the table is extracted. However, due to the
    derived table being implicitly grouped, one row is contained in the
    table, and when join_read_const_table() is called for the table, a row
    is found and the condition for it is evaluated. This condition refers to
    table t1 which is not yet read, and a valgrind exception or other bad
    things may happen.
    
    The fix is to notice in st_select_lex_unit::optimize() that the row count
    for an implicitly grouped table is exactly 1 (or, if HAVING is also
    present, 0 or 1 rows).
    
    mysql-test/r/derived.result
      Plan is changed from ref access to ALL because the row count is
      increased from 0 to 1.
    
    mysql-test/r/heap.result
      Plan is changed from ref access to ALL because the row count is
      reduced from 2 to 1.
    
    sql/sql_union.cc
      In st_select_lex_unit::optimize(), notice that the row count for
      an implicitly grouped query is (maximum) 1.
Loading