diff options
author | Vlad Lesin <vlad_lesin@mail.ru> | 2020-01-20 22:56:01 +0300 |
---|---|---|
committer | Vlad Lesin <vlad_lesin@mail.ru> | 2020-01-21 17:06:31 +0300 |
commit | 4e7f3fb8332c42c3beb2376ee0d90f559f1e7470 (patch) | |
tree | 5a5a29224bbff1370db58b11fac9b61a26aac1b5 | |
parent | 90e7e6783b8a667012146e16f4d804a0c8b9ee8a (diff) | |
download | mariadb-git-4e7f3fb8332c42c3beb2376ee0d90f559f1e7470.tar.gz |
MDEV-14183: aria_pack segfaults in compress_maria_file
Column definition order in st_maria_share::columndef can differ from
order of fields in record(see also st_maria_share::column_nr,
st_maria_columndef::column_nr, _ma_column_nr_write(),
_ma_column_nr_read()). This was not taken into account in aria_pack
tool.
The fix is to initialize elements of HUFF_COUNTS array in the correct
order.
-rw-r--r-- | mysql-test/suite/maria/aria_pack_mdev14183.result | 22 | ||||
-rw-r--r-- | mysql-test/suite/maria/aria_pack_mdev14183.test | 22 | ||||
-rw-r--r-- | storage/maria/maria_pack.c | 16 |
3 files changed, 53 insertions, 7 deletions
diff --git a/mysql-test/suite/maria/aria_pack_mdev14183.result b/mysql-test/suite/maria/aria_pack_mdev14183.result new file mode 100644 index 00000000000..cd1decdef75 --- /dev/null +++ b/mysql-test/suite/maria/aria_pack_mdev14183.result @@ -0,0 +1,22 @@ +CREATE TABLE `t` ( +`col_1` varchar(255) NOT NULL DEFAULT '', +`col_2` varchar(255) NOT NULL, +`col_3` int(11) NOT NULL DEFAULT '0', +`col_4` int(11) NOT NULL DEFAULT '0' +) ENGINE=Aria; +insert into t values +('foobar','qux',0,0),('abcdef','qux',0,0); +Compressing test/t.MAD: (2 records) +- Calculating statistics + +normal: 0 empty-space: 0 empty-zero: 0 empty-fill: 0 +pre-space: 0 end-space: 0 intervall-fields: 0 zero: 2 +Original trees: 4 After join: 1 +- Compressing file +Min record length: 5 Max length: 5 Mean total length: 35 +99.57% +SELECT * FROM t; +col_1 col_2 col_3 col_4 +foobar qux 0 0 +abcdef qux 0 0 +DROP TABLE t; diff --git a/mysql-test/suite/maria/aria_pack_mdev14183.test b/mysql-test/suite/maria/aria_pack_mdev14183.test new file mode 100644 index 00000000000..ab0589dc780 --- /dev/null +++ b/mysql-test/suite/maria/aria_pack_mdev14183.test @@ -0,0 +1,22 @@ +--source include/have_aria.inc +--source include/have_debug.inc + +CREATE TABLE `t` ( + `col_1` varchar(255) NOT NULL DEFAULT '', + `col_2` varchar(255) NOT NULL, + `col_3` int(11) NOT NULL DEFAULT '0', + `col_4` int(11) NOT NULL DEFAULT '0' +) ENGINE=Aria; + +insert into t values + ('foobar','qux',0,0),('abcdef','qux',0,0); + +--let $datadir= `SELECT @@datadir` +--source include/shutdown_mysqld.inc +# maria_pack crashes by assert() if the bug is not fixed +--exec cd $datadir && $MARIA_PACK -t test/t + +--source include/start_mysqld.inc +SELECT * FROM t; + +DROP TABLE t; diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 5166ae63758..6f2d9fe8a5d 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -782,27 +782,29 @@ static HUFF_COUNTS *init_huff_count(MARIA_HA *info,my_off_t records) for (i=0 ; i < info->s->base.fields ; i++) { enum en_fieldtype type; - count[i].field_length=info->s->columndef[i].length; - type= count[i].field_type= (enum en_fieldtype) info->s->columndef[i].type; + uint col_nr = info->s->columndef[i].column_nr; + count[col_nr].field_length=info->s->columndef[i].length; + type= count[col_nr].field_type= + (enum en_fieldtype) info->s->columndef[i].type; if (type == FIELD_INTERVALL || type == FIELD_CONSTANT || type == FIELD_ZERO) type = FIELD_NORMAL; - if (count[i].field_length <= 8 && + if (count[col_nr].field_length <= 8 && (type == FIELD_NORMAL || type == FIELD_SKIP_ZERO)) - count[i].max_zero_fill= count[i].field_length; + count[col_nr].max_zero_fill= count[col_nr].field_length; /* For every column initialize a tree, which is used to detect distinct column values. 'int_tree' works together with 'tree_buff' and 'tree_pos'. It's keys are implemented by pointers into 'tree_buff'. This is accomplished by '-1' as the element size. */ - init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL, + init_tree(&count[col_nr].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL, NULL, MYF(0)); if (records && type != FIELD_BLOB && type != FIELD_VARCHAR) - count[i].tree_pos=count[i].tree_buff = - my_malloc(count[i].field_length > 1 ? tree_buff_length : 2, + count[col_nr].tree_pos=count[col_nr].tree_buff = + my_malloc(count[col_nr].field_length > 1 ? tree_buff_length : 2, MYF(MY_WME)); } } |