From fc1c8ffdadfd14eb51969ecfde43e3204f10f6f8 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 11 Mar 2013 07:44:24 -0700 Subject: The pilot patch for mwl#253. --- sql/field.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'sql/field.cc') diff --git a/sql/field.cc b/sql/field.cc index d4468ba3c5b..e54a3e59795 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1273,6 +1273,20 @@ out_of_range: return 1; } + +double Field_num::middle_point_pos(Field *min, Field *max) +{ + double n, d; + n= val_real() - min->val_real(); + if (n < 0) + return 0.0; + d= max->val_real() - min->val_real(); + if (d <= 0) + return 1.0; + return min(n/d, 1.0); +} + + /** Process decimal library return codes and issue warnings for overflow and truncation. @@ -1344,6 +1358,8 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, comment.length=0; field_index= 0; is_stat_field= FALSE; + cond_selectivity= 1.0; + next_equal_field= NULL; } @@ -6167,6 +6183,46 @@ int Field_str::store(double nr) return store(buff, length, &my_charset_numeric); } +static +inline ulonglong char_prefix_to_ulonglong(uchar *src) +{ + uint sz= sizeof(ulonglong); + for (uint i= 0; i < sz/2; i++) + { + uchar tmp= src[i]; + src[i]= src[sz-1-i]; + src[sz-1-i]= tmp; + } + return uint8korr(src); +} + +double Field_str::middle_point_pos(Field *min, Field *max) +{ + uchar mp_prefix[sizeof(ulonglong)]; + uchar minp_prefix[sizeof(ulonglong)]; + uchar maxp_prefix[sizeof(ulonglong)]; + ulonglong mp, minp, maxp; + my_strnxfrm(charset(), mp_prefix, sizeof(mp), + ptr + length_size(), sizeof(mp) * charset()->mbmaxlen); + my_strnxfrm(charset(), minp_prefix, sizeof(minp), + min->ptr + length_size(), + sizeof(minp) * charset()->mbmaxlen); + my_strnxfrm(charset(), maxp_prefix, sizeof(maxp), + max->ptr + length_size(), + sizeof(maxp) * charset()->mbmaxlen); + mp= char_prefix_to_ulonglong(mp_prefix); + minp= char_prefix_to_ulonglong(minp_prefix); + maxp= char_prefix_to_ulonglong(maxp_prefix); + double n, d; + n= mp - minp; + if (n < 0) + return 0.0; + d= maxp - minp; + if (d <= 0) + return 1.0; + return min(n/d, 1.0); +} + uint Field::is_equal(Create_field *new_field) { -- cgit v1.2.1 From 1009832c13380365c03f77fcabd0fda470b73390 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 25 Mar 2013 23:48:29 -0700 Subject: Added histogams for table columns. --- sql/field.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'sql/field.cc') diff --git a/sql/field.cc b/sql/field.cc index e54a3e59795..afa12f84178 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8420,6 +8420,19 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value) } +double Field_bit::middle_point_pos(Field *min, Field *max) +{ + double n, d; + n= val_real() - min->val_real(); + if (n < 0) + return 0.0; + d= max->val_real() - min->val_real(); + if (d <= 0) + return 1.0; + return min(n/d, 1.0); +} + + /* Compare two bit fields using pointers within the record. SYNOPSIS -- cgit v1.2.1 From b2d0a33ea04a5eb20124667ea277fe78eb981a90 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 6 Apr 2013 00:51:41 -0700 Subject: Fixed bug mdev-4373: Valgrind complained on usage of uninitialized memory. --- sql/field.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'sql/field.cc') diff --git a/sql/field.cc b/sql/field.cc index 51fa24fc9ad..7eba901d46b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6202,14 +6202,16 @@ double Field_str::middle_point_pos(Field *min, Field *max) uchar minp_prefix[sizeof(ulonglong)]; uchar maxp_prefix[sizeof(ulonglong)]; ulonglong mp, minp, maxp; + uint dsz= min(field_length, sizeof(ulonglong) * charset()->mbmaxlen); + memset(mp_prefix, 0, sizeof(ulonglong)); + memset(minp_prefix, 0, sizeof(ulonglong)); + memset(maxp_prefix, 0, sizeof(ulonglong)); my_strnxfrm(charset(), mp_prefix, sizeof(mp), - ptr + length_size(), sizeof(mp) * charset()->mbmaxlen); + ptr + length_size(), dsz); my_strnxfrm(charset(), minp_prefix, sizeof(minp), - min->ptr + length_size(), - sizeof(minp) * charset()->mbmaxlen); + min->ptr + length_size(), dsz); my_strnxfrm(charset(), maxp_prefix, sizeof(maxp), - max->ptr + length_size(), - sizeof(maxp) * charset()->mbmaxlen); + max->ptr + length_size(), dsz); mp= char_prefix_to_ulonglong(mp_prefix); minp= char_prefix_to_ulonglong(minp_prefix); maxp= char_prefix_to_ulonglong(maxp_prefix); -- cgit v1.2.1 From 549ada35b0ae2f5a5728243cd6be0fe8f873c792 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 9 Apr 2013 10:26:39 -0700 Subject: Fixed valgrind complain on usage of uninitialized data. --- sql/field.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'sql/field.cc') diff --git a/sql/field.cc b/sql/field.cc index 7eba901d46b..e543689bef9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6202,16 +6202,15 @@ double Field_str::middle_point_pos(Field *min, Field *max) uchar minp_prefix[sizeof(ulonglong)]; uchar maxp_prefix[sizeof(ulonglong)]; ulonglong mp, minp, maxp; - uint dsz= min(field_length, sizeof(ulonglong) * charset()->mbmaxlen); - memset(mp_prefix, 0, sizeof(ulonglong)); - memset(minp_prefix, 0, sizeof(ulonglong)); - memset(maxp_prefix, 0, sizeof(ulonglong)); my_strnxfrm(charset(), mp_prefix, sizeof(mp), - ptr + length_size(), dsz); + ptr + length_size(), + data_length()); my_strnxfrm(charset(), minp_prefix, sizeof(minp), - min->ptr + length_size(), dsz); + min->ptr + length_size(), + min->data_length()); my_strnxfrm(charset(), maxp_prefix, sizeof(maxp), - max->ptr + length_size(), dsz); + max->ptr + length_size(), + max->data_length()); mp= char_prefix_to_ulonglong(mp_prefix); minp= char_prefix_to_ulonglong(minp_prefix); maxp= char_prefix_to_ulonglong(maxp_prefix); -- cgit v1.2.1 From b12b3cae85effe89f91e816f86bd15bc4039779b Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 15 Apr 2013 22:43:07 -0700 Subject: Added comments. Renamed the virtual method middle_point_pos for the class Field to pos_in_interval. --- sql/field.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) (limited to 'sql/field.cc') diff --git a/sql/field.cc b/sql/field.cc index 103d868d834..e491afd9f25 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1274,7 +1274,24 @@ out_of_range: } -double Field_num::middle_point_pos(Field *min, Field *max) +/** + @brief + Determine the relative position of the field value in a numeric interval + + @details + The function returns a double number between 0.0 and 1.0 as the relative + position of the value of the this field in the numeric interval of [min,max]. + If the value is not in the interval the the function returns 0.0 when + the value is less than min, and, 1.0 when the value is greater than max. + + @param min value of the left end of the interval + @param max value of the right end of the interval + + @return + relative position of the field value in the numeric interval [min,max] +*/ + +double Field_num::pos_in_interval(Field *min, Field *max) { double n, d; n= val_real() - min->val_real(); @@ -6196,7 +6213,39 @@ inline ulonglong char_prefix_to_ulonglong(uchar *src) return uint8korr(src); } -double Field_str::middle_point_pos(Field *min, Field *max) +/** + @brief + Determine the relative position of the field value in a string interval + + @details + The function returns a double number between 0.0 and 1.0 as the relative + position of the value of the this field in the string interval of [min,max]. + If the value is not in the interval the the function returns 0.0 when + the value is less than min, and, 1.0 when the value is greater than max. + + @note + To calculate the relative position of the string value v in the interval + [min, max] the function first converts the beginning of these three + strings v, min, max into the strings that are used for byte comparison. + For each string not more sizeof(ulonglong) first bytes are taken + from the result of conversion. Then these bytes are interpreted as the + big-endian representation of an ulonglong integer. The values of these + integer numbers obtained for the strings v, min, max are used to calculate + the position of v in [min,max] in the same way is it's done for numeric + fields (see Field_num::pos_in_interval). + + @todo + Improve the procedure for the case when min and max have the same + beginning + + @param min value of the left end of the interval + @param max value of the right end of the interval + + @return + relative position of the field value in the string interval [min,max] +*/ + +double Field_str::pos_in_interval(Field *min, Field *max) { uchar mp_prefix[sizeof(ulonglong)]; uchar minp_prefix[sizeof(ulonglong)]; @@ -8435,7 +8484,24 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value) } -double Field_bit::middle_point_pos(Field *min, Field *max) +/** + @brief + Determine the relative position of the field value in a bit interval + + @details + The function returns a double number between 0.0 and 1.0 as the relative + position of the value of the this field in the bit interval of [min,max]. + If the value is not in the interval the the function returns 0.0 when + the value is less than min, and, 1.0 when the value is greater than max. + + @param min value of the left end of the interval + @param max value of the right end of the interval + + @return + relative position of the field value in the bit interval [min,max] +*/ + +double Field_bit::pos_in_interval(Field *min, Field *max) { double n, d; n= val_real() - min->val_real(); -- cgit v1.2.1