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.
This commit is contained in:
parent
3fc85580c9
commit
3b05fc78e5
@ -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 =
|
|||||||
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 contentes of the temp table of a materialized subquery is
|
||||||
|
# cleanup up between PS reexecutions.
|
||||||
|
#
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -2942,8 +2942,7 @@ bool select_dumpvar::send_eof()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool select_materialize_with_stats::
|
||||||
select_materialize_with_stats::
|
|
||||||
create_result_table(THD *thd_arg, List<Item> *column_types,
|
create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||||
bool is_union_distinct, ulonglong options,
|
bool is_union_distinct, ulonglong options,
|
||||||
const char *table_alias, bool bit_fields_as_long)
|
const char *table_alias, bool bit_fields_as_long)
|
||||||
@ -2962,14 +2961,29 @@ 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.
|
||||||
|
@ -2820,7 +2820,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);
|
||||||
@ -2883,6 +2883,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,
|
||||||
@ -2890,12 +2893,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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
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()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user