diff --git a/include/m_ctype.h b/include/m_ctype.h
index 785fa431385a0a88f4e6c515f7c5b96686114c66..1b6e7bf67391f718dfd6e63be260daaebc1f5eab 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -391,8 +391,10 @@ extern my_bool my_parse_charset_xml(const char *bug, uint len,
 #define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d), 0))
 #define my_like_range(s, a, b, c, d, e, f, g, h, i, j) \
    ((s)->coll->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)))
-#define my_wildcmp(cs,s,se,w,we,e,o,m)	((cs)->coll->wildcmp((cs),(s),(se),(w),(we),(e),(o),(m)))
+#define my_wildcmp(cs,s,se,w,we,e,o,m) ((cs)->coll->wildcmp((cs),(s),(se),(w),(we),(e),(o),(m)))
 #define my_strcasecmp(s, a, b)        ((s)->coll->strcasecmp((s), (a), (b)))
+#define my_charpos(cs, b, e, num)     (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num))
+
 
 #define use_mb(s)                     ((s)->cset->ismbchar != NULL)
 #define my_ismbchar(s, a, b)          ((s)->cset->ismbchar((s), (a), (b)))
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index e06239d3bba82d199d7b72c021a64e325f01d503..a872787fecdfa1a2c42fc4d5b15778b222f010c8 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -25,6 +25,10 @@
 
 #define CHECK_KEYS
 
+#define FIX_LENGTH if (length > char_length) \
+                     char_length= my_charpos(cs, pos, pos+length, char_length); \
+                   set_if_smaller(char_length,length); \
+
 static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record);
 
 	/*
@@ -32,20 +36,18 @@ static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record);
 	** Ret: Length of key
 	*/
 
-#define my_charpos(cs, b, e, num)\
- (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num))
-
 uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
 		  const byte *record, my_off_t filepos)
 {
   byte *pos,*end;
   uchar *start;
   reg1 HA_KEYSEG *keyseg;
+  my_bool is_unique=info->s->keyinfo[keynr].flag & HA_NOSAME;
   DBUG_ENTER("_mi_make_key");
 
   if(info->s->keyinfo[keynr].flag & HA_SPATIAL)
   {
-    /* 
+    /*
       TODO: nulls processing
     */
 #ifdef HAVE_SPATIAL
@@ -61,7 +63,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
     enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
     uint length=keyseg->length;
     uint char_length;
-    CHARSET_INFO *cs;
+    CHARSET_INFO *cs=keyseg->charset;
 
     if (keyseg->null_bit)
     {
@@ -73,15 +75,8 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
       *key++=1;					/* Not NULL */
     }
 
-    char_length= (cs= keyseg->charset) && (cs->mbmaxlen > 1) ?
-                 length / cs->mbmaxlen : 0;
-    
-    if (info->s->keyinfo[keynr].flag & HA_FULLTEXT)
-    {
-      /* Ask Serg to make a better fix */
-      char_length= 0;
-    }
-    
+    char_length= (is_unique && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
+
     pos= (byte*) record+keyseg->start;
     if (keyseg->flag & HA_SPACE_PACK)
     {
@@ -97,14 +92,10 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
 	  pos++;
       }
       length=(uint) (end-pos);
-      if (char_length && length > char_length)
-      {
-        char_length= my_charpos(cs, pos, pos+length, char_length);
-        set_if_smaller(length, char_length);
-      }
-      store_key_length_inc(key,length);
-      memcpy((byte*) key,(byte*) pos,(size_t) length);
-      key+=length;
+      FIX_LENGTH;
+      store_key_length_inc(key,char_length);
+      memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+      key+=char_length;
       continue;
     }
     if (keyseg->flag & HA_VAR_LENGTH)
@@ -112,9 +103,10 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
       uint tmp_length=uint2korr(pos);
       pos+=2;					/* Skip VARCHAR length */
       set_if_smaller(length,tmp_length);
-      store_key_length_inc(key,length);
-      memcpy((byte*) key, pos, length);
-      key+= length;
+      FIX_LENGTH;
+      store_key_length_inc(key,char_length);
+      memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+      key+= char_length;
       continue;
     }
     else if (keyseg->flag & HA_BLOB_PART)
@@ -122,16 +114,10 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
       uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
       memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*));
       set_if_smaller(length,tmp_length);
