@@ -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