1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-15656 Assertion `is_last_prefix <= 0' failed in QUICK_GROUP_MIN_MAX_SELECT::get_next

When QUICK_GROUP_MIN_MAX_SELECT is initialized or being reset
it stores the prefix of the last group of the index chosen for
retrieving data (last_value). Later, when looping through records
at get_next() method, the server checks whether the retrieved
group is the last, and if so, it finishes processing.

At the same time, it looks like there is no need for that additional
check since method next_prefix() returns HA_ERR_KEY_NOT_FOUND
or HA_ERR_END_OF_FILE when there are no more satisfying records.
If we do not perform the check, we do not need to retrieve and
store last_value either.

This commit removes using of last_value from QUICK_GROUP_MIN_MAX_SELECT.

Reviewer: Sergei Petrunia <sergey@mariadb.com>
This commit is contained in:
Oleg Smirnov
2023-11-10 20:03:06 +07:00
parent d5fc34db4c
commit a8bd6a9813
6 changed files with 202 additions and 38 deletions

View File

@@ -14669,13 +14669,6 @@ int QUICK_GROUP_MIN_MAX_SELECT::init()
{
if (group_prefix) /* Already initialized. */
return 0;
/*
We allocate one byte more to serve the case when the last field in
the buffer is compared using uint3korr (e.g. a Field_newdate field)
*/
if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len+1)))
return 1;
/*
We may use group_prefix to store keys with all select fields, so allocate
enough space for it.
@@ -14931,8 +14924,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
QUICK_GROUP_MIN_MAX_SELECT::reset()
DESCRIPTION
Initialize the index chosen for access and find and store the prefix
of the last group. The method is expensive since it performs disk access.
Initialize the index chosen for access.
RETURN
0 OK
@@ -14954,12 +14946,6 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
}
if (quick_prefix_select && quick_prefix_select->reset())
DBUG_RETURN(1);
result= file->ha_index_last(record);
if (result == HA_ERR_END_OF_FILE)
DBUG_RETURN(0);
/* Save the prefix of the last group. */
key_copy(last_prefix, record, index_info, group_prefix_len);
DBUG_RETURN(0);
}
@@ -15005,34 +14991,20 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next()
#else
int result;
#endif
int is_last_prefix= 0;
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::get_next");
/*
Loop until a group is found that satisfies all query conditions or the last
group is reached.
Loop until a group is found that satisfies all query conditions or
there are no satisfying groups left
*/
do
{
result= next_prefix();
/*
Check if this is the last group prefix. Notice that at this point
this->record contains the current prefix in record format.
*/
if (!result)
{
is_last_prefix= key_cmp(index_info->key_part, last_prefix,
group_prefix_len);
DBUG_ASSERT(is_last_prefix <= 0);
}
else
{
if (result == HA_ERR_KEY_NOT_FOUND)
continue;
if (result != 0)
break;
}
/*
At this point this->record contains the current prefix in record format.
*/
if (have_min)
{
min_res= next_min();
@@ -15061,8 +15033,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next()
HA_READ_KEY_EXACT);
result= have_min ? min_res : have_max ? max_res : result;
} while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
is_last_prefix != 0);
} while (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE);
if (result == HA_ERR_KEY_NOT_FOUND)
result= HA_ERR_END_OF_FILE;