diff -rpu storage/innobase/data/data0type.c storage/innobase/data/data0type.c
--- storage/innobase/data/data0type.c	2008-09-11 11:36:30.000000000 +0300
+++ storage/innobase/data/data0type.c	2008-10-28 10:09:43.000000000 +0200
@@ -51,9 +51,7 @@ dtype_get_at_most_n_mbchars(
 					/* out: length of the prefix,
 					in bytes */
 	ulint		prtype,		/* in: precise type */
-	ulint		mbminlen,	/* in: minimum length of a
-					multi-byte character */
-	ulint		mbmaxlen,	/* in: maximum length of a
+	ulint		mbminmaxlen,	/* in: minimum and maximum length of a
 					multi-byte character */
 	ulint		prefix_len,	/* in: length of the requested
 					prefix, in characters, multiplied by
@@ -63,6 +61,9 @@ dtype_get_at_most_n_mbchars(
 					length is being determined */
 {
 #ifndef UNIV_HOTBACKUP
+	ulint	mbminlen = mbminmaxlen % DATA_MBMAX;
+	ulint	mbmaxlen = mbminmaxlen / DATA_MBMAX;
+
 	ut_a(data_len != UNIV_SQL_NULL);
 	ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
 
@@ -197,7 +198,7 @@ dtype_validate(
 		ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
 	}
 
-	ut_a(type->mbminlen <= type->mbmaxlen);
+	ut_a(dtype_get_mbminlen(type) <= dtype_get_mbmaxlen(type));
 
 	return(TRUE);
 }
diff -rpu storage/innobase/dict/dict0mem.c storage/innobase/dict/dict0mem.c
--- storage/innobase/dict/dict0mem.c	2008-09-11 11:36:30.000000000 +0300
+++ storage/innobase/dict/dict0mem.c	2008-10-28 09:35:58.000000000 +0200
@@ -217,9 +217,7 @@ dict_mem_table_add_col(
 	col->len = (unsigned int) len;
 
 	dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
-
-	col->mbminlen = (unsigned int) mbminlen;
-	col->mbmaxlen = (unsigned int) mbmaxlen;
+	dict_col_set_mbminmaxlen(col, mbminlen, mbmaxlen);
 }
 
 /**************************************************************************
diff -rpu storage/innobase/handler/ha_innodb.cc storage/innobase/handler/ha_innodb.cc
--- storage/innobase/handler/ha_innodb.cc	2008-10-24 11:10:56.000000000 +0300
+++ storage/innobase/handler/ha_innodb.cc	2008-10-28 09:45:19.000000000 +0200
@@ -3170,6 +3170,7 @@ build_template(
 	  'fields'.
         */
 	for (i = 0; i < n_fields; i++) {
+		const dict_col_t* col = &index->table->cols[i];
 		templ = prebuilt->mysql_template + n_requested_fields;
 		field = table->field[i];
 
@@ -3224,7 +3225,7 @@ include_field:
 
 		if (index == clust_index) {
 			templ->rec_field_no = dict_col_get_clust_pos_noninline(
-				&index->table->cols[i], index);
+				col, index);
 		} else {
 			templ->rec_field_no = dict_index_get_nth_col_pos(
 								index, i);
@@ -3253,7 +3254,7 @@ include_field:
 			mysql_prefix_len = templ->mysql_col_offset
 				+ templ->mysql_col_len;
 		}
-		templ->type = index->table->cols[i].mtype;
+		templ->type = col->mtype;
 		templ->mysql_type = (ulint)field->type();
 
 		if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
@@ -3262,11 +3263,10 @@ include_field:
 		}
 
 		templ->charset = dtype_get_charset_coll_noninline(
-				index->table->cols[i].prtype);
-		templ->mbminlen = index->table->cols[i].mbminlen;
-		templ->mbmaxlen = index->table->cols[i].mbmaxlen;
-		templ->is_unsigned = index->table->cols[i].prtype
-							& DATA_UNSIGNED;
+				col->prtype);
+		templ->mbminlen = dict_col_get_mbminlen(col);
+		templ->mbmaxlen = dict_col_get_mbmaxlen(col);
+		templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 		if (templ->type == DATA_BLOB) {
 			prebuilt->templ_contains_blob = TRUE;
 		}
