Skip to content

Commit f0c5092

Browse files
committed
Merge branch 'mysql-8.0' into mysql-8.4
Change-Id: Ic28746e0a6b126beb4de5cac2ba0e2d0b7edb8f2
2 parents faaf0fd + bbcf89b commit f0c5092

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed

storage/ndb/plugin/ha_ndbcluster_cond.cc

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,16 @@ class Ndb_expect_stack {
325325
static const uint MAX_EXPECT_ITEMS = Item::VALUES_COLUMN_ITEM + 1;
326326
static const uint MAX_EXPECT_FIELD_TYPES = MYSQL_TYPE_GEOMETRY + 1;
327327
static const uint MAX_EXPECT_FIELD_RESULTS = DECIMAL_RESULT + 1;
328+
static constexpr Uint32 NO_LENGTH = UINT32_MAX;
328329

329330
public:
330331
Ndb_expect_stack()
331332
: expect_tables(),
332333
other_field(nullptr),
333334
collation(nullptr),
334-
length(0),
335-
max_length(0),
335+
length(NO_LENGTH),
336+
min_length(NO_LENGTH),
337+
max_length(NO_LENGTH),
336338
next(nullptr) {
337339
// Allocate type checking bitmaps using fixed size buffers
338340
// since max size is known at compile time
@@ -442,12 +444,19 @@ class Ndb_expect_stack {
442444
return matching;
443445
}
444446
void expect_length(Uint32 len) { length = len; }
447+
void expect_min_length(Uint32 min) { min_length = min; }
445448
void expect_max_length(Uint32 max) { max_length = max; }
446449
bool expecting_length(Uint32 len) {
447-
return max_length == 0 || len <= max_length;
450+
return (min_length == NO_LENGTH || min_length <= len) &&
451+
(max_length == NO_LENGTH || len <= max_length);
448452
}
449-
bool expecting_max_length(Uint32 max) { return max >= length; }
450-
void expect_no_length() { length = max_length = 0; }
453+
bool expecting_max_length(Uint32 max) {
454+
return (length == NO_LENGTH || max >= length);
455+
}
456+
bool expecting_min_length(Uint32 min) {
457+
return (length == NO_LENGTH || min <= length);
458+
}
459+
void expect_no_length() { length = min_length = max_length = NO_LENGTH; }
451460

452461
private:
453462
Ndb_bitmap_buf<MAX_EXPECT_ITEMS> m_expect_buf;
@@ -460,6 +469,7 @@ class Ndb_expect_stack {
460469
const Field *other_field;
461470
const CHARSET_INFO *collation;
462471
Uint32 length;
472+
Uint32 min_length;
463473
Uint32 max_length;
464474
Ndb_expect_stack *next;
465475
};
@@ -563,6 +573,9 @@ class Ndb_cond_traverse_context {
563573
inline void expect_length(Uint32 length) {
564574
expect_stack.expect_length(length);
565575
}
576+
inline void expect_min_length(Uint32 min) {
577+
expect_stack.expect_min_length(min);
578+
}
566579
inline void expect_max_length(Uint32 max) {
567580
expect_stack.expect_max_length(max);
568581
}
@@ -572,6 +585,9 @@ class Ndb_cond_traverse_context {
572585
inline bool expecting_max_length(Uint32 max) {
573586
return expect_stack.expecting_max_length(max);
574587
}
588+
inline bool expecting_min_length(Uint32 min) {
589+
return expect_stack.expecting_min_length(min);
590+
}
575591
inline void expect_no_length() { expect_stack.expect_no_length(); }
576592

577593
TABLE *const table;
@@ -870,19 +886,27 @@ static void ndb_serialize_cond(const Item *item, void *arg) {
870886
context->supported = false;
871887
break;
872888

873-
case STRING_RESULT:
889+
case STRING_RESULT: {
874890
DBUG_PRINT("info", ("STRING 'VALUE' expression: '%s'",
875891
str.c_ptr_safe()));
876-
// Check that we do support pushing the item value length
892+
size_t item_length = item->max_length;
893+
// For BINARY value the actual value length should be used.
894+
// If the BINARY value comes from a CHAR value casted to BINARY
895+
// it will have max_length as a multiple of connection charset
896+
// max character size.
897+
if (item->collation.collation == &my_charset_bin) {
898+
String buf, *val = const_cast<Item *>(item)->val_str(&buf);
899+
if (val) item_length = val->length();
900+
}
877901
if (context->expecting(Item::STRING_ITEM) &&
878-
context->expecting_length(item->max_length)) {
902+
context->expecting_length(item_length)) {
879903
ndb_item = new (*THR_MALLOC) Ndb_value(item);
880904
if (context->expecting_no_field_result()) {
881905
// We have not seen the field argument yet
882906
context->expect_only_field_from_table(this_table);
883907
context->expect_field_result(STRING_RESULT);
884908
context->expect_collation(item->collation.collation);
885-
context->expect_length(item->max_length);
909+
context->expect_length(item_length);
886910
} else {
887911
// Expect another logical expression
888912
context->expect_only(Item::FUNC_ITEM);
@@ -901,7 +925,7 @@ static void ndb_serialize_cond(const Item *item, void *arg) {
901925
} else
902926
context->supported = false;
903927
break;
904-
928+
}
905929
default:
906930
assert(false);
907931
context->supported = false;
@@ -1010,7 +1034,9 @@ static void ndb_serialize_cond(const Item *item, void *arg) {
10101034
// type.
10111035
if (field->result_type() == STRING_RESULT &&
10121036
!is_supported_temporal_type(type)) {
1013-
if (!context->expecting_max_length(field->field_length)) {
1037+
if (!context->expecting_max_length(field->field_length) ||
1038+
(field->binary() &&
1039+
!context->expecting_min_length(field->field_length))) {
10141040
DBUG_PRINT("info", ("Found non-matching string length %s",
10151041
field->field_name));
10161042
context->supported = false;
@@ -1046,6 +1072,13 @@ static void ndb_serialize_cond(const Item *item, void *arg) {
10461072
context->expect(Item::HEX_BIN_ITEM);
10471073
context->expect_collation(
10481074
field_item->collation.collation);
1075+
/*
1076+
* For BINARY columns value length must be exactly the
1077+
* same for equality like conditions, since value will be
1078+
* zero padded when compared in NdbSqlUtil::cmpBinary.
1079+
*/
1080+
if (type == MYSQL_TYPE_STRING && field->binary())
1081+
context->expect_min_length(field->field_length);
10491082
context->expect_max_length(field->field_length);
10501083
break;
10511084
case REAL_RESULT:

0 commit comments

Comments
 (0)