Commit 2d78ffb8 authored by unknown's avatar unknown

Fixed a problem where the temp table of a materialized subquery

was not cleaned up between PS re-executions. The reason was two-fold:
- a merge with mysql-6.0 missed select_union::cleanup() that should
  have cleaned up the temp table, and
- the subclass of select_union used by materialization didn't call
  the base class cleanup() method.
parent 75bba30c
...@@ -1246,3 +1246,29 @@ i ...@@ -1246,3 +1246,29 @@ i
4 4
set session optimizer_switch=@save_optimizer_switch; set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3; drop table t1, t2, t3;
create table t0 (a int);
insert into t0 values (0),(1),(2);
create table t1 (a int);
insert into t1 values (0),(1),(2);
explain select a, a in (select a from t1) from t0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 3
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
select a, a in (select a from t1) from t0;
a a in (select a from t1)
0 1
1 1
2 1
prepare s from 'select a, a in (select a from t1) from t0';
execute s;
a a in (select a from t1)
0 1
1 1
2 1
update t1 set a=123;
execute s;
a a in (select a from t1)
0 0
1 0
2 0
drop table t0, t1;
...@@ -905,3 +905,19 @@ select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = ...@@ -905,3 +905,19 @@ select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i =
set session optimizer_switch=@save_optimizer_switch; set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3; drop table t1, t2, t3;
#
# Test that the contents of the temp table of a materialized subquery is
# cleaned up between PS re-executions.
#
create table t0 (a int);
insert into t0 values (0),(1),(2);
create table t1 (a int);
insert into t1 values (0),(1),(2);
explain select a, a in (select a from t1) from t0;
select a, a in (select a from t1) from t0;
prepare s from 'select a, a in (select a from t1) from t0';
execute s;
update t1 set a=123;
execute s;
drop table t0, t1;
...@@ -2994,14 +2994,28 @@ create_result_table(THD *thd_arg, List<Item> *column_types, ...@@ -2994,14 +2994,28 @@ create_result_table(THD *thd_arg, List<Item> *column_types,
if (!stat) if (!stat)
return TRUE; return TRUE;
cleanup(); reset();
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
return FALSE; return FALSE;
} }
void select_materialize_with_stats::reset()
{
memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
max_nulls_in_row= 0;
count_rows= 0;
}
void select_materialize_with_stats::cleanup()
{
reset();
select_union::cleanup();
}
/** /**
Override select_union::send_data to analyze each row for NULLs and to Override select_union::send_data to analyze each row for NULLs and to
update null_statistics before sending data to the client. update null_statistics before sending data to the client.
......
...@@ -2905,7 +2905,7 @@ public: ...@@ -2905,7 +2905,7 @@ public:
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
bool flush(); bool flush();
void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types, virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options, bool is_distinct, ulonglong options,
const char *alias, bool bit_fields_as_long); const char *alias, bool bit_fields_as_long);
...@@ -2968,6 +2968,9 @@ protected: ...@@ -2968,6 +2968,9 @@ protected:
*/ */
ha_rows count_rows; ha_rows count_rows;
protected:
void reset();
public: public:
select_materialize_with_stats() {} select_materialize_with_stats() {}
virtual bool create_result_table(THD *thd, List<Item> *column_types, virtual bool create_result_table(THD *thd, List<Item> *column_types,
...@@ -2975,12 +2978,7 @@ public: ...@@ -2975,12 +2978,7 @@ public:
const char *alias, bool bit_fields_as_long); const char *alias, bool bit_fields_as_long);
bool init_result_table(ulonglong select_options); bool init_result_table(ulonglong select_options);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
void cleanup() void cleanup();
{
memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
max_nulls_in_row= 0;
count_rows= 0;
}
ha_rows get_null_count_of_col(uint idx) ha_rows get_null_count_of_col(uint idx)
{ {
DBUG_ASSERT(idx < table->s->fields); DBUG_ASSERT(idx < table->s->fields);
......
...@@ -136,6 +136,22 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types, ...@@ -136,6 +136,22 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
} }
/**
Reset and empty the temporary table that stores the materialized query result.
@note The cleanup performed here is exactly the same as for the two temp
tables of JOIN - exec_tmp_table_[1 | 2].
*/
void select_union::cleanup()
{
table->file->extra(HA_EXTRA_RESET_STATE);
table->file->ha_delete_all_rows();
free_io_cache(table);
filesort_free_buffers(table,0);
}
/* /*
initialization procedures before fake_select_lex preparation() initialization procedures before fake_select_lex preparation()
......
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