diff -rpu storage/innobase/include/data0type.h storage/innobase/include/data0type.h
--- storage/innobase/include/data0type.h	2008-09-11 11:36:31.000000000 +0300
+++ storage/innobase/include/data0type.h	2008-10-28 10:06:49.000000000 +0200
@@ -54,6 +54,7 @@ binary strings */
 				can also be latin1_swedish_ci */
 #define DATA_MTYPE_MAX	63	/* dtype_store_for_order_and_null_size()
 				requires the values are <= 63 */
+
 /*-------------------------------------------*/
 /* The 'PRECISE TYPE' of a column */
 /*
@@ -149,6 +150,9 @@ SQL null*/
 store the charset-collation number; one byte is left unused, though */
 #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE	6
 
+/* Maximum multi-byte character length in bytes, plus 1 */
+#define DATA_MBMAX	5
+
 /*************************************************************************
 Gets the MySQL type code from a dtype. */
 UNIV_INLINE
@@ -169,9 +173,7 @@ dtype_get_at_most_n_mbchars(
 					/* out: length of the prefix,
 					in bytes */
 	ulint		prtype,		/* in: precise type */
-	ulint		mbminlen,	/* in: minimum length of a
-					multi-byte character */
-	ulint		mbmaxlen,	/* in: maximum length of a
+	ulint		mbminmaxlen,	/* in: minimum and maximum length of a
 					multi-byte character */
 	ulint		prefix_len,	/* in: length of the requested
 					prefix, in characters, multiplied by
@@ -305,6 +307,19 @@ dtype_get_mbmaxlen(
 				or 0 if this is not a character type */
 	const dtype_t*	type);	/* in: type */
 /*************************************************************************
+Sets the minimum and maximum length of a character, in bytes. */
+UNIV_INLINE
+void
+dtype_set_mbminmaxlen(
+/*==================*/
+	dtype_t*	type,		/* in/out: type */
+	ulint		mbminlen,	/* in: minimum length of a char,
+					in bytes, or 0 if this is not
+					a character type */
+	ulint		mbmaxlen);	/* in: maximum length of a char,
+					in bytes, or 0 if this is not
+					a character type */
+/*************************************************************************
 Gets the padding character code for the type. */
 UNIV_INLINE
 ulint
@@ -437,10 +452,8 @@ struct dtype_struct{
 					the string, MySQL uses 1 or 2
 					bytes to store the string length) */
 
-	unsigned	mbminlen:2;	/* minimum length of a
-					character, in bytes */
-	unsigned	mbmaxlen:3;	/* maximum length of a
-					character, in bytes */
+	unsigned	mbminmaxlen:5;	/* minimum and maximum length of a
+					character */
 };
 
 #ifndef UNIV_NONINL
diff -rpu storage/innobase/include/data0type.ic storage/innobase/include/data0type.ic
--- storage/innobase/include/data0type.ic	2008-09-11 11:36:31.000000000 +0300
+++ storage/innobase/include/data0type.ic	2008-10-28 10:02:30.000000000 +0200
@@ -65,8 +65,8 @@ dtype_get_mblen(
 		innobase_get_cset_width(dtype_get_charset_coll(prtype),
 					mbminlen, mbmaxlen);
 		ut_ad(*mbminlen <= *mbmaxlen);
-		ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
-		ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
+		ut_ad(*mbminlen < DATA_MBMAX);
+		ut_ad(*mbmaxlen < DATA_MBMAX);
 #else /* !UNIV_HOTBACKUP */
 		ut_a(mtype <= DATA_BINARY);
 		*mbminlen = *mbmaxlen = 1;
@@ -77,6 +77,27 @@ dtype_get_mblen(
 }
 
 /*************************************************************************
+Sets the minimum and maximum length of a character, in bytes. */
+UNIV_INLINE
+void
+dtype_set_mbminmaxlen(
+/*==================*/
+	dtype_t*	type,		/* in/out: type */
+	ulint		mbminlen,	/* in: minimum length of a char,
+					in bytes, or 0 if this is not
+					a character type */
+	ulint		mbmaxlen)	/* in: maximum length of a char,
+					in bytes, or 0 if this is not
+					a character type */
+{
+	ut_ad(mbminlen < DATA_MBMAX);
+	ut_ad(mbmaxlen < DATA_MBMAX);
+	ut_ad(mbminlen <= mbmaxlen);
+
+	type->mbminmaxlen = mbmaxlen * DATA_MBMAX + mbminlen;
+}
+
+/*************************************************************************
 Compute the mbminlen and mbmaxlen members of a data type structure. */
 UNIV_INLINE
 void
@@ -88,8 +109,7 @@ dtype_set_mblen(
 	ulint	mbmaxlen;
 
 	dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
-	type->mbminlen = mbminlen;
-	type->mbmaxlen = mbmaxlen;
+	dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen);
 
 	ut_ad(dtype_validate(type));
 }
