Commit 1b3336dc authored by unknown's avatar unknown

Fix LP BUG#680943

Analysis:
The problem lies in filesort.cc:find_all_keys().

When find_all_keys() is called for the outer query, it resets all
of the tree sets of fields - [read,write,vcol]_set and recomputes
them with respect to sorting.

However, in the loop for each current record the procedure calls
select->skip_record(thd), which evaluates the where clause, which
in turns evaluates the subquery. The JOIN evaluation of the
subquery eventually calls Field_long::val_int to evaluate the field
alias1.f1. The assertion condition
  "bitmap_is_set(table->read_set, field_index)"
fails, because the outer query changed the read_set of table "alias1".

Solution:
Restore the original read_set of the table before calling
SQL_SELECT::skip_record, then revert back to the read_set used in
find_all_keys.
parent 6dfca7d3
...@@ -527,7 +527,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -527,7 +527,7 @@ id select_type table type possible_keys key key_len ref rows Extra
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
# #
# BUG#680846: Crash in clear_tables() with subqueries # LP BUG#680846: Crash in clear_tables() with subqueries
# #
CREATE TABLE t1 (f3 int) ; CREATE TABLE t1 (f3 int) ;
INSERT IGNORE INTO t1 VALUES (0),(0); INSERT IGNORE INTO t1 VALUES (0),(0);
...@@ -604,3 +604,19 @@ ORDER BY f9; ...@@ -604,3 +604,19 @@ ORDER BY f9;
COUNT(t2.f3) f9 COUNT(t2.f3) f9
0 NULL 0 NULL
drop table t1,t2; drop table t1,t2;
#
# LP BUG#680943 Assertion `!table || (!table->read_set ||
# bitmap_is_set(table->read_set, field_index))' failed with subquery
#
CREATE TABLE t1 (f1 int,f3 int) ;
INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
SELECT f2
FROM (SELECT * FROM t2) AS alias1
WHERE (SELECT SQ2_t2.f1
FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
WHERE SQ2_t2.f3 AND alias1.f1)
ORDER BY f3 ;
f2
drop table t1,t2;
...@@ -493,7 +493,7 @@ DROP TABLE t2; ...@@ -493,7 +493,7 @@ DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
--echo # BUG#680846: Crash in clear_tables() with subqueries --echo # LP BUG#680846: Crash in clear_tables() with subqueries
--echo # --echo #
CREATE TABLE t1 (f3 int) ; CREATE TABLE t1 (f3 int) ;
...@@ -557,3 +557,23 @@ WHERE ('v') IN (SELECT f4 FROM t2) ...@@ -557,3 +557,23 @@ WHERE ('v') IN (SELECT f4 FROM t2)
ORDER BY f9; ORDER BY f9;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # LP BUG#680943 Assertion `!table || (!table->read_set ||
--echo # bitmap_is_set(table->read_set, field_index))' failed with subquery
--echo #
CREATE TABLE t1 (f1 int,f3 int) ;
INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
SELECT f2
FROM (SELECT * FROM t2) AS alias1
WHERE (SELECT SQ2_t2.f1
FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
WHERE SQ2_t2.f3 AND alias1.f1)
ORDER BY f3 ;
drop table t1,t2;
...@@ -613,10 +613,34 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, ...@@ -613,10 +613,34 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} }
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
} }
bool write_record= false;
if (error == 0) if (error == 0)
{
param->examined_rows++; param->examined_rows++;
if (select && select->cond)
if (error == 0 && (!select || select->skip_record(thd) > 0)) {
/*
If the condition 'select->cond' contains a subquery, restore the
original read/write sets of the table 'sort_form' because when
SQL_SELECT::skip_record evaluates this condition. it may include a
correlated subquery predicate, such that some field in the subquery
refers to 'sort_form'.
*/
if (select->cond->with_subselect)
sort_form->column_bitmaps_set(save_read_set, save_write_set,
save_vcol_set);
write_record= (select->skip_record(thd) > 0);
if (select->cond->with_subselect)
sort_form->column_bitmaps_set(&sort_form->tmp_set,
&sort_form->tmp_set,
&sort_form->tmp_set);
}
else
write_record= true;
}
if (write_record)
{ {
if (idx == param->keys) if (idx == param->keys)
{ {
...@@ -629,7 +653,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, ...@@ -629,7 +653,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
} }
else else
file->unlock_row(); file->unlock_row();
/* It does not make sense to read more keys in case of a fatal error */ /* It does not make sense to read more keys in case of a fatal error */
if (thd->is_error()) if (thd->is_error())
break; break;
......
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