Commit ce0b598a 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 201e124d
......@@ -1246,3 +1246,29 @@ i
4
set session optimizer_switch=@save_optimizer_switch;
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 =
set session optimizer_switch=@save_optimizer_switch;
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,
if (!stat)
return TRUE;
cleanup();
reset();
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
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
update null_statistics before sending data to the client.
......
......@@ -2905,7 +2905,7 @@ class select_union :public select_result_interceptor
bool send_data(List<Item> &items);
bool send_eof();
bool flush();
void cleanup();
virtual bool create_result_table(THD *thd, List<Item> *column_types,
bool is_distinct, ulonglong options,
const char *alias, bool bit_fields_as_long);
......@@ -2968,6 +2968,9 @@ class select_materialize_with_stats : public select_union
*/
ha_rows count_rows;
protected:
void reset();
public:
select_materialize_with_stats() {}
virtual bool create_result_table(THD *thd, List<Item> *column_types,
......@@ -2975,12 +2978,7 @@ class select_materialize_with_stats : public select_union
const char *alias, bool bit_fields_as_long);
bool init_result_table(ulonglong select_options);
bool send_data(List<Item> &items);
void cleanup()
{
memset(col_stat, 0, table->s->fields * sizeof(Column_statistics));
max_nulls_in_row= 0;
count_rows= 0;
}
void cleanup();
ha_rows get_null_count_of_col(uint idx)
{
DBUG_ASSERT(idx < table->s->fields);
......
......@@ -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()
......
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