• Sergey Glukhov's avatar
    Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field · 4a23ac20
    Sergey Glukhov authored
    Lines below which were added in the patch for Bug#56814 cause this crash:
    
    +      if (table->table)
    +        table->table->maybe_null= FALSE;
    
    Consider following test case:
    --
    CREATE TABLE t1(f1 INT NOT NULL);
    INSERT INTO t1 VALUES (16777214),(0);
    
    SELECT COUNT(*) FROM t1 LEFT JOIN t1 t2
    ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
    
    DROP TABLE t1;
    --
    
    We set TABLE::maybe_null to FALSE for t2 table
    and in create_tmp_field() we create appropriate tmp table field
    using create_tmp_field_from_item() function instead of
    create_tmp_field_from_field. As a result we have
    LONGLONG field. As we have GROUP BY clause we calculate
    group buffer length, see calc_group_buffer().
    Item from group list which is used for calculation
    refer to the field from real tables and have LONG type.
    So group buffer length become insufficient for storing of
    LONGLONG value. It leads to overwriting of wrong memory
    area in do_field_int() function which is called from
    end_update().
    After some investigation I found out that
    create_tmp_field_from_item() is used only for OLAP
    grouping and can not be used for common grouping
    as it could be an incompatibility between tmp
    table fields and group buffer length.
    We can not remove create_tmp_field_from_item() call from
    create_tmp_field as OLAP needs it and we can not use this
    function for common grouping. So we should remove setting
    TABLE::maybe_null to FALSE from simplify_joins().
    In this case we'll get wrong behaviour of
    list_contains_unique_index() back. To fix it we
    could use Field::real_maybe_null() check instead of
    Field::maybe_null() and add addition check of
    TABLE_LIST::outer_join.
    
    
    mysql-test/r/group_by.result:
      test case
    mysql-test/r/join_outer.result:
      test case
    mysql-test/t/group_by.test:
      test case
    mysql-test/t/join_outer.test:
      test case
    sql/sql_select.cc:
      --remove wrong code
      --use Field::real_maybe_null() check instead of
        Field::maybe_null() and add addition check of
        TABLE_LIST::outer_join
    4a23ac20
join_outer.test 35.4 KB