-#if NOT_YET_BLOB_PART
-      if (char_length && length > char_length)
-      {
-        char_length= my_charpos(cs, pos, pos+length, char_length);
-        set_if_smaller(length, char_length);
-      }
-#endif
-      store_key_length_inc(key,length);
-      memcpy((byte*) key, pos, length);
-      key+= length;
+      FIX_LENGTH;
+      store_key_length_inc(key,char_length);
+      memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+      key+= char_length;
       continue;
     }
     else if (keyseg->flag & HA_SWAP_KEY)
@@ -144,7 +130,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
 	if (isnan(nr))
 	{
 	  /* Replace NAN with zero */
- 	  bzero(key,length);
+	  bzero(key,length);
 	  key+=length;
 	  continue;
 	}
@@ -155,7 +141,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
 	float8get(nr,pos);
 	if (isnan(nr))
 	{
- 	  bzero(key,length);
+	  bzero(key,length);
 	  key+=length;
 	  continue;
 	}
@@ -168,19 +154,10 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
       }
       continue;
     }
-    if (char_length && length > char_length)
-    {
-      char_length= my_charpos(cs, pos, pos+length, char_length);
-      if (char_length < length)
-      {
-        uint diff= length - char_length;
-        memcpy((byte*) key, pos, char_length);
-        cs->cset->fill(cs, key + char_length, diff, ' ');
-        key+= length;
-        continue;
-      }
-    }
-    memcpy((byte*) key, pos, length);
+    FIX_LENGTH;
+    memcpy((byte*) key, pos, char_length);
+    if (length > char_length)
+      bfill(key+char_length, length-char_length, ' ');
     key+= length;
   }
   _mi_dpointer(info,key,filepos);
@@ -208,25 +185,27 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
    RETURN
      length of packed key
 
-     last_use_keyseg 	Store pointer to the keyseg after the last used one
+     last_use_keyseg    Store pointer to the keyseg after the last used one
 */
 
 uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
 		  uint k_length, HA_KEYSEG **last_used_keyseg)
 {
-  uint length;
-  uchar *pos,*end,*start_key=key;
-  reg1 HA_KEYSEG *keyseg;
-  enum ha_base_keytype type;
+  uchar *start_key=key;
+  HA_KEYSEG *keyseg;
+  my_bool is_unique=info->s->keyinfo[keynr].flag & HA_NOSAME;
   DBUG_ENTER("_mi_pack_key");
 
-  start_key=key;
   for (keyseg=info->s->keyinfo[keynr].seg ;
        keyseg->type && (int) k_length > 0;
        old+=keyseg->length, keyseg++)
   {
-    length=min((uint) keyseg->length,(uint) k_length);
-    type=(enum ha_base_keytype) keyseg->type;
+    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
+    uint length=min((uint) keyseg->length,(uint) k_length);
+    uint char_length;
+    uchar *pos;
+    CHARSET_INFO *cs=keyseg->charset;
+
     if (keyseg->null_bit)
     {
       k_length--;
@@ -236,10 +215,11 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
 	continue;					/* Found NULL */
       }
     }
+    char_length= (is_unique && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
     pos=old;
     if (keyseg->flag & HA_SPACE_PACK)
     {
-      end=pos+length;
+      uchar *end=pos+length;
       if (type != HA_KEYTYPE_NUM)
       {
 	while (end > pos && end[-1] == ' ')
@@ -252,9 +232,10 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
       }
       k_length-=length;
       length=(uint) (end-pos);
-      store_key_length_inc(key,length);
-      memcpy((byte*) key,pos,(size_t) length);
-      key+= length;
+      FIX_LENGTH;
+      store_key_length_inc(key,char_length);
+      memcpy((byte*) key,pos,(size_t) char_length);
+      key+= char_length;
       continue;
     }
     else if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART))
@@ -262,11 +243,13 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
       /* Length of key-part used with mi_rkey() always 2 */
       uint tmp_length=uint2korr(pos);
       k_length-= 2+length;
+      pos+=2;
       set_if_smaller(length,tmp_length);	/* Safety */
-      store_key_length_inc(key,length);
+      FIX_LENGTH;
+      store_key_length_inc(key,char_length);
       old+=2;					/* Skip length */
