summaryrefslogtreecommitdiff
path: root/sql/opt_histogram_json.cc
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2021-10-18 16:31:18 +0300
committerSergei Petrunia <psergey@askmonty.org>2022-01-19 18:10:11 +0300
commitf3f78bed8530e1e858d5ed87054f2ac672760824 (patch)
tree84303fb727fe41a7c961e9a415de987a93534944 /sql/opt_histogram_json.cc
parent27539cd2c8b4f631cce78a4bb6f0eabe8eb1141c (diff)
downloadmariadb-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.cc25
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
{