diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index 96d66bbb579..a3a874a8ed2 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -407,3 +407,35 @@ explain select * from t3 where a=1 and b=1; drop table t3; drop table t0, t1, t2; } + +# +# BUG#20256 - LOCK WRITE - MyISAM +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1); +CREATE TABLE t2(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b)); +INSERT INTO t2(a,b) VALUES +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(1,2); +LOCK TABLES t1 WRITE, t2 WRITE; +INSERT INTO t2(a,b) VALUES(1,2); +SELECT t2.a FROM t1,t2 WHERE t2.b=2 AND t2.a=1; +UNLOCK TABLES; +DROP TABLE t1, t2; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index cbb8a7a48c0..3826a30e247 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -147,6 +147,14 @@ ha_myisam::ha_myisam(TABLE_SHARE *table_arg) can_enable_indexes(1) {} +handler *ha_myisam::clone(MEM_ROOT *mem_root) +{ + ha_myisam *new_handler= static_cast (handler::clone(mem_root)); + if (new_handler) + new_handler->file->state= file->state; + return new_handler; +} + static const char *ha_myisam_exts[] = { ".MYI", diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 5544e5040b3..511b796ebdb 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -45,6 +45,7 @@ class ha_myisam: public handler public: ha_myisam(TABLE_SHARE *table_arg); ~ha_myisam() {} + handler *clone(MEM_ROOT *mem_root); const char *table_type() const { return "MyISAM"; } const char *index_type(uint key_number); const char **bas_ext() const; diff --git a/sql/handler.cc b/sql/handler.cc index fbccfe7fa46..b787fad2f96 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1416,6 +1416,15 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /**************************************************************************** ** General handler functions ****************************************************************************/ +handler *handler::clone(MEM_ROOT *mem_root) +{ + handler *new_handler= get_new_handler(table, mem_root, table->s->db_type); + if (new_handler && !new_handler->ha_open(table->s->path, table->db_stat, + HA_OPEN_IGNORE_IF_LOCKED)) + return new_handler; + return NULL; +} + void handler::ha_statistic_increment(ulong SSV::*offset) const diff --git a/sql/handler.h b/sql/handler.h index 201a2f1980a..767990613f2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -942,6 +942,7 @@ public: { /* TODO: DBUG_ASSERT(inited == NONE); */ } + virtual handler *clone(MEM_ROOT *mem_root); /* This is called after create to allow us to set up cached variables */ void init() { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index a5a46ba11b6..30235154a89 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1164,11 +1164,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) } thd= head->in_use; - if (!(file= get_new_handler(head->s, thd->mem_root, head->s->db_type))) - goto failure; - DBUG_PRINT("info", ("Allocated new handler 0x%lx", (long) file)); - if (file->ha_open(head, head->s->normalized_path.str, head->db_stat, - HA_OPEN_IGNORE_IF_LOCKED)) + if (!(file= head->file->clone(thd->mem_root))) { /* Caller will free the memory */ goto failure;