Commit 3b94309a authored by Varun Gupta's avatar Varun Gupta

MDEV-23753: SIGSEGV in Column_stat::store_stat_fields

For EITS collection min and max fields are allocated for each column
that is set in the read_set bitmap of a table. This allocation of min and max
fields happens inside alloc_statistics_for_table.

For a partitioned table ha_rnd_init is called inside the function
collect_statistics_for_table which sets the read_set bitmap for the columns
inside the partition expression. This happens only when there is a write lock
on the partitioned table.
But the allocation happens before this, so min and max fields are not allocated
for the columns involved in the partition expression.
This resulted in a crash, as the EITS statistics were collected but there was
no min and max field to store the value to.

The fix would be to call ha_rnd_init inside the function alloc_statistics_for_table
that would make sure that min and max fields are allocated for the columns
involved in the partition expression.
parent a216672d
...@@ -825,5 +825,19 @@ length(a) ...@@ -825,5 +825,19 @@ length(a)
set names latin1; set names latin1;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;
drop table t1; drop table t1;
#
# MDEV-23753: SIGSEGV in Column_stat::store_stat_fields
#
CREATE TABLE t1 (a INT, b INT) PARTITION BY HASH (b) PARTITIONS 2;
LOCK TABLES t1 WRITE;
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (nonexisting) INDEXES (nonexisting);
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze error Invalid argument
DROP TABLE t1;
# please keep this at the last # please keep this at the last
set @@global.histogram_size=@save_histogram_size; set @@global.histogram_size=@save_histogram_size;
...@@ -852,6 +852,20 @@ length(a) ...@@ -852,6 +852,20 @@ length(a)
set names latin1; set names latin1;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;
drop table t1; drop table t1;
#
# MDEV-23753: SIGSEGV in Column_stat::store_stat_fields
#
CREATE TABLE t1 (a INT, b INT) PARTITION BY HASH (b) PARTITIONS 2;
LOCK TABLES t1 WRITE;
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES ();
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (nonexisting) INDEXES (nonexisting);
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze error Invalid argument
DROP TABLE t1;
# please keep this at the last # please keep this at the last
set @@global.histogram_size=@save_histogram_size; set @@global.histogram_size=@save_histogram_size;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
......
--source include/have_stat_tables.inc --source include/have_stat_tables.inc
--source include/have_partition.inc
select @@global.use_stat_tables; select @@global.use_stat_tables;
select @@session.use_stat_tables; select @@session.use_stat_tables;
...@@ -568,5 +569,16 @@ set names latin1; ...@@ -568,5 +569,16 @@ set names latin1;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;
drop table t1; drop table t1;
--echo #
--echo # MDEV-23753: SIGSEGV in Column_stat::store_stat_fields
--echo #
CREATE TABLE t1 (a INT, b INT) PARTITION BY HASH (b) PARTITIONS 2;
LOCK TABLES t1 WRITE;
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES ();
ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (nonexisting) INDEXES (nonexisting);
DROP TABLE t1;
--echo # please keep this at the last --echo # please keep this at the last
set @@global.histogram_size=@save_histogram_size; set @@global.histogram_size=@save_histogram_size;
...@@ -2110,6 +2110,10 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) ...@@ -2110,6 +2110,10 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root, ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root,
sizeof(ulonglong) * key_parts); sizeof(ulonglong) * key_parts);
if (table->file->ha_rnd_init(TRUE))
DBUG_RETURN(1);
table->file->ha_rnd_end();
uint columns= 0; uint columns= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++) for (field_ptr= table->field; *field_ptr; field_ptr++)
{ {
......
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