diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2021-10-18 16:31:18 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2022-01-19 18:10:11 +0300 |
commit | f3f78bed8530e1e858d5ed87054f2ac672760824 (patch) | |
tree | 84303fb727fe41a7c961e9a415de987a93534944 /sql/opt_histogram_json.cc | |
parent | 27539cd2c8b4f631cce78a4bb6f0eabe8eb1141c (diff) | |
download | mariadb-git-f3f78bed8530e1e858d5ed87054f2ac672760824.tar.gz |
MDEV-26750: Estimation for filtered rows is far off with JSON_HB histogram
Fix a bug in position_in_interval(). Do not overwrite one interval endpoint
with another.
Diffstat (limited to 'sql/opt_histogram_json.cc')
-rw-r--r-- | sql/opt_histogram_json.cc | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/sql/opt_histogram_json.cc b/sql/opt_histogram_json.cc index 944c5ffb353..1793aa7df0d 100644 --- a/sql/opt_histogram_json.cc +++ b/sql/opt_histogram_json.cc @@ -569,21 +569,34 @@ double position_in_interval(Field *field, const uchar *key, uint key_len, if (field->pos_through_val_str()) { StringBuffer<64> buf1, buf2, buf3; - String empty_buf1, empty_buf2, empty_buf3; store_key_image_to_rec_no_null(field, left.data(), left.size()); - String *min_str= field->val_str(&buf1, &empty_buf1); + String *min_str= field->val_str(&buf1); + /* + Make sure we've saved a copy of the data, not a pointer into the + field->ptr. We will overwrite the contents of field->ptr with the next + store_key_image_to_rec_no_null call + */ + if (&buf1 != min_str) + buf1.copy(*min_str); + else + buf1.copy(); store_key_image_to_rec_no_null(field, right.data(), right.size()); - String *max_str= field->val_str(&buf2, &empty_buf2); + String *max_str= field->val_str(&buf2); + /* Same as above */ + if (&buf2 != max_str) + buf2.copy(*max_str); + else + buf2.copy(); store_key_image_to_rec_no_null(field, (const char*)key, key_len); - String *midp_str= field->val_str(&buf3, &empty_buf3); + String *midp_str= field->val_str(&buf3); res= pos_in_interval_for_string(field->charset(), (const uchar*)midp_str->ptr(), midp_str->length(), - (const uchar*)min_str->ptr(), min_str->length(), - (const uchar*)max_str->ptr(), max_str->length()); + (const uchar*)buf1.ptr(), buf1.length(), + (const uchar*)buf2.ptr(), buf2.length()); } else { |