From 2bbcec41488ff4506cb848357086e8fb07a9648c Mon Sep 17 00:00:00 2001
From: Igor Babaev <igor@askmonty.org>
Date: Tue, 11 Sep 2012 22:36:04 -0700
Subject: [PATCH] Fixed bug mdev-518. If some statistical tables are corrupted
 the server should use the conventional statistical data.

---
 mysql-test/r/stat_tables.result        | 16 ++++++++++++++++
 mysql-test/r/stat_tables_innodb.result | 16 ++++++++++++++++
 mysql-test/t/stat_tables.test          | 24 ++++++++++++++++++++++++
 sql/sql_statistics.cc                  |  8 +++++---
 4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result
index 3cc650e7050..169266fea25 100644
--- a/mysql-test/r/stat_tables.result
+++ b/mysql-test/r/stat_tables.result
@@ -364,4 +364,20 @@ ANALYZE TABLE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	OK
 DROP TABLE t1;
+#
+# Bug mdev-518: corrupted/missing statistical tables
+# 
+CREATE TABLE t1 (i int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+FLUSH TABLE t1;
+SET use_stat_tables='never';
+EXPLAIN SELECT * FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+FLUSH TABLES;
+SET use_stat_tables='preferably';
+EXPLAIN SELECT * FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+DROP TABLE t1;
 set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result
index bb0497ee331..699df08225e 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/stat_tables_innodb.result
@@ -391,6 +391,22 @@ ANALYZE TABLE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	analyze	status	OK
 DROP TABLE t1;
+#
+# Bug mdev-518: corrupted/missing statistical tables
+# 
+CREATE TABLE t1 (i int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+FLUSH TABLE t1;
+SET use_stat_tables='never';
+EXPLAIN SELECT * FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+FLUSH TABLES;
+SET use_stat_tables='preferably';
+EXPLAIN SELECT * FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+DROP TABLE t1;
 set use_stat_tables=@save_use_stat_tables;
 set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
 SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test
index 3ef5b4e9b92..e3712c8d022 100644
--- a/mysql-test/t/stat_tables.test
+++ b/mysql-test/t/stat_tables.test
@@ -180,4 +180,28 @@ ANALYZE TABLE t1;
 
 DROP TABLE t1;
 
+--echo #
+--echo # Bug mdev-518: corrupted/missing statistical tables
+--echo # 
+
+CREATE TABLE t1 (i int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+FLUSH TABLE t1;
+SET use_stat_tables='never';
+EXPLAIN SELECT * FROM t1;
+
+--move_file $MYSQLTEST_VARDIR/mysqld.1/data/mysql/table_stat.MYD $MYSQLTEST_VARDIR/mysqld.1/data/mysql/table_stat.MYD.save
+
+FLUSH TABLES;
+SET use_stat_tables='preferably';
+--disable_warnings
+EXPLAIN SELECT * FROM t1;
+--enable_warnings
+
+# Cleanup
+--move_file $MYSQLTEST_VARDIR/mysqld.1/data/mysql/table_stat.MYD.save $MYSQLTEST_VARDIR/mysqld.1/data/mysql/table_stat.MYD
+DROP TABLE t1;
+
 set use_stat_tables=@save_use_stat_tables;
+
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 7c5086da439..412d5722d74 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2908,15 +2908,17 @@ void set_statistics_for_table(THD *thd, TABLE *table)
 {
   uint use_stat_table_mode= thd->variables.use_stat_tables;
   table->used_stat_records= 
-    (use_stat_table_mode <= 1 || !table->s->read_stats ||
-      table->s->read_stats->cardinality_is_null) ?
+    (use_stat_table_mode <= 1 ||
+     !table->s->stats_is_read || !table->s->read_stats ||
+     table->s->read_stats->cardinality_is_null) ?
     table->file->stats.records : table->s->read_stats->cardinality;
   KEY *key_info, *key_info_end;
   for (key_info= table->key_info, key_info_end= key_info+table->s->keys;
        key_info < key_info_end; key_info++)
   {
     key_info->is_statistics_from_stat_tables=
-      (use_stat_table_mode > 1  && key_info->read_stats &&
+      (use_stat_table_mode > 1  && table->s->stats_is_read &&
+       key_info->read_stats &&
        key_info->read_stats->avg_frequency_is_inited() &&
        key_info->read_stats->get_avg_frequency(0) > 0.5);
   }
-- 
2.30.9