-      memcpy((byte*) key, pos+2,(size_t) length);
-      key+= length;
+      memcpy((byte*) key, pos,(size_t) char_length);
+      key+= char_length;
       continue;
     }
     else if (keyseg->flag & HA_SWAP_KEY)
@@ -279,7 +262,10 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
       }
       continue;
     }
-    memcpy((byte*) key,pos,(size_t) length);
+    FIX_LENGTH;
+    memcpy((byte*) key, pos, char_length);
+    if (length > char_length)
+      bfill(key+char_length, length-char_length, ' ');
     key+= length;
     k_length-=length;
   }
diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index f6ad190b05a42eff98b6f5af368d918dfc1f0b8b..000c0c16d77788c98927d62e31431e6d3c0feba5 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -62,6 +62,10 @@ concat("-",a,"-",b,"-")
 select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
 concat("-",a,"-",b,"-")
 alter table t1 modify b tinytext not null, drop key b, add key (b(100));
+select concat("-",a,"-",b,"-") from t1;
+concat("-",a,"-",b,"-")
+-hello-hello-
+-hello2-hello2-
 select concat("-",a,"-",b,"-") from t1 where b="hello ";
 concat("-",a,"-",b,"-")
 -hello-hello-
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index 9b4621edc4214607f5923317cd7f271e03b0dd2e..967ff47e1ead7d8b7d59194858205e7ee343d8c4 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -76,13 +76,12 @@ CCident varchar(50) DEFAULT '' NOT NULL,
 PRIMARY KEY (name,author,category)
 );
 INSERT INTO t1 VALUES
