Commit b50d4476 authored by unknown's avatar unknown
Browse files

Fixed unique prefix key bug for multibyte character sets (BUG #4521) for

InnoDB. This fixes also a second part of the same problem with prefix keys
on a multibyte string column for InnoDB.


innobase/rem/rem0cmp.c:
  Fixed unique prefix key or prefix key using multibyte character set bugs for
  InnoDB (BUG #4521).
  
  The unique key with a prefix of N appears index 3*N bytes of the column not N
  characters. If you had two records which have the same first N characters 
  but differ in the first 3*N bytes, then you couldn't select the records using 
  an equality test.
parent 094c9f32
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@ Created 7/1/1994 Heikki Tuuri

#include "srv0srv.h"

#include <m_ctype.h>
#include <my_sys.h>

/*		ALPHABETICAL ORDER
		==================
		
@@ -453,6 +456,8 @@ cmp_dtuple_rec_with_match(
					in current field */
	int		ret = 3333;	/* return value */
	
	CHARSET_INFO*   charset;        /* charset used in the field */

	ut_ad(dtuple && rec && matched_fields && matched_bytes);
	ut_ad(dtuple_check_typed(dtuple));

@@ -541,6 +546,32 @@ cmp_dtuple_rec_with_match(
			&& dtype_get_charset_coll(cur_type->prtype) !=
				data_mysql_latin1_swedish_charset_coll)) {

		  	/* If character set is not latin1_swedish
			we have to devide character length by the
			maximum bytes needed for that character
			set. For example if we have unique prefix
			index for 1 utf8 character then we have
			actually 3 bytes allocated in the index.
			Therefore, we have to divide that with
			maximum bytes needed for utf8 character i.e.
			3 byges.*/

                        if ( dtuple_f_len > 0) {
			  charset = get_charset(
				dtype_get_charset_coll(cur_type->prtype), 
				MYF(MY_WME));

			  ut_ad(charset);
			  ut_ad(charset->mbmaxlen);

			  dtuple_f_len = dtuple_f_len / charset->mbmaxlen;

                          if ( dtuple_f_len == 0)
			    dtuple_f_len = 1;

			  rec_f_len = dtuple_f_len;
			} 

			ret = cmp_whole_field(cur_type,
				dfield_get_data(dtuple_field), dtuple_f_len,
				rec_b_ptr, rec_f_len);