@@ -179,7 +199,7 @@ dtype_get_mbminlen(
 	const dtype_t*	type)	/* in: type */
 {
 	ut_ad(type);
-	return(type->mbminlen);
+	return(UNIV_EXPECT(type->mbminmaxlen % DATA_MBMAX, 1));
 }
 /*************************************************************************
 Gets the maximum length of a character, in bytes. */
@@ -192,7 +212,7 @@ dtype_get_mbmaxlen(
 	const dtype_t*	type)	/* in: type */
 {
 	ut_ad(type);
-	return(type->mbmaxlen);
+	return(type->mbminmaxlen / DATA_MBMAX);
 }
 
 /*************************************************************************
@@ -558,5 +578,6 @@ dtype_get_sql_null_size(
 	const dtype_t*	type)	/* in: type */
 {
 	return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
-					type->mbminlen, type->mbmaxlen) > 0);
+					dtype_get_mbminlen(type),
+					dtype_get_mbmaxlen(type)) > 0);
 }
diff -rpu storage/innobase/include/dict0dict.h storage/innobase/include/dict0dict.h
--- storage/innobase/include/dict0dict.h	2008-09-11 11:36:31.000000000 +0300
+++ storage/innobase/include/dict0dict.h	2008-10-28 10:04:52.000000000 +0200
@@ -77,6 +77,31 @@ void
 dict_load_space_id_list(void);
 /*=========================*/
 /*************************************************************************
+Gets the minimum number of bytes per character. */
+UNIV_INLINE
+ulint
+dict_col_get_mbminlen(
+/*==================*/
+					/* out: minimum multi-byte char size */
+	const dict_col_t*	col);	/* in: column */
+/*************************************************************************
+Gets the maximum number of bytes per character. */
+UNIV_INLINE
+ulint
+dict_col_get_mbmaxlen(
+/*==================*/
+					/* out: maximum multi-byte char size */
+	const dict_col_t*	col);	/* in: column */
+/*************************************************************************
+Sets the minimum and maximum number of bytes per character. */
+UNIV_INLINE
+void
+dict_col_set_mbminmaxlen(
+/*=====================*/
+	dict_col_t*	col,		/* in/out: column */
+	ulint		mbminlen,	/* in: minimum multi-byte char size */
+	ulint		mbmaxlen);	/* in: minimum multi-byte char size */
+/*************************************************************************
 Gets the column data type. */
 UNIV_INLINE
 void
diff -rpu storage/innobase/include/dict0dict.ic storage/innobase/include/dict0dict.ic
--- storage/innobase/include/dict0dict.ic	2008-09-11 11:36:31.000000000 +0300
+++ storage/innobase/include/dict0dict.ic	2008-10-28 10:04:41.000000000 +0200
@@ -13,6 +13,44 @@ Created 1/8/1996 Heikki Tuuri
 #include "data0type.h"
 
 /*************************************************************************
+Gets the minimum number of bytes per character. */
+UNIV_INLINE
+ulint
+dict_col_get_mbminlen(
+/*==================*/
+					/* out: minimum multi-byte char size */
+	const dict_col_t*	col)	/* in: column */
+{
+	return(UNIV_EXPECT(col->mbminmaxlen % DATA_MBMAX, 1));
+}
+/*************************************************************************
+Gets the maximum number of bytes per character. */
+UNIV_INLINE
+ulint
+dict_col_get_mbmaxlen(
+/*==================*/
+					/* out: maximum multi-byte char size */
+	const dict_col_t*	col)	/* in: column */
+{
+	return(col->mbminmaxlen / DATA_MBMAX);
+}
+/*************************************************************************
+Sets the minimum and maximum number of bytes per character. */
+UNIV_INLINE
+void
+dict_col_set_mbminmaxlen(
+/*=====================*/
+	dict_col_t*	col,		/* in/out: column */
+	ulint		mbminlen,	/* in: minimum multi-byte char size */
+	ulint		mbmaxlen)	/* in: minimum multi-byte char size */
+{
+	ut_ad(mbminlen < DATA_MBMAX);
+	ut_ad(mbmaxlen < DATA_MBMAX);
+	ut_ad(mbminlen <= mbmaxlen);
+
+	col->mbminmaxlen = mbmaxlen * DATA_MBMAX + mbminlen;
+}
+/*************************************************************************
 Gets the column data type. */
 UNIV_INLINE
 void
