Commit 36d83ee2 authored by Tatiana A. Nurnberg's avatar Tatiana A. Nurnberg

auto-merge

parents f218f9f2 759edca6
...@@ -1267,4 +1267,20 @@ CREATE INDEX i1 on t1 (a(3)); ...@@ -1267,4 +1267,20 @@ CREATE INDEX i1 on t1 (a(3));
SELECT * FROM t1 WHERE a = 'abcde'; SELECT * FROM t1 WHERE a = 'abcde';
a a
DROP TABLE t1; DROP TABLE t1;
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;
End of 5.0 tests End of 5.0 tests
--innodb-lock-wait-timeout=2 --innodb-lock-wait-timeout=3
...@@ -1025,4 +1025,55 @@ CREATE INDEX i1 on t1 (a(3)); ...@@ -1025,4 +1025,55 @@ CREATE INDEX i1 on t1 (a(3));
SELECT * FROM t1 WHERE a = 'abcde'; SELECT * FROM t1 WHERE a = 'abcde';
DROP TABLE t1; 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;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -2373,11 +2373,12 @@ typedef struct st_sargable_param ...@@ -2373,11 +2373,12 @@ typedef struct st_sargable_param
*/ */
static bool 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) DYNAMIC_ARRAY *keyuse_array)
{ {
int error; int error;
TABLE *table; TABLE *table;
TABLE_LIST *tables= tables_arg;
uint i,table_count,const_count,key; uint i,table_count,const_count,key;
table_map found_const_table_map, all_table_map, found_ref, refs; table_map found_const_table_map, all_table_map, found_ref, refs;
key_map const_ref, eq_part; key_map const_ref, eq_part;
...@@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
table_vector[i]=s->table=table=tables->table; table_vector[i]=s->table=table=tables->table;
table->pos_in_table_list= tables; table->pos_in_table_list= tables;
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
if(error) if (error)
{ {
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(1); goto error;
} }
table->quick_keys.clear_all(); table->quick_keys.clear_all();
table->reginfo.join_tab=s; table->reginfo.join_tab=s;
...@@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{ {
join->tables=0; // Don't use join->table join->tables=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
DBUG_RETURN(1); goto error;
} }
s->key_dependent= s->dependent; s->key_dependent= s->dependent;
} }
...@@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
conds, join->cond_equal, conds, join->cond_equal,
~outer_join, join->select_lex, &sargables)) ~outer_join, join->select_lex, &sargables))
DBUG_RETURN(1); goto error;
/* Read tables with 0 or 1 rows (system tables) */ /* Read tables with 0 or 1 rows (system tables) */
join->const_table_map= 0; join->const_table_map= 0;
...@@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if ((tmp=join_read_const_table(s, p_pos))) if ((tmp=join_read_const_table(s, p_pos)))
{ {
if (tmp > 0) if (tmp > 0)
DBUG_RETURN(1); // Fatal error goto error; // Fatal error
} }
else else
found_const_table_map|= s->table->map; found_const_table_map|= s->table->map;
...@@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2601,7 +2602,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= join_read_const_table(s, join->positions+const_count-1)))
{ {
if (tmp > 0) if (tmp > 0)
DBUG_RETURN(1); // Fatal error goto error; // Fatal error
} }
else else
found_const_table_map|= table->map; found_const_table_map|= table->map;
...@@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
set_position(join,const_count++,s,start_keyuse); set_position(join,const_count++,s,start_keyuse);
if (create_ref_for_key(join, s, start_keyuse, if (create_ref_for_key(join, s, start_keyuse,
found_const_table_map)) found_const_table_map))
DBUG_RETURN(1); goto error;
if ((tmp=join_read_const_table(s, if ((tmp=join_read_const_table(s,
join->positions+const_count-1))) join->positions+const_count-1)))
{ {
if (tmp > 0) if (tmp > 0)
DBUG_RETURN(1); // Fatal error goto error; // Fatal error
} }
else else
found_const_table_map|= table->map; found_const_table_map|= table->map;
...@@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
*s->on_expr_ref ? *s->on_expr_ref : conds, *s->on_expr_ref ? *s->on_expr_ref : conds,
1, &error); 1, &error);
if (!select) if (!select)
DBUG_RETURN(1); goto error;
records= get_quick_record_count(join->thd, select, s->table, records= get_quick_record_count(join->thd, select, s->table,
&s->const_keys, join->row_limit); &s->const_keys, join->row_limit);
s->quick=select->quick; s->quick=select->quick;
...@@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{ {
optimize_keyuse(join, keyuse_array); optimize_keyuse(join, keyuse_array);
if (choose_plan(join, all_table_map & ~join->const_table_map)) if (choose_plan(join, all_table_map & ~join->const_table_map))
DBUG_RETURN(TRUE); goto error;
} }
else else
{ {
...@@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, ...@@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
} }
/* Generate an execution plan from the found optimal join order. */ /* Generate an execution plan from the found optimal join order. */
DBUG_RETURN(join->thd->killed || get_best_combination(join)); 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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment