Loading innobase/data/data0type.c +3 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ charset-collation code for them. */ ulint data_mysql_default_charset_coll = 99999999; ulint data_mysql_latin1_swedish_charset_coll = 99999999; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0}; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0}; dtype_t* dtype_binary = &dtype_binary_val; /************************************************************************* Loading Loading @@ -216,6 +216,8 @@ dtype_validate( ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); } ut_a(type->mbminlen <= type->mbmaxlen); return(TRUE); } Loading innobase/include/data0type.h +29 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,24 @@ dtype_get_prec( /*===========*/ dtype_t* type); /************************************************************************* Gets the minimum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbminlen( /*===============*/ /* out: minimum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type); /* in: type */ /************************************************************************* Gets the maximum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbmaxlen( /*===============*/ /* out: maximum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type); /* in: type */ /************************************************************************* Gets the padding character code for the type. */ UNIV_INLINE ulint Loading Loading @@ -352,16 +370,25 @@ dtype_print( /*========*/ dtype_t* type); /* in: type */ /* Structure for an SQL data type */ /* Structure for an SQL data type. If you add fields to this structure, be sure to initialize them everywhere. This structure is initialized in the following functions: dtype_set() dtype_read_for_order_and_null_size() dtype_new_read_for_order_and_null_size() sym_tab_add_null_lit() */ struct dtype_struct{ ulint mtype; /* main data type */ ulint prtype; /* precise type; MySQL data type */ /* the remaining two fields do not affect alphabetical ordering: */ /* the remaining fields do not affect alphabetical ordering: */ ulint len; /* length */ ulint prec; /* precision */ ulint mbminlen; /* minimum length of a character, in bytes */ ulint mbmaxlen; /* maximum length of a character, in bytes */ }; #ifndef UNIV_NONINL Loading innobase/include/data0type.ic +99 −20 Original line number Diff line number Diff line Loading @@ -9,15 +9,46 @@ Created 1/16/1996 Heikki Tuuri #include "mach0data.h" /********************************************************************** Determines whether the given character set is of variable length. Get the variable length bounds of the given character set. NOTE: the prototype of this function is copied from ha_innodb.cc! If you change this function, you MUST change also the prototype here! */ extern ibool innobase_is_mb_cset( /*================*/ ulint cset); /* in: MySQL charset-collation code */ void innobase_get_cset_width( /*====================*/ ulint cset, /* in: MySQL charset-collation code */ ulint* mbminlen, /* out: minimum length of a char (in bytes) */ ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */ /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( /*===================*/ ulint prtype) /* in: precise data type */ { return((prtype >> 16) & 0xFFUL); } /************************************************************************* Sets the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void dtype_set_mblen( /*============*/ dtype_t* type) /* in/out: type struct */ { ut_ad(type); if (dtype_is_string_type(type->mtype)) { innobase_get_cset_width(dtype_get_charset_coll(type->prtype), &type->mbminlen, &type->mbmaxlen); ut_ad(type->mbminlen <= type->mbmaxlen); } else { type->mbminlen = type->mbmaxlen = 0; } } /************************************************************************* Sets a data type structure. */ Loading @@ -39,6 +70,7 @@ dtype_set( type->len = len; type->prec = prec; dtype_set_mblen(type); ut_ad(dtype_validate(type)); } Loading Loading @@ -82,17 +114,6 @@ dtype_get_prtype( return(type->prtype); } /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( /*===================*/ ulint prtype) /* in: precise data type */ { return((prtype >> 16) & 0xFFUL); } /************************************************************************* Gets the type length. */ UNIV_INLINE Loading @@ -119,6 +140,33 @@ dtype_get_prec( return(type->prec); } /************************************************************************* Gets the minimum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbminlen( /*===============*/ /* out: minimum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type) /* in: type */ { ut_ad(type); return(type->mbminlen); } /************************************************************************* Gets the maximum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbmaxlen( /*===============*/ /* out: maximum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type) /* in: type */ { ut_ad(type); return(type->mbmaxlen); } /************************************************************************* Gets the padding character code for the type. */ UNIV_INLINE Loading Loading @@ -211,6 +259,7 @@ dtype_read_for_order_and_null_size( type->prtype = dtype_form_prtype(type->prtype, data_mysql_default_charset_coll); dtype_set_mblen(type); } /************************************************************************** Loading Loading @@ -262,6 +311,7 @@ dtype_new_read_for_order_and_null_size( type->prtype = dtype_form_prtype(type->prtype, charset_coll); } dtype_set_mblen(type); } /*************************************************************************** Loading Loading @@ -305,11 +355,40 @@ dtype_get_fixed_size( case DATA_FLOAT: case DATA_DOUBLE: case DATA_MYSQL: if ((type->prtype & DATA_BINARY_TYPE) || !innobase_is_mb_cset( dtype_get_charset_coll( type->prtype))) { if (type->prtype & DATA_BINARY_TYPE) { return(dtype_get_len(type)); } else { /* We play it safe here and ask MySQL for mbminlen and mbmaxlen. Although type->mbminlen and type->mbmaxlen are initialized if and only if type->prtype is (in one of the 3 functions in this file), it could be that none of these functions has been called. */ ulint mbminlen, mbmaxlen; innobase_get_cset_width( dtype_get_charset_coll(type->prtype), &mbminlen, &mbmaxlen); if (type->mbminlen != mbminlen || type->mbmaxlen != mbmaxlen) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: " "mbminlen=%lu, " "mbmaxlen=%lu, " "type->mbminlen=%lu, " "type->mbmaxlen=%lu\n", (ulong) mbminlen, (ulong) mbmaxlen, (ulong) type->mbminlen, (ulong) type->mbmaxlen); } if (mbminlen == mbmaxlen) { return(dtype_get_len(type)); } } /* fall through for variable-length charsets */ case DATA_VARCHAR: Loading innobase/include/row0mysql.h +4 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,10 @@ struct mysql_row_templ_struct { numbers DATA_CHAR... */ ulint charset; /* MySQL charset-collation code of the column, or zero */ ulint mbminlen; /* minimum length of a char, in bytes, or zero if not a char type */ ulint mbmaxlen; /* maximum length of a char, in bytes, or zero if not a char type */ ulint is_unsigned; /* if a column type is an integer type and this field is != 0, then it is an unsigned integer type */ Loading innobase/include/row0mysql.ic +5 −10 Original line number Diff line number Diff line Loading @@ -93,17 +93,11 @@ row_mysql_store_col_in_innobase_format( || type == DATA_BINARY) { /* Remove trailing spaces. */ /* Handle UCS2 strings differently. As no new collations will be introduced in 4.1, we hardcode the charset-collation codes here. In 5.0, the logic will be based on mbminlen. */ ulint cset = dtype_get_charset_coll( dtype_get_prtype(dfield_get_type(dfield))); /* Handle UCS2 strings differently. */ ulint mbminlen = dtype_get_mbminlen( dfield_get_type(dfield)); ptr = row_mysql_read_var_ref(&col_len, mysql_data); if (cset == 35/*ucs2_general_ci*/ || cset == 90/*ucs2_bin*/ || (cset >= 128/*ucs2_unicode_ci*/ && cset <= 144/*ucs2_persian_ci*/)) { if (mbminlen == 2) { /* space=0x0020 */ /* Trim "half-chars", just in case. */ col_len &= ~1; Loading @@ -113,6 +107,7 @@ row_mysql_store_col_in_innobase_format( col_len -= 2; } } else { ut_a(mbminlen == 1); /* space=0x20 */ while (col_len > 0 && ptr[col_len - 1] == 0x20) { col_len--; Loading Loading
innobase/data/data0type.c +3 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ charset-collation code for them. */ ulint data_mysql_default_charset_coll = 99999999; ulint data_mysql_latin1_swedish_charset_coll = 99999999; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0}; dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0}; dtype_t* dtype_binary = &dtype_binary_val; /************************************************************************* Loading Loading @@ -216,6 +216,8 @@ dtype_validate( ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); } ut_a(type->mbminlen <= type->mbmaxlen); return(TRUE); } Loading
innobase/include/data0type.h +29 −2 Original line number Diff line number Diff line Loading @@ -271,6 +271,24 @@ dtype_get_prec( /*===========*/ dtype_t* type); /************************************************************************* Gets the minimum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbminlen( /*===============*/ /* out: minimum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type); /* in: type */ /************************************************************************* Gets the maximum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbmaxlen( /*===============*/ /* out: maximum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type); /* in: type */ /************************************************************************* Gets the padding character code for the type. */ UNIV_INLINE ulint Loading Loading @@ -352,16 +370,25 @@ dtype_print( /*========*/ dtype_t* type); /* in: type */ /* Structure for an SQL data type */ /* Structure for an SQL data type. If you add fields to this structure, be sure to initialize them everywhere. This structure is initialized in the following functions: dtype_set() dtype_read_for_order_and_null_size() dtype_new_read_for_order_and_null_size() sym_tab_add_null_lit() */ struct dtype_struct{ ulint mtype; /* main data type */ ulint prtype; /* precise type; MySQL data type */ /* the remaining two fields do not affect alphabetical ordering: */ /* the remaining fields do not affect alphabetical ordering: */ ulint len; /* length */ ulint prec; /* precision */ ulint mbminlen; /* minimum length of a character, in bytes */ ulint mbmaxlen; /* maximum length of a character, in bytes */ }; #ifndef UNIV_NONINL Loading
innobase/include/data0type.ic +99 −20 Original line number Diff line number Diff line Loading @@ -9,15 +9,46 @@ Created 1/16/1996 Heikki Tuuri #include "mach0data.h" /********************************************************************** Determines whether the given character set is of variable length. Get the variable length bounds of the given character set. NOTE: the prototype of this function is copied from ha_innodb.cc! If you change this function, you MUST change also the prototype here! */ extern ibool innobase_is_mb_cset( /*================*/ ulint cset); /* in: MySQL charset-collation code */ void innobase_get_cset_width( /*====================*/ ulint cset, /* in: MySQL charset-collation code */ ulint* mbminlen, /* out: minimum length of a char (in bytes) */ ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */ /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( /*===================*/ ulint prtype) /* in: precise data type */ { return((prtype >> 16) & 0xFFUL); } /************************************************************************* Sets the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void dtype_set_mblen( /*============*/ dtype_t* type) /* in/out: type struct */ { ut_ad(type); if (dtype_is_string_type(type->mtype)) { innobase_get_cset_width(dtype_get_charset_coll(type->prtype), &type->mbminlen, &type->mbmaxlen); ut_ad(type->mbminlen <= type->mbmaxlen); } else { type->mbminlen = type->mbmaxlen = 0; } } /************************************************************************* Sets a data type structure. */ Loading @@ -39,6 +70,7 @@ dtype_set( type->len = len; type->prec = prec; dtype_set_mblen(type); ut_ad(dtype_validate(type)); } Loading Loading @@ -82,17 +114,6 @@ dtype_get_prtype( return(type->prtype); } /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( /*===================*/ ulint prtype) /* in: precise data type */ { return((prtype >> 16) & 0xFFUL); } /************************************************************************* Gets the type length. */ UNIV_INLINE Loading @@ -119,6 +140,33 @@ dtype_get_prec( return(type->prec); } /************************************************************************* Gets the minimum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbminlen( /*===============*/ /* out: minimum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type) /* in: type */ { ut_ad(type); return(type->mbminlen); } /************************************************************************* Gets the maximum length of a character, in bytes. */ UNIV_INLINE ulint dtype_get_mbmaxlen( /*===============*/ /* out: maximum length of a char, in bytes, or 0 if this is not a character type */ const dtype_t* type) /* in: type */ { ut_ad(type); return(type->mbmaxlen); } /************************************************************************* Gets the padding character code for the type. */ UNIV_INLINE Loading Loading @@ -211,6 +259,7 @@ dtype_read_for_order_and_null_size( type->prtype = dtype_form_prtype(type->prtype, data_mysql_default_charset_coll); dtype_set_mblen(type); } /************************************************************************** Loading Loading @@ -262,6 +311,7 @@ dtype_new_read_for_order_and_null_size( type->prtype = dtype_form_prtype(type->prtype, charset_coll); } dtype_set_mblen(type); } /*************************************************************************** Loading Loading @@ -305,11 +355,40 @@ dtype_get_fixed_size( case DATA_FLOAT: case DATA_DOUBLE: case DATA_MYSQL: if ((type->prtype & DATA_BINARY_TYPE) || !innobase_is_mb_cset( dtype_get_charset_coll( type->prtype))) { if (type->prtype & DATA_BINARY_TYPE) { return(dtype_get_len(type)); } else { /* We play it safe here and ask MySQL for mbminlen and mbmaxlen. Although type->mbminlen and type->mbmaxlen are initialized if and only if type->prtype is (in one of the 3 functions in this file), it could be that none of these functions has been called. */ ulint mbminlen, mbmaxlen; innobase_get_cset_width( dtype_get_charset_coll(type->prtype), &mbminlen, &mbmaxlen); if (type->mbminlen != mbminlen || type->mbmaxlen != mbmaxlen) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: " "mbminlen=%lu, " "mbmaxlen=%lu, " "type->mbminlen=%lu, " "type->mbmaxlen=%lu\n", (ulong) mbminlen, (ulong) mbmaxlen, (ulong) type->mbminlen, (ulong) type->mbmaxlen); } if (mbminlen == mbmaxlen) { return(dtype_get_len(type)); } } /* fall through for variable-length charsets */ case DATA_VARCHAR: Loading
innobase/include/row0mysql.h +4 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,10 @@ struct mysql_row_templ_struct { numbers DATA_CHAR... */ ulint charset; /* MySQL charset-collation code of the column, or zero */ ulint mbminlen; /* minimum length of a char, in bytes, or zero if not a char type */ ulint mbmaxlen; /* maximum length of a char, in bytes, or zero if not a char type */ ulint is_unsigned; /* if a column type is an integer type and this field is != 0, then it is an unsigned integer type */ Loading
innobase/include/row0mysql.ic +5 −10 Original line number Diff line number Diff line Loading @@ -93,17 +93,11 @@ row_mysql_store_col_in_innobase_format( || type == DATA_BINARY) { /* Remove trailing spaces. */ /* Handle UCS2 strings differently. As no new collations will be introduced in 4.1, we hardcode the charset-collation codes here. In 5.0, the logic will be based on mbminlen. */ ulint cset = dtype_get_charset_coll( dtype_get_prtype(dfield_get_type(dfield))); /* Handle UCS2 strings differently. */ ulint mbminlen = dtype_get_mbminlen( dfield_get_type(dfield)); ptr = row_mysql_read_var_ref(&col_len, mysql_data); if (cset == 35/*ucs2_general_ci*/ || cset == 90/*ucs2_bin*/ || (cset >= 128/*ucs2_unicode_ci*/ && cset <= 144/*ucs2_persian_ci*/)) { if (mbminlen == 2) { /* space=0x0020 */ /* Trim "half-chars", just in case. */ col_len &= ~1; Loading @@ -113,6 +107,7 @@ row_mysql_store_col_in_innobase_format( col_len -= 2; } } else { ut_a(mbminlen == 1); /* space=0x20 */ while (col_len > 0 && ptr[col_len - 1] == 0x20) { col_len--; Loading