@@ -26,8 +64,7 @@ dict_col_copy_type(
 	type->mtype = col->mtype;
 	type->prtype = col->prtype;
 	type->len = col->len;
-	type->mbminlen = col->mbminlen;
-	type->mbmaxlen = col->mbmaxlen;
+	type->mbminmaxlen = col->mbminmaxlen;
 }
 
 #ifdef UNIV_DEBUG
@@ -47,8 +84,7 @@ dict_col_type_assert_equal(
 	ut_ad(col->mtype == type->mtype);
 	ut_ad(col->prtype == type->prtype);
 	ut_ad(col->len == type->len);
-	ut_ad(col->mbminlen == type->mbminlen);
-	ut_ad(col->mbmaxlen == type->mbmaxlen);
+	ut_ad(col->mbminmaxlen == type->mbminmaxlen);
 
 	return(TRUE);
 }
@@ -64,7 +100,8 @@ dict_col_get_min_size(
 	const dict_col_t*	col)	/* in: column */
 {
 	return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
-				      col->mbminlen, col->mbmaxlen));
+				      dict_col_get_mbminlen(col),
+				      dict_col_get_mbmaxlen(col)));
 }
 /***************************************************************************
 Returns the maximum size of the column. */
@@ -87,7 +124,8 @@ dict_col_get_fixed_size(
 	const dict_col_t*	col)	/* in: column */
 {
 	return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
-					col->mbminlen, col->mbmaxlen));
+					dict_col_get_mbminlen(col),
+					dict_col_get_mbmaxlen(col)));
 }
 /***************************************************************************
 Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
diff -rpu storage/innobase/include/dict0mem.h storage/innobase/include/dict0mem.h
--- storage/innobase/include/dict0mem.h	2008-09-11 11:36:31.000000000 +0300
+++ storage/innobase/include/dict0mem.h	2008-10-28 09:53:07.000000000 +0200
@@ -145,10 +145,8 @@ struct dict_col_struct{
 					the string, MySQL uses 1 or 2
 					bytes to store the string length) */
 
-	unsigned	mbminlen:2;	/* minimum length of a
-					character, in bytes */
-	unsigned	mbmaxlen:3;	/* maximum length of a
-					character, in bytes */
+	unsigned	mbminmaxlen:5;	/* minimum and maximum length of a
+					character */
 	/*----------------------*/
 	/* End of definitions copied from dtype_t */
 
