diff options
author | Georgi Kodinov <joro@sun.com> | 2009-02-19 20:30:05 +0200 |
---|---|---|
committer | Georgi Kodinov <joro@sun.com> | 2009-02-19 20:30:05 +0200 |
commit | 901427b2413a8f8c80b4720969d101357da57556 (patch) | |
tree | 5e934ca40c0afa37342cc84b5469c0a95bd97c34 | |
parent | e89fddc63684301a0e958fe54a5917fdbad56877 (diff) | |
parent | cf42f6689fd52da07fd6588d2aaded1f0f39abae (diff) | |
download | mariadb-git-901427b2413a8f8c80b4720969d101357da57556.tar.gz |
merged 5.0-bugteam -> 5.1-bugteam
-rw-r--r-- | mysql-test/r/innodb_mysql.result | 18 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql-master.opt | 2 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql.test | 52 | ||||
-rw-r--r-- | sql/sql_select.cc | 36 |
4 files changed, 95 insertions, 13 deletions
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 6fcc9415d12..32a828cf82d 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1683,6 +1683,24 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; a DROP TABLE t1; +connect(localhost,root,,test,12500,/home/kgeorge/mysql/work/B42419-merge-5.1-bugteam/mysql-test/var/tmp/mysqld.1.sock); +connect(localhost,root,,test,12500,/home/kgeorge/mysql/work/B42419-merge-5.1-bugteam/mysql-test/var/tmp/mysqld.1.sock); +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp (b INT); +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; CREATE TABLE foo (a int, b int, c char(10), PRIMARY KEY (c(3)), KEY b (b) diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/t/innodb_mysql-master.opt index 205c733455d..c8613e0ccd5 100644 --- a/mysql-test/t/innodb_mysql-master.opt +++ b/mysql-test/t/innodb_mysql-master.opt @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--innodb-lock-wait-timeout=3 diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 21ee440f10b..77140fd85d7 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -55,6 +55,57 @@ SELECT * FROM t1 WHERE a = 'abcde'; DROP TABLE t1; # +# Bug #42419: Server crash with "Pure virtual method called" on two +# concurrent connections +# + +connect (c1, localhost, root,,); +connect (c2, localhost, root,,); + +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT) + ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); + +connection c1; + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp (b INT); + +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2; + +connection c2; + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; + +--send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +--sleep 3 + +connection c1; + +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; + +connection c2; + +--reap +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect c1; +disconnect c2; +DROP TABLE t1; + +# # Bug #37742: HA_EXTRA_KEYREAD flag is set when key contains only prefix of # requested column # @@ -91,6 +142,7 @@ INSERT INTO foo2 SELECT * FROM foo; DROP TABLE foo, bar, foo2; + # # Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 75c11c2ac64..bea748562eb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2460,11 +2460,12 @@ typedef struct st_sargable_param */ static bool -make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, +make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DYNAMIC_ARRAY *keyuse_array) { int error; TABLE *table; + TABLE_LIST *tables= tables_arg; uint i,table_count,const_count,key; table_map found_const_table_map, all_table_map, found_ref, refs; key_map const_ref, eq_part; @@ -2502,10 +2503,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, table_vector[i]=s->table=table=tables->table; table->pos_in_table_list= tables; error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (error) { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(1); + table->file->print_error(error, MYF(0)); + goto error; } table->quick_keys.clear_all(); table->reginfo.join_tab=s; @@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { join->tables=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); - DBUG_RETURN(1); + goto error; } s->key_dependent= s->dependent; } @@ -2611,7 +2612,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) - DBUG_RETURN(1); + goto error; /* Read tables with 0 or 1 rows (system tables) */ join->const_table_map= 0; @@ -2627,7 +2628,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp=join_read_const_table(s, p_pos))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= s->table->map; @@ -2699,7 +2700,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp= join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2748,12 +2749,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) - DBUG_RETURN(1); + goto error; if ((tmp=join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2830,7 +2831,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error); if (!select) - DBUG_RETURN(1); + goto error; records= get_quick_record_count(join->thd, select, s->table, &s->const_keys, join->row_limit); s->quick=select->quick; @@ -2876,7 +2877,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { optimize_keyuse(join, keyuse_array); if (choose_plan(join, all_table_map & ~join->const_table_map)) - DBUG_RETURN(TRUE); + goto error; } else { @@ -2886,6 +2887,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, } /* Generate an execution plan from the found optimal join order. */ DBUG_RETURN(join->thd->killed || get_best_combination(join)); + +error: + /* + Need to clean up join_tab from TABLEs in case of error. + They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab + may not be assigned yet by this function (which is building join_tab). + Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. + */ + for (tables= tables_arg; tables; tables= tables->next_leaf) + tables->table->reginfo.join_tab= NULL; + DBUG_RETURN (1); } |