-
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.
Roy Lyseng authoredThe 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