diff -rpu storage/innobase/row/row0ins.c storage/innobase/row/row0ins.c
--- storage/innobase/row/row0ins.c	2008-09-11 11:36:32.000000000 +0300
+++ storage/innobase/row/row0ins.c	2008-10-28 10:11:32.000000000 +0200
@@ -499,8 +499,7 @@ row_ins_cascade_calc_update_vec(
 
 				if (ufield->new_val.len != UNIV_SQL_NULL
 				    && dtype_get_at_most_n_mbchars(
-					col->prtype,
-					col->mbminlen, col->mbmaxlen,
+					col->prtype, col->mbminmaxlen,
 					col->len,
 					ufield->new_val.len,
 					ufield->new_val.data)
@@ -535,7 +534,7 @@ row_ins_cascade_calc_update_vec(
 						  parent_ufield->new_val.data,
 						  parent_ufield->new_val.len);
 
-					switch (UNIV_EXPECT(col->mbminlen,1)) {
+					switch (dict_col_get_mbminlen(col)) {
 					default:
 						ut_error;
 					case 1:
@@ -2226,7 +2225,7 @@ row_ins_index_entry_set_vals(
 				= dict_field_get_col(ind_field);
 
 			field->len = dtype_get_at_most_n_mbchars(
-				col->prtype, col->mbminlen, col->mbmaxlen,
+				col->prtype, col->mbminmaxlen,
 				ind_field->prefix_len,
 				row_field->len, row_field->data);
 		} else {
diff -rpu storage/innobase/row/row0row.c storage/innobase/row/row0row.c
--- storage/innobase/row/row0row.c	2008-09-11 11:36:33.000000000 +0300
+++ storage/innobase/row/row0row.c	2008-10-28 10:12:18.000000000 +0200
@@ -146,7 +146,7 @@ row_build_index_entry(
 		    && dfield_get_len(dfield2) != UNIV_SQL_NULL) {
 
 			storage_len = dtype_get_at_most_n_mbchars(
-				col->prtype, col->mbminlen, col->mbmaxlen,
+				col->prtype, col->mbminmaxlen,
 				ind_field->prefix_len,
 				dfield_get_len(dfield2), dfield2->data);
 
@@ -426,8 +426,7 @@ row_build_row_ref(
 				dfield_set_len(dfield,
 					       dtype_get_at_most_n_mbchars(
 						       dtype->prtype,
-						       dtype->mbminlen,
-						       dtype->mbmaxlen,
+						       dtype->mbminmaxlen,
 						       clust_col_prefix_len,
 						       len, (char*) field));
 			}
@@ -530,8 +529,7 @@ notfound:
 				dfield_set_len(dfield,
 					       dtype_get_at_most_n_mbchars(
 						       dtype->prtype,
-						       dtype->mbminlen,
-						       dtype->mbmaxlen,
+						       dtype->mbminmaxlen,
 						       clust_col_prefix_len,
 						       len, (char*) field));
 			}
@@ -591,7 +589,7 @@ row_build_row_ref_from_row(
 		    && dfield->len != UNIV_SQL_NULL) {
 
 			dfield->len = dtype_get_at_most_n_mbchars(
-				col->prtype, col->mbminlen, col->mbmaxlen,
+				col->prtype, col->mbminmaxlen,
 				field->prefix_len, dfield->len, dfield->data);
 		}
 	}
diff -rpu storage/innobase/row/row0sel.c storage/innobase/row/row0sel.c
--- storage/innobase/row/row0sel.c	2008-09-11 11:36:33.000000000 +0300
+++ storage/innobase/row/row0sel.c	2008-10-28 10:12:30.000000000 +0200
@@ -107,7 +107,7 @@ row_sel_sec_rec_is_for_clust_rec(
 		if (ifield->prefix_len > 0 && clust_len != UNIV_SQL_NULL) {
 
 			clust_len = dtype_get_at_most_n_mbchars(
-				col->prtype, col->mbminlen, col->mbmaxlen,
+				col->prtype, col->mbminmaxlen,
 				ifield->prefix_len,
 				clust_len, (char*) clust_field);
 		}
diff -rpu storage/innobase/row/row0upd.c storage/innobase/row/row0upd.c
--- storage/innobase/row/row0upd.c	2008-09-11 11:36:33.000000000 +0300
+++ storage/innobase/row/row0upd.c	2008-10-28 10:13:22.000000000 +0200
@@ -929,8 +929,7 @@ row_upd_index_replace_new_col_vals_index
 					dfield->len
 						= dtype_get_at_most_n_mbchars(
 							col->prtype,
-							col->mbminlen,
-							col->mbmaxlen,
+							col->mbminmaxlen,
 							field->prefix_len,
 							new_val->len,
 							new_val->data);
@@ -1005,8 +1004,7 @@ row_upd_index_replace_new_col_vals(
 					dfield->len
 						= dtype_get_at_most_n_mbchars(
 							col->prtype,
-							col->mbminlen,
-							col->mbmaxlen,
+							col->mbminmaxlen,
 							field->prefix_len,
 							new_val->len,
 							new_val->data);
