Fix for Bug #39243 SELECT WHERE does not find row
Symptom was that records_in_range() found 0 matching keys which confused the optimizer to belive that there was no matching rows for the query mysql-test/r/maria.result: New testcase mysql-test/t/maria.test: New testcase storage/maria/ma_search.c: Fix bug in skip_key for keys that starts with a CHAR/VARCHAR NULL key.
This commit is contained in:
parent
7f960da42b
commit
be0b404266
@ -2243,3 +2243,35 @@ lock table t1 write concurrent;
|
|||||||
delete from t1;
|
delete from t1;
|
||||||
ERROR 42000: The storage engine for the table doesn't support DELETE in WRITE CONCURRENT
|
ERROR 42000: The storage engine for the table doesn't support DELETE in WRITE CONCURRENT
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (p int primary key, i int, a char(10), key k1(i), key k2(a))
|
||||||
|
engine maria;
|
||||||
|
insert into t1 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
|
||||||
|
(3, 1, 'yyyy'), (4, 3, 'zzzz');
|
||||||
|
insert into t1 values (5, 3, 'yyyy'), (6, 3, 'yyyy'), (7, 0, NULL),
|
||||||
|
(8, 0, NULL);
|
||||||
|
select * from t1 where a='zzzz';
|
||||||
|
p i a
|
||||||
|
4 3 zzzz
|
||||||
|
select * from t1 where a='yyyy';
|
||||||
|
p i a
|
||||||
|
3 1 yyyy
|
||||||
|
5 3 yyyy
|
||||||
|
6 3 yyyy
|
||||||
|
select * from t1 where a is NULL;
|
||||||
|
p i a
|
||||||
|
7 0 NULL
|
||||||
|
8 0 NULL
|
||||||
|
select * from t1;
|
||||||
|
p i a
|
||||||
|
1 1 qqqq
|
||||||
|
2 1 pppp
|
||||||
|
3 1 yyyy
|
||||||
|
4 3 zzzz
|
||||||
|
5 3 yyyy
|
||||||
|
6 3 yyyy
|
||||||
|
7 0 NULL
|
||||||
|
8 0 NULL
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
drop table t1;
|
||||||
|
@ -1542,3 +1542,20 @@ eval set global storage_engine=$default_engine, maria_page_checksum=$default_che
|
|||||||
--enable_result_log
|
--enable_result_log
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#39243 SELECT WHERE does not find row
|
||||||
|
# (Problem with skip_row)
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (p int primary key, i int, a char(10), key k1(i), key k2(a))
|
||||||
|
engine maria;
|
||||||
|
insert into t1 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
|
||||||
|
(3, 1, 'yyyy'), (4, 3, 'zzzz');
|
||||||
|
insert into t1 values (5, 3, 'yyyy'), (6, 3, 'yyyy'), (7, 0, NULL),
|
||||||
|
(8, 0, NULL);
|
||||||
|
select * from t1 where a='zzzz';
|
||||||
|
select * from t1 where a='yyyy';
|
||||||
|
select * from t1 where a is NULL;
|
||||||
|
select * from t1;
|
||||||
|
check table t1;
|
||||||
|
drop table t1;
|
||||||
|
@ -931,7 +931,7 @@ uint _ma_get_static_key(MARIA_KEY *key, uint page_flag, uint nod_flag,
|
|||||||
/**
|
/**
|
||||||
Skip over static length key from key-block
|
Skip over static length key from key-block
|
||||||
|
|
||||||
@fn _ma_skip_pack_key()
|
@fn _ma_skip_static_key()
|
||||||
@param key Keyinfo and buffer that can be used
|
@param key Keyinfo and buffer that can be used
|
||||||
@param nod_flag If nod: Length of node pointer, else zero.
|
@param nod_flag If nod: Length of node pointer, else zero.
|
||||||
@param key Points at key
|
@param key Points at key
|
||||||
@ -1049,6 +1049,7 @@ uint _ma_get_pack_key(MARIA_KEY *int_key, uint page_flag,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Key that is not packed against previous key */
|
||||||
if (keyseg->flag & HA_NULL_PART)
|
if (keyseg->flag & HA_NULL_PART)
|
||||||
{
|
{
|
||||||
if (!length--) /* Null part */
|
if (!length--) /* Null part */
|
||||||
@ -1121,6 +1122,9 @@ uint _ma_get_pack_key(MARIA_KEY *int_key, uint page_flag,
|
|||||||
@param nod_flag If nod: Length of node pointer, else zero.
|
@param nod_flag If nod: Length of node pointer, else zero.
|
||||||
@param key Points at key
|
@param key Points at key
|
||||||
|
|
||||||
|
@note
|
||||||
|
This is in principle a simpler version of _ma_get_pack_key()
|
||||||
|
|
||||||
@retval pointer to next key
|
@retval pointer to next key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1150,6 +1154,14 @@ uchar *_ma_skip_pack_key(MARIA_KEY *key, uint page_flag,
|
|||||||
page+= length;
|
page+= length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ((keyseg->flag & HA_NULL_PART) && length)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Keys that can have null use length+1 as the length for date as the
|
||||||
|
number 0 is reserved for keys that have a NULL value
|
||||||
|
*/
|
||||||
|
length--;
|
||||||
|
}
|
||||||
page+= length;
|
page+= length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1846,11 +1858,14 @@ _ma_calc_var_key_length(const MARIA_KEY *key, uint nod_flag,
|
|||||||
|
|
||||||
prefix byte(s) The high bit is set if this is a prefix for the prev key
|
prefix byte(s) The high bit is set if this is a prefix for the prev key
|
||||||
length Packed length if the previous was a prefix byte
|
length Packed length if the previous was a prefix byte
|
||||||
[length] data bytes ('length' bytes)
|
[data_length] data bytes ('length' bytes)
|
||||||
next-key-seg Next key segments
|
next-key-seg Next key segments
|
||||||
|
|
||||||
If the first segment can have NULL:
|
If the first segment can have NULL:
|
||||||
The length is 0 for NULLS and 1+length for not null columns.
|
If key was packed
|
||||||
|
data_length is length of rest of key
|
||||||
|
If key was not packed
|
||||||
|
The data_length is 0 for NULLS and 1+data_length for not null columns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user