Commit 775e7ce6 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-27303 Table corruption after insert into a non-InnoDB table with DESC index

optimized prefix search didn't take into account descending indexes

also fixes MDEV-27330
parent d6ab34b3
...@@ -2706,3 +2706,43 @@ DROP TABLE t1; ...@@ -2706,3 +2706,43 @@ DROP TABLE t1;
# #
# End of 5.5 tests # End of 5.5 tests
# #
#
# MDEV-27303 Table corruption after insert into a non-InnoDB table with DESC index
#
create table t1 (
a bigint default 0,
b bigint default 0,
c binary(128) not null,
d datetime default '0000-00-00 00:00:00',
key (c desc,b,d,a)
) engine=aria;
insert into t1 (c) values
('xx'),('bb'),('tt'),('pp'),('mm'),('yy'),('rr'),('bb'),('yy'),('gg'),
('dd'),('fx'),('wi'),('ix'),('ox'),('mu'),('ux'),('pm'),('mx'),('xu'),
('ul'),('lp'),('px'),('lp'),('xx'),('pq'),('qs'),('se'),('ee'),('xx'),
('rv'),('ff'),('vj'),('jy'),('yn'),('nc'),('nx'),('hj'),('ji'),('ik'),
('kk'),('ww'),('xx'),('yd'),('dw'),('wk'),('kr'),('dd'),('rj'),('jf'),
('bx'),('fc'),('cp'),('pm'),('mw'),('wy'),('yl'),('li'),('ic'),('he'),
('ci'),('il'),('lz'),('zd'),('gz'),('xd'),('ze'),('dm'),('ms'),('xd'),
('sw'),('we'),('nb'),('tx'),('vr'),('xw'),('aa'),('ah'),('hd'),('jl'),
('lf'),('fw'),('wx'),('xh'),('hr'),('zx'),('vw'),('rm'),('mx'),('xt'),
('tp'),('ps'),('sh'),('ga'),('df'),('as'),('gz'),('xd'),('yy'),('xr');
check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
#
# MDEV-27330 Wrong sorting order with DESC index and empty strings in MyISAM/Aria table
#
create table t (id int, c char(128) not null, key (c desc));
insert into t values (1,''),(2,'foo'),(3,''),(4,'bar');
select c from t order by c;
c
bar
foo
drop table t;
#
# End of 10.8 tests
#
...@@ -1830,3 +1830,39 @@ DROP TABLE t1; ...@@ -1830,3 +1830,39 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 5.5 tests --echo # End of 5.5 tests
--echo # --echo #
--echo #
--echo # MDEV-27303 Table corruption after insert into a non-InnoDB table with DESC index
--echo #
create table t1 (
a bigint default 0,
b bigint default 0,
c binary(128) not null,
d datetime default '0000-00-00 00:00:00',
key (c desc,b,d,a)
) engine=aria;
insert into t1 (c) values
('xx'),('bb'),('tt'),('pp'),('mm'),('yy'),('rr'),('bb'),('yy'),('gg'),
('dd'),('fx'),('wi'),('ix'),('ox'),('mu'),('ux'),('pm'),('mx'),('xu'),
('ul'),('lp'),('px'),('lp'),('xx'),('pq'),('qs'),('se'),('ee'),('xx'),
('rv'),('ff'),('vj'),('jy'),('yn'),('nc'),('nx'),('hj'),('ji'),('ik'),
('kk'),('ww'),('xx'),('yd'),('dw'),('wk'),('kr'),('dd'),('rj'),('jf'),
('bx'),('fc'),('cp'),('pm'),('mw'),('wy'),('yl'),('li'),('ic'),('he'),
('ci'),('il'),('lz'),('zd'),('gz'),('xd'),('ze'),('dm'),('ms'),('xd'),
('sw'),('we'),('nb'),('tx'),('vr'),('xw'),('aa'),('ah'),('hd'),('jl'),
('lf'),('fw'),('wx'),('xh'),('hr'),('zx'),('vw'),('rm'),('mx'),('xt'),
('tp'),('ps'),('sh'),('ga'),('df'),('as'),('gz'),('xd'),('yy'),('xr');
check table t1 extended;
drop table t1;
--echo #
--echo # MDEV-27330 Wrong sorting order with DESC index and empty strings in MyISAM/Aria table
--echo #
create table t (id int, c char(128) not null, key (c desc));
insert into t values (1,''),(2,'foo'),(3,''),(4,'bar');
select c from t order by c;
drop table t;
--echo #
--echo # End of 10.8 tests
--echo #
...@@ -68,3 +68,46 @@ pk apk data ...@@ -68,3 +68,46 @@ pk apk data
3 4 NULL 3 4 NULL
5 6 NULL 5 6 NULL
drop table t1; drop table t1;
#
# End of 5.5 tests
#
#
# MDEV-27303 Table corruption after insert into a non-InnoDB table with DESC index
#
create table t1 (
a bigint default 0,
b bigint default 0,
c binary(128) not null,
d datetime default '0000-00-00 00:00:00',
key (c desc,b,d,a)
) engine=aria;
insert into t1 (c) values
('xx'),('bb'),('tt'),('pp'),('mm'),('yy'),('rr'),('bb'),('yy'),('gg'),
('dd'),('fx'),('wi'),('ix'),('ox'),('mu'),('ux'),('pm'),('mx'),('xu'),
('ul'),('lp'),('px'),('lp'),('xx'),('pq'),('qs'),('se'),('ee'),('xx'),
('rv'),('ff'),('vj'),('jy'),('yn'),('nc'),('nx'),('hj'),('ji'),('ik'),
('kk'),('ww'),('xx'),('yd'),('dw'),('wk'),('kr'),('dd'),('rj'),('jf'),
('bx'),('fc'),('cp'),('pm'),('mw'),('wy'),('yl'),('li'),('ic'),('he'),
('ci'),('il'),('lz'),('zd'),('gz'),('xd'),('ze'),('dm'),('ms'),('xd'),
('sw'),('we'),('nb'),('tx'),('vr'),('xw'),('aa'),('ah'),('hd'),('jl'),
('lf'),('fw'),('wx'),('xh'),('hr'),('zx'),('vw'),('rm'),('mx'),('xt'),
('tp'),('ps'),('sh'),('ga'),('df'),('as'),('gz'),('xd'),('yy'),('xr');
check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
#
# MDEV-27330 Wrong sorting order with DESC index and empty strings in MyISAM/Aria table
#
create table t (id int, c char(128) not null, key (c desc)) engine=aria;
insert into t values (1,''),(2,'foo'),(3,''),(4,'bar');
select c from t order by c;
c
bar
foo
drop table t;
#
# End of 10.8 tests
#
...@@ -109,3 +109,43 @@ select * from t1 order by pk; ...@@ -109,3 +109,43 @@ select * from t1 order by pk;
load data infile '../../std_data/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk); load data infile '../../std_data/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
select * from t1 order by pk; select * from t1 order by pk;
drop table t1; drop table t1;
--echo #
--echo # End of 5.5 tests
--echo #
--echo #
--echo # MDEV-27303 Table corruption after insert into a non-InnoDB table with DESC index
--echo #
create table t1 (
a bigint default 0,
b bigint default 0,
c binary(128) not null,
d datetime default '0000-00-00 00:00:00',
key (c desc,b,d,a)
) engine=aria;
insert into t1 (c) values
('xx'),('bb'),('tt'),('pp'),('mm'),('yy'),('rr'),('bb'),('yy'),('gg'),
('dd'),('fx'),('wi'),('ix'),('ox'),('mu'),('ux'),('pm'),('mx'),('xu'),
('ul'),('lp'),('px'),('lp'),('xx'),('pq'),('qs'),('se'),('ee'),('xx'),
('rv'),('ff'),('vj'),('jy'),('yn'),('nc'),('nx'),('hj'),('ji'),('ik'),
('kk'),('ww'),('xx'),('yd'),('dw'),('wk'),('kr'),('dd'),('rj'),('jf'),
('bx'),('fc'),('cp'),('pm'),('mw'),('wy'),('yl'),('li'),('ic'),('he'),
('ci'),('il'),('lz'),('zd'),('gz'),('xd'),('ze'),('dm'),('ms'),('xd'),
('sw'),('we'),('nb'),('tx'),('vr'),('xw'),('aa'),('ah'),('hd'),('jl'),
('lf'),('fw'),('wx'),('xh'),('hr'),('zx'),('vw'),('rm'),('mx'),('xt'),
('tp'),('ps'),('sh'),('ga'),('df'),('as'),('gz'),('xd'),('yy'),('xr');
check table t1 extended;
drop table t1;
--echo #
--echo # MDEV-27330 Wrong sorting order with DESC index and empty strings in MyISAM/Aria table
--echo #
create table t (id int, c char(128) not null, key (c desc)) engine=aria;
insert into t values (1,''),(2,'foo'),(3,''),(4,'bar');
select c from t order by c;
drop table t;
--echo #
--echo # End of 10.8 tests
--echo #
...@@ -446,6 +446,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -446,6 +446,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
MARIA_KEYDEF *keyinfo= key->keyinfo; MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_SHARE *share= keyinfo->share; MARIA_SHARE *share= keyinfo->share;
const uchar *sort_order= keyinfo->seg->charset->sort_order; const uchar *sort_order= keyinfo->seg->charset->sort_order;
const int reverse = keyinfo->seg->flag & HA_REVERSE_SORT;
DBUG_ENTER("_ma_prefix_search"); DBUG_ENTER("_ma_prefix_search");
t_buff[0]=0; /* Avoid bugs */ t_buff[0]=0; /* Avoid bugs */
...@@ -579,7 +580,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -579,7 +580,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
/* /*
If prefix_len > cmplen then we are in the end-space comparison If prefix_len > cmplen then we are in the end-space comparison
phase. Do not try to acces the key any more ==> left= 0. phase. Do not try to access the key any more ==> left= 0.
*/ */
left= ((len <= cmplen) ? suffix_len : left= ((len <= cmplen) ? suffix_len :
((prefix_len < cmplen) ? cmplen - prefix_len : 0)); ((prefix_len < cmplen) ? cmplen - prefix_len : 0));
...@@ -599,7 +600,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -599,7 +600,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
break; break;
} }
if (my_flag>0) /* mismatch */ if ((reverse ? -my_flag : my_flag) > 0) /* mismatch */
break; break;
if (my_flag==0) /* match */ if (my_flag==0) /* match */
{ {
...@@ -626,13 +627,10 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -626,13 +627,10 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
for ( ; k < k_end && *k == ' '; k++) ; for ( ; k < k_end && *k == ' '; k++) ;
if (k == k_end) if (k == k_end)
goto cmp_rest; /* should never happen */ goto cmp_rest; /* should never happen */
if ((uchar) *k < (uchar) ' ') my_flag= (uchar)' ' - *k;
{
my_flag= 1; /* Compared string is smaller */
break;
}
my_flag= -1; /* Continue searching */
} }
if ((reverse ? -my_flag : my_flag) > 0)
break;
} }
else if (len > cmplen) else if (len > cmplen)
{ {
...@@ -646,13 +644,10 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -646,13 +644,10 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
vseg++, matched++) ; vseg++, matched++) ;
DBUG_ASSERT(vseg < vseg_end); DBUG_ASSERT(vseg < vseg_end);
if ((uchar) *vseg > (uchar) ' ') my_flag= *vseg - (uchar)' ';
{ if ((reverse ? -my_flag : my_flag) > 0)
my_flag= 1; /* Compared string is smaller */
break; break;
} }
my_flag= -1; /* Continue searching */
}
else else
{ {
cmp_rest: cmp_rest:
...@@ -690,7 +685,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page, ...@@ -690,7 +685,7 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
*ret_pos=page; *ret_pos=page;
} }
if (my_flag) if (my_flag)
flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag; flag= reverse ? -my_flag : my_flag;
if (flag == 0) if (flag == 0)
{ {
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
......
...@@ -309,6 +309,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -309,6 +309,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uchar *UNINIT_VAR(saved_vseg); uchar *UNINIT_VAR(saved_vseg);
uint saved_length=0, saved_prefix_len=0; uint saved_length=0, saved_prefix_len=0;
uint length_pack; uint length_pack;
const int reverse = keyinfo->seg->flag & HA_REVERSE_SORT;
DBUG_ENTER("_mi_prefix_search"); DBUG_ENTER("_mi_prefix_search");
t_buff[0]=0; /* Avoid bugs */ t_buff[0]=0; /* Avoid bugs */
...@@ -452,7 +453,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -452,7 +453,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
break; break;
} }
if (my_flag>0) /* mismatch */ if ((reverse ? -my_flag : my_flag) > 0) /* mismatch */
break; break;
if (my_flag==0) /* match */ if (my_flag==0) /* match */
{ {
...@@ -478,13 +479,10 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -478,13 +479,10 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
for ( ; k < k_end && *k == ' '; k++) ; for ( ; k < k_end && *k == ' '; k++) ;
if (k == k_end) if (k == k_end)
goto cmp_rest; /* should never happen */ goto cmp_rest; /* should never happen */
if (*k < (uchar) ' ') my_flag= (uchar)' ' - *k;
{
my_flag= 1; /* Compared string is smaller */
break;
}
my_flag= -1; /* Continue searching */
} }
if ((reverse ? -my_flag : my_flag) > 0)
break;
} }
else if (len > cmplen) else if (len > cmplen)
{ {
...@@ -498,13 +496,10 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -498,13 +496,10 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
vseg++, matched++) ; vseg++, matched++) ;
DBUG_ASSERT(vseg < vseg_end); DBUG_ASSERT(vseg < vseg_end);
if (*vseg > (uchar) ' ') my_flag= *vseg - (uchar)' ';
{ if ((reverse ? -my_flag : my_flag) > 0)
my_flag= 1; /* Compared string is smaller */
break; break;
} }
my_flag= -1; /* Continue searching */
}
else else
{ {
cmp_rest: cmp_rest:
...@@ -541,7 +536,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, ...@@ -541,7 +536,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
*ret_pos=page; *ret_pos=page;
} }
if (my_flag) if (my_flag)
flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag; flag= reverse ? -my_flag : my_flag;
if (flag == 0) if (flag == 0)
{ {
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len); memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
......
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