Skip to content
  • Roy Lyseng's avatar
    d4d5fd66
    Bug#14728469: Crash with big_tables=1 and table joins · d4d5fd66
    Roy Lyseng authored
    The basic problem here is that we sometimes attempt to set the keyread
    flag on a temporary table that has not been instantiated yet.
    This is acceptable for a Memory temporary table, but not for a MyISAM
    temporary table. The solution for this problem is to save the keyread
    flag in the TABLE object and forward it to the storage engine when
    the table is instantiated. To prevent misuse, the "created" flag is made
    private, and the set_created() function is introduced.
    
    During debugging, it was also found that tab->keys was not always set
    for a derived table, meaning that we sometimes missed that we had decided
    to use a generated key. The problematic code was the test for
    tab->keys.is_clear_all() in JOIN::set_access_methods(). This test has
    been replaced with debug asserts (a selected key must be a candidate
    key). Opportunity was also taken to approve readability of code in
    JOIN::set_access_methods().
    
    Fixing this problem meant some test case changes - earlier table scans
    were converted to key lookups.
    
    Removal of unused keys for derived tables used to update tab->ref.key,
    but failed to add the selected key to tab->keys. It seems more
    consistent to update the keyuse objects and tab->keys, and then let
    create_ref_for_key() make the "correct" key choice immediately.
     
    mysql-test/r/derived.result
      Changed explain result due to use of generated key.
    
    mysql-test/r/distinct.result
      Changed explain result due to use of generated key.
    
    mysql-test/suite/opt_trace/r/filesort_pq.result
      Changed explain result due to use of generated key.
    
    mysql-test/t/derived.test
      Added analyze table for test stability.
    
    sql/records.cc
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_base.cc
      Uses functions "is_created()" and "set_created()".
    
    sql/sql_derived.cc
      Uses functions "is_created()" and "set_created()".
    
    sql/sql_executor.cc
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_optimizer.cc
      JOIN::drop_unused_derived_keys() has been modified so that when
      deleting unused derived keys, it adjusts the affected keyuse objects
      instead of tab->ref.key. It also sets correct keys into tab->keys.
      In JOIN::optimize(), JOIN::drop_unused_derived_keys() is now called
      before JOIN::set_access_methods(). This can be done because we now fix
      the keyuse objects that JOIN::set_access_methods() rely upon.
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_select.cc
      Use of flag "created" replaced with function "is_created()".
      In JOIN::set_access_methods(), no longer tests the redundant function
      tab->keys.is_clear_all() (testing tab->position->key is sufficient).
      Also removed some redundant initializations (checked with asserts)
      and expanded the if test for table scan and semi-join loose scan into
      two separate code sections.
      Expanded some TAB characters in make_join_readinfo().
    
    sql/sql_tmp_table.cc
      Setting of flag "created" replaced with functions "set_created()
      and set_deleted().
    
    sql/table.h
      Made flag "created" private.
      Added functions is_created(), set_created() and set_deleted().
      In TABLE::set_keyread(), added check for is_created() before sending
      keyread flag to storage engine.
    d4d5fd66
    Bug#14728469: Crash with big_tables=1 and table joins
    Roy Lyseng authored
    The basic problem here is that we sometimes attempt to set the keyread
    flag on a temporary table that has not been instantiated yet.
    This is acceptable for a Memory temporary table, but not for a MyISAM
    temporary table. The solution for this problem is to save the keyread
    flag in the TABLE object and forward it to the storage engine when
    the table is instantiated. To prevent misuse, the "created" flag is made
    private, and the set_created() function is introduced.
    
    During debugging, it was also found that tab->keys was not always set
    for a derived table, meaning that we sometimes missed that we had decided
    to use a generated key. The problematic code was the test for
    tab->keys.is_clear_all() in JOIN::set_access_methods(). This test has
    been replaced with debug asserts (a selected key must be a candidate
    key). Opportunity was also taken to approve readability of code in
    JOIN::set_access_methods().
    
    Fixing this problem meant some test case changes - earlier table scans
    were converted to key lookups.
    
    Removal of unused keys for derived tables used to update tab->ref.key,
    but failed to add the selected key to tab->keys. It seems more
    consistent to update the keyuse objects and tab->keys, and then let
    create_ref_for_key() make the "correct" key choice immediately.
     
    mysql-test/r/derived.result
      Changed explain result due to use of generated key.
    
    mysql-test/r/distinct.result
      Changed explain result due to use of generated key.
    
    mysql-test/suite/opt_trace/r/filesort_pq.result
      Changed explain result due to use of generated key.
    
    mysql-test/t/derived.test
      Added analyze table for test stability.
    
    sql/records.cc
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_base.cc
      Uses functions "is_created()" and "set_created()".
    
    sql/sql_derived.cc
      Uses functions "is_created()" and "set_created()".
    
    sql/sql_executor.cc
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_optimizer.cc
      JOIN::drop_unused_derived_keys() has been modified so that when
      deleting unused derived keys, it adjusts the affected keyuse objects
      instead of tab->ref.key. It also sets correct keys into tab->keys.
      In JOIN::optimize(), JOIN::drop_unused_derived_keys() is now called
      before JOIN::set_access_methods(). This can be done because we now fix
      the keyuse objects that JOIN::set_access_methods() rely upon.
      Use of flag "created" replaced with function "is_created()".
    
    sql/sql_select.cc
      Use of flag "created" replaced with function "is_created()".
      In JOIN::set_access_methods(), no longer tests the redundant function
      tab->keys.is_clear_all() (testing tab->position->key is sufficient).
      Also removed some redundant initializations (checked with asserts)
      and expanded the if test for table scan and semi-join loose scan into
      two separate code sections.
      Expanded some TAB characters in make_join_readinfo().
    
    sql/sql_tmp_table.cc
      Setting of flag "created" replaced with functions "set_created()
      and set_deleted().
    
    sql/table.h
      Made flag "created" private.
      Added functions is_created(), set_created() and set_deleted().
      In TABLE::set_keyread(), added check for is_created() before sending
      keyread flag to storage engine.
Loading