Commit d0ad93fb authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-487.

The function collect_statistics_for_table() when scanning a table
did not take into account that the handler function ha_rnd_next
could return the code HA_ERR_RECORD_DELETE that should not be
considered as an indication of an error.
Also fixed a potential memory leak in this function.
parent f4631d6f
...@@ -353,4 +353,15 @@ Table Op Msg_type Msg_text ...@@ -353,4 +353,15 @@ Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date test.t1 analyze status Table is already up to date
alter table t1 add column a varchar(8); alter table t1 add column a varchar(8);
drop table t1; drop table t1;
#
# Bug mdev-487: memory leak in ANALYZE with stat tables
#
SET use_stat_tables = 'preferably';
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
DELETE FROM t1 WHERE a=1;
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -380,6 +380,17 @@ Table Op Msg_type Msg_text ...@@ -380,6 +380,17 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK test.t1 analyze status OK
alter table t1 add column a varchar(8); alter table t1 add column a varchar(8);
drop table t1; drop table t1;
#
# Bug mdev-487: memory leak in ANALYZE with stat tables
#
SET use_stat_tables = 'preferably';
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
DELETE FROM t1 WHERE a=1;
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
SET SESSION STORAGE_ENGINE=DEFAULT; SET SESSION STORAGE_ENGINE=DEFAULT;
...@@ -166,5 +166,18 @@ alter table t1 add column a varchar(8); ...@@ -166,5 +166,18 @@ alter table t1 add column a varchar(8);
drop table t1; drop table t1;
--echo #
--echo # Bug mdev-487: memory leak in ANALYZE with stat tables
--echo #
SET use_stat_tables = 'preferably';
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
DELETE FROM t1 WHERE a=1;
ANALYZE TABLE t1;
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -179,6 +179,7 @@ public: ...@@ -179,6 +179,7 @@ public:
inline void init(THD *thd, Field * table_field); inline void init(THD *thd, Field * table_field);
inline void add(ha_rows rowno); inline void add(ha_rows rowno);
inline void finish(ha_rows rows); inline void finish(ha_rows rows);
inline void cleanup();
}; };
...@@ -1893,6 +1894,22 @@ void Column_statistics_collected::finish(ha_rows rows) ...@@ -1893,6 +1894,22 @@ void Column_statistics_collected::finish(ha_rows rows)
} }
/**
@brief
Clean up auxiliary structures used for aggregation
*/
inline
void Column_statistics_collected::cleanup()
{
if (count_distinct)
{
delete count_distinct;
count_distinct= NULL;
}
}
/** /**
@brief @brief
Collect statistical data on an index Collect statistical data on an index
...@@ -2047,7 +2064,11 @@ int collect_statistics_for_table(THD *thd, TABLE *table) ...@@ -2047,7 +2064,11 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
break; break;
if (rc) if (rc)
{
if (rc == HA_ERR_RECORD_DELETED)
continue;
break; break;
}
for (field_ptr= table->field; *field_ptr; field_ptr++) for (field_ptr= table->field; *field_ptr; field_ptr++)
{ {
...@@ -2071,14 +2092,17 @@ int collect_statistics_for_table(THD *thd, TABLE *table) ...@@ -2071,14 +2092,17 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
{ {
table->collected_stats->cardinality_is_null= FALSE; table->collected_stats->cardinality_is_null= FALSE;
table->collected_stats->cardinality= rows; table->collected_stats->cardinality= rows;
}
for (field_ptr= table->field; *field_ptr; field_ptr++) for (field_ptr= table->field; *field_ptr; field_ptr++)
{ {
table_field= *field_ptr; table_field= *field_ptr;
if (!bitmap_is_set(table->read_set, table_field->field_index)) if (!bitmap_is_set(table->read_set, table_field->field_index))
continue; continue;
if (!rc)
table_field->collected_stats->finish(rows); table_field->collected_stats->finish(rows);
} else
table_field->collected_stats->cleanup();
} }
if (!rc) if (!rc)
......
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