-('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai\nsalut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
+('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai salut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
 INSERT INTO t1 VALUES
 ('LeNomDeMonSite','Marc',0,'m.barilley@cryo-networks.fr',NULL,NULL,NULL,NULL,'scol://195.242.78.119:Marc.LeNomDeMonSite',NULL,NULL,NULL,950560434,-881563214,NULL,3,0,3,'1','Pub/LeNomDeMonSite/domus_hibere.scs',NULL,'Marq','CC1');
 select * from t1 where name='patnom' and author='patauteur' and category=0;
 name	author	category	email	password	proxy	bitmap	msg	urlscol	urlhttp	timeout	nbcnx	creation	livinguntil	lang	type	subcat	subtype	reg	scs	capacity	userISP	CCident
-patnom	patauteur	0	p.favre@cryo-networks.fr	NULL	NULL	#p2sndnq6ae5g1u6t	essai
-salut	scol://195.242.78.119:patauteur.patnom	NULL	NULL	NULL	950036174	-882087474	NULL	3	0	3	1	Pub/patnom/futur_divers.scs	NULL	pat	CC1
+patnom	patauteur	0	p.favre@cryo-networks.fr	NULL	NULL	#p2sndnq6ae5g1u6t	essai salut	scol://195.242.78.119:patauteur.patnom	NULL	NULL	NULL	950036174	-882087474	NULL	3	0	3	1	Pub/patnom/futur_divers.scs	NULL	pat	CC1
 drop table t1;
 create table t1
 (
@@ -235,3 +234,36 @@ SELECT numeropost FROM t1 WHERE numreponse='1';
 numeropost
 1
 drop table t1;
+create table t1 (c varchar(30) character set utf8, t text character set utf8, unique (c(2)), unique (t(3))) engine=myisam;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c` varchar(30) character set utf8 default NULL,
+  `t` text character set utf8,
+  UNIQUE KEY `c` (`c`(2)),
+  UNIQUE KEY `t` (`t`(3))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert t1 values ('cccc', 'tttt'),
+(0xD0B1212223D0B1D0B1D0B1D0B1D0B1, 0xD0B1D0B1212223D0B1D0B1D0B1D0B1),
+(0xD0B1222123D0B1D0B1D0B1D0B1D0B1, 0xD0B1D0B1222123D0B1D0B1D0B1D0B1);
+insert t1 (c) values ('cc22');
+ERROR 23000: Duplicate entry 'cc22' for key 1
+insert t1 (t) values ('ttt22');
+ERROR 23000: Duplicate entry 'ttt22' for key 2
+insert t1 (c) values (0xD0B1212322D0B1D0B1D0B1D0B1D0B1);
+ERROR 23000: Duplicate entry 'б!#"Ð' for key 1
+insert t1 (t) values (0xD0B1D0B1212322D0B1D0B1D0B1D0B1);
+ERROR 23000: Duplicate entry 'бб!#"б' for key 2
+select c from t1 where c='cccc';
+c
+cccc
+select t from t1 where t='tttt';
+t
+tttt
+select c from t1 where c=0xD0B1212223D0B1D0B1D0B1D0B1D0B1;
+c
+?!"#?????
+select t from t1 where t=0xD0B1D0B1212223D0B1D0B1D0B1D0B1;
+t
+??!"#????
+drop table t1;
diff --git a/mysql-test/t/binary.test b/mysql-test/t/binary.test
index 20a047e0b269213e5f61cfd0105ce28280e248c5..9f63c2ed445999549c8ab3c7175780ab9f64bae6 100644
--- a/mysql-test/t/binary.test
+++ b/mysql-test/t/binary.test
@@ -38,6 +38,7 @@ select concat("-",a,"-",b,"-") from t1 where b="hello ";
 select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
 # blob test
 alter table t1 modify b tinytext not null, drop key b, add key (b(100));
+select concat("-",a,"-",b,"-") from t1;
 select concat("-",a,"-",b,"-") from t1 where b="hello ";
 select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello ";
 drop table t1;
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index d27e5d7d77fc76be6c2971e42373a28f83606c70..ad19c8414ec92ee711cfc14fe96216cfb22b7e71 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -215,10 +215,12 @@ DROP TABLE t1;
 # check null values #1
 #
 
+--disable_warnings
 CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY  (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 INSERT INTO t1 VALUES (1),(2),(3);
 CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY  (b_id), KEY  (b_a), 
                 CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+--enable_warnings
 INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
 SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
 DROP TABLE t2;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 8d399abfec90fe93f8d9bc7a1ac57047606b52b5..ce10f07cf07bcf5b6a68b9f6c10d4eac628afb58 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -97,7 +97,7 @@ CREATE TABLE t1 (
   PRIMARY KEY (name,author,category)
 );
 INSERT INTO t1 VALUES
-('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai\nsalut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
+('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai salut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
 INSERT INTO t1 VALUES
 ('LeNomDeMonSite','Marc',0,'m.barilley@cryo-networks.fr',NULL,NULL,NULL,NULL,'scol://195.242.78.119:Marc.LeNomDeMonSite',NULL,NULL,NULL,950560434,-881563214,NULL,3,0,3,'1','Pub/LeNomDeMonSite/domus_hibere.scs',NULL,'Marq','CC1');
 select * from t1 where name='patnom' and author='patauteur' and category=0;
@@ -228,3 +228,27 @@ EXPLAIN SELECT numeropost FROM t1 WHERE numreponse='1';
 FLUSH TABLES;
 SELECT numeropost FROM t1 WHERE numreponse='1';
 drop table t1;
+
+#
+# UNIQUE prefix keys and multi-byte charsets
+#
+
+create table t1 (c varchar(30) character set utf8, t text character set utf8, unique (c(2)), unique (t(3))) engine=myisam;
+show create table t1;
+insert t1 values ('cccc', 'tttt'),
+  (0xD0B1212223D0B1D0B1D0B1D0B1D0B1, 0xD0B1D0B1212223D0B1D0B1D0B1D0B1),
+  (0xD0B1222123D0B1D0B1D0B1D0B1D0B1, 0xD0B1D0B1222123D0B1D0B1D0B1D0B1);
+--error 1062
+insert t1 (c) values ('cc22');
+--error 1062
+insert t1 (t) values ('ttt22');
+--error 1062
+insert t1 (c) values (0xD0B1212322D0B1D0B1D0B1D0B1D0B1);
+--error 1062
+insert t1 (t) values (0xD0B1D0B1212322D0B1D0B1D0B1D0B1);
+select c from t1 where c='cccc';
+select t from t1 where t='tttt';
+select c from t1 where c=0xD0B1212223D0B1D0B1D0B1D0B1D0B1;
+select t from t1 where t=0xD0B1D0B1212223D0B1D0B1D0B1D0B1;
+drop table t1;
+