MDEV-7362: ANALYZE TABLES crash with table-independent-statistics gathering

FULLTEXT indexes do not permit index first lookups. By calling:
ha_index_first() with a garbage parameter, random data gets overwritten
that causes the table->field array to be corrupted. Subsequently, when
the field array is accessed, a segfault occurs.

By not allowing index statistics for FULLTEXT indexes, the problem is
resolved.
This commit is contained in:
Vicențiu Ciorbaru 2015-01-17 16:58:10 +00:00
parent 6e6750ad6c
commit 09d54b37f5
3 changed files with 71 additions and 2 deletions

View File

@ -0,0 +1,33 @@
CREATE TABLE t1 (a longtext, FULLTEXT KEY (`a`)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (unhex('3E0D0A4141414142334E7A6143317963324541414141424977414141674541726D'));
ANALYZE TABLE t1 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
SELECT * FROM mysql.index_stats WHERE index_name='a' AND table_name='t1';
db_name table_name index_name prefix_arity avg_frequency
test t1 a 1 NULL
DROP TABLE t1;
CREATE TABLE t1 (a longtext, FULLTEXT KEY (`a`)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (unhex('3E0D0A4141414142334E7A6143317963324541414141424977414141674541726D'));
ANALYZE TABLE t1 PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
SELECT * FROM mysql.index_stats WHERE index_name='a' AND table_name='t1';
db_name table_name index_name prefix_arity avg_frequency
test t1 a 1 NULL
DROP TABLE t1;
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;
INSERT INTO geom VALUES
(MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
ANALYZE TABLE geom PERSISTENT FOR ALL;
Table Op Msg_type Msg_text
test.geom analyze status Engine-independent statistics collected
test.geom analyze status OK
SELECT * FROM mysql.index_stats WHERE index_name='g' AND table_name='geom';
db_name table_name index_name prefix_arity avg_frequency
test geom g 1 NULL
DROP TABLE geom;

View File

@ -0,0 +1,30 @@
# Test cases that cover the crashes within:
# MDEV-7362 ANALYZE TABLES crash with table-independent-statistics gathering
# MDEV-7380 engine-independent stats SEGV on ANALYZE TABLE (#2)
--source include/have_stat_tables.inc
--source include/have_innodb.inc
CREATE TABLE t1 (a longtext, FULLTEXT KEY (`a`)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (unhex('3E0D0A4141414142334E7A6143317963324541414141424977414141674541726D'));
ANALYZE TABLE t1 PERSISTENT FOR ALL;
--sorted_result
SELECT * FROM mysql.index_stats WHERE index_name='a' AND table_name='t1';
DROP TABLE t1;
CREATE TABLE t1 (a longtext, FULLTEXT KEY (`a`)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (unhex('3E0D0A4141414142334E7A6143317963324541414141424977414141674541726D'));
ANALYZE TABLE t1 PERSISTENT FOR ALL;
--sorted_result
SELECT * FROM mysql.index_stats WHERE index_name='a' AND table_name='t1';
DROP TABLE t1;
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;
INSERT INTO geom VALUES
(MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
ANALYZE TABLE geom PERSISTENT FOR ALL;
--sorted_result
SELECT * FROM mysql.index_stats WHERE index_name='g' AND table_name='geom';
DROP TABLE geom;

View File

@ -2355,9 +2355,15 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index)
int rc= 0;
KEY *key_info= &table->key_info[index];
ha_rows rows= 0;
Index_prefix_calc index_prefix_calc(table, key_info);
DBUG_ENTER("collect_statistics_for_index");
/* No statistics for FULLTEXT indexes. */
if (key_info->flags & HA_FULLTEXT)
DBUG_RETURN(rc);
Index_prefix_calc index_prefix_calc(table, key_info);
DEBUG_SYNC(table->in_use, "statistics_collection_start1");
DEBUG_SYNC(table->in_use, "statistics_collection_start2");