summaryrefslogtreecommitdiffstats
path: root/sql/opt_sum.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
commita2a2e32c02643a0cec111511220227703fda1cd5 (patch)
tree69cc2b631234c2a8e026b9cd4d72676c61c594df /sql/opt_sum.cc
parentReleasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff)
downloadmariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz
mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sql/opt_sum.cc')
-rw-r--r--sql/opt_sum.cc54
1 files changed, 36 insertions, 18 deletions
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 794ec40f..30739054 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -55,7 +55,7 @@
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, Field* field,
COND *cond, uint *range_fl,
- uint *key_prefix_length);
+ uint *key_prefix_length, bool *reverse);
static int reckey_in_range(bool max_fl, TABLE_REF *ref, Field* field,
COND *cond, uint range_fl, uint prefix_len);
static int maxmin_in_range(bool max_fl, Field* field, COND *cond);
@@ -101,6 +101,7 @@ static ulonglong get_exact_record_count(List<TABLE_LIST> &tables)
@item_field Field used in MIN()
@range_fl Whether range endpoint is strict less than
@prefix_len Length of common key part for the range
+ @reverse Whether key part used is reverse descending index
@retval
0 No errors
@@ -109,12 +110,15 @@ static ulonglong get_exact_record_count(List<TABLE_LIST> &tables)
static int get_index_min_value(TABLE *table, TABLE_REF *ref,
Item_field *item_field, uint range_fl,
- uint prefix_len)
+ uint prefix_len, bool reverse)
{
int error;
if (!ref->key_length)
- error= table->file->ha_index_first(table->record[0]);
+ {
+ error= reverse ? table->file->ha_index_last(table->record[0]) :
+ table->file->ha_index_first(table->record[0]);
+ }
else
{
/*
@@ -139,6 +143,8 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref,
error= table->file->ha_index_read_map(table->record[0],
ref->key_buff,
make_prev_keypart_map(ref->key_parts),
+ reverse ?
+ HA_READ_PREFIX_LAST_OR_PREV :
HA_READ_KEY_OR_NEXT);
else
{
@@ -154,6 +160,7 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref,
error= table->file->ha_index_read_map(table->record[0],
ref->key_buff,
make_prev_keypart_map(ref->key_parts),
+ reverse ? HA_READ_BEFORE_KEY :
HA_READ_AFTER_KEY);
/*
If the found record is outside the group formed by the search
@@ -194,21 +201,31 @@ static int get_index_min_value(TABLE *table, TABLE_REF *ref,
@param table Table object
@param ref Reference to the structure where we store the key value
@range_fl Whether range endpoint is strict greater than
+ @reverse Whether the key part used is reverse descending index
@retval
0 No errors
HA_ERR_... Otherwise
*/
-static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl)
+static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl,
+ bool reverse)
{
- return (ref->key_length ?
- table->file->ha_index_read_map(table->record[0], ref->key_buff,
- make_prev_keypart_map(ref->key_parts),
- range_fl & NEAR_MAX ?
- HA_READ_BEFORE_KEY :
- HA_READ_PREFIX_LAST_OR_PREV) :
- table->file->ha_index_last(table->record[0]));
+ if (ref->key_length)
+ {
+ return table->file->ha_index_read_map(table->record[0], ref->key_buff,
+ make_prev_keypart_map(ref->key_parts),
+ range_fl & NEAR_MAX ?
+ (reverse ? HA_READ_AFTER_KEY :
+ HA_READ_BEFORE_KEY) :
+ (reverse ? HA_READ_KEY_OR_NEXT :
+ HA_READ_PREFIX_LAST_OR_PREV));
+ }
+ else
+ {
+ return reverse ? table->file->ha_index_first(table->record[0]) :
+ table->file->ha_index_last(table->record[0]);
+ }
}
@@ -378,6 +395,7 @@ int opt_sum_query(THD *thd,
uchar key_buff[MAX_KEY_LENGTH];
TABLE_REF ref;
uint range_fl, prefix_len;
+ bool reverse= false;
ref.key_buff= key_buff;
Item_field *item_field= (Item_field*) (expr->real_item());
@@ -393,7 +411,7 @@ int opt_sum_query(THD *thd,
*/
if (table->file->inited || (outer_tables & table->map) ||
!find_key_for_maxmin(is_max, &ref, item_field->field, conds,
- &range_fl, &prefix_len))
+ &range_fl, &prefix_len, &reverse))
{
const_result= 0;
break;
@@ -407,9 +425,9 @@ int opt_sum_query(THD *thd,
if (likely(!(error= table->file->ha_index_init((uint) ref.key,
1))))
error= (is_max ?
- get_index_max_value(table, &ref, range_fl) :
+ get_index_max_value(table, &ref, range_fl, reverse) :
get_index_min_value(table, &ref, item_field, range_fl,
- prefix_len));
+ prefix_len, reverse));
}
/* Verify that the read tuple indeed matches the search key */
if (!error &&
@@ -899,6 +917,7 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
@param[in] cond WHERE condition
@param[out] range_fl Bit flags for how to search if key is ok
@param[out] prefix_len Length of prefix for the search range
+ @param[out] reverse Whether the key part used is descending index
@note
This function may set field->table->key_read to true,
@@ -914,7 +933,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
Field* field, COND *cond,
- uint *range_fl, uint *prefix_len)
+ uint *range_fl, uint *prefix_len,
+ bool *reverse)
{
if (!(field->flags & PART_KEY_FLAG))
return FALSE; // Not key field
@@ -953,9 +973,6 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
part->length < part_field->key_length())
break;
- if (part->key_part_flag & HA_REVERSE_SORT)
- break; // TODO MDEV-27576
-
if (field->eq(part->field))
{
ref->key= idx;
@@ -997,6 +1014,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
*/
if (field->part_of_key.is_set(idx))
table->file->ha_start_keyread(idx);
+ *reverse= part->key_part_flag & HA_REVERSE_SORT ? true : false;
DBUG_RETURN(TRUE);
}
}