diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2015-04-15 12:09:25 -0700 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2015-04-15 12:09:25 -0700 |
commit | c712b376d8189b963851db86a0bedd478aab869e (patch) | |
tree | 8d02a74357f8ba77261d79bd70ca6174e0fe5dd8 /sql/opt_range.cc | |
parent | 25da74ce3f17a4720f4f7f06b1d694ff417d6b60 (diff) | |
parent | d051f6c36beaf6c7ea269d6c174cca7482f3e823 (diff) | |
download | mariadb-git-bb-10.1-explain-analyze.tar.gz |
Merge branch '10.1' into bb-10.1-explain-analyzebb-10.1-explain-analyze
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4bef42e82bf..49aaa1dac1e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -14697,6 +14697,36 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_prefix() } +/** + Allocate a temporary buffer, populate the buffer using the group prefix key + and the min/max field key, and compare the result to the current key pointed + by index_info. + + @param key - the min or max field key + @param length - length of "key" +*/ +int +QUICK_GROUP_MIN_MAX_SELECT::cmp_min_max_key(const uchar *key, uint16 length) +{ + /* + Allocate a buffer. + Note, we allocate one extra byte, because some of Field_xxx::cmp(), + e.g. Field_newdate::cmp(), use uint3korr() which actually read four bytes + and then bit-and the read value with 0xFFFFFF. + See "MDEV-7920 main.group_min_max fails ... with valgrind" for details. + */ + uchar *buffer= (uchar*) my_alloca(real_prefix_len + min_max_arg_len + 1); + /* Concatenate the group prefix key and the min/max field key */ + memcpy(buffer, group_prefix, real_prefix_len); + memcpy(buffer + real_prefix_len, key, length); + /* Compare the key pointed by key_info to the created key */ + int cmp_res= key_cmp(index_info->key_part, buffer, + real_prefix_len + min_max_arg_len); + my_afree(buffer); + return cmp_res; +} + + /* Find the minimal key in a group that satisfies some range conditions for the min/max argument field. @@ -14798,15 +14828,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* If there is an upper limit, check if the found key is in the range. */ if ( !(cur_range->flag & NO_MAX_RANGE) ) { - /* Compose the MAX key for the range. */ - uchar *max_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len); - memcpy(max_key, group_prefix, real_prefix_len); - memcpy(max_key + real_prefix_len, cur_range->max_key, - cur_range->max_length); - /* Compare the found key with max_key. */ - int cmp_res= key_cmp(index_info->key_part, max_key, - real_prefix_len + min_max_arg_len); - my_afree(max_key); + int cmp_res= cmp_min_max_key(cur_range->max_key, cur_range->max_length); /* The key is outside of the range if: the interval is open and the key is equal to the maximum boundry @@ -14924,15 +14946,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* If there is a lower limit, check if the found key is in the range. */ if ( !(cur_range->flag & NO_MIN_RANGE) ) { - /* Compose the MIN key for the range. */ - uchar *min_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len); - memcpy(min_key, group_prefix, real_prefix_len); - memcpy(min_key + real_prefix_len, cur_range->min_key, - cur_range->min_length); - /* Compare the found key with min_key. */ - int cmp_res= key_cmp(index_info->key_part, min_key, - real_prefix_len + min_max_arg_len); - my_afree(min_key); + int cmp_res= cmp_min_max_key(cur_range->min_key, cur_range->min_length); /* The key is outside of the range if: the interval is open and the key is equal to the minimum boundry |