diff options
author | unknown <marko@hundin.mysql.fi> | 2005-02-14 17:23:12 +0200 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2005-02-14 17:23:12 +0200 |
commit | cc2843e2fa8b8b89af0951815c88b0ecd8df62c1 (patch) | |
tree | 02cdd4c79dc893a53f2b7dba83a846ce17bb6ce5 /innobase | |
parent | 28bb6893e92d4dc0bde980f9591a0e6c27d60d44 (diff) | |
parent | 93fd45904acbf5914e417ff7cd8f394efd52e850 (diff) | |
download | mariadb-git-cc2843e2fa8b8b89af0951815c88b0ecd8df62c1.tar.gz |
Merge marko@bk-internal.mysql.com:/home/bk/mysql-5.0
into hundin.mysql.fi:/home/marko/k/mysql-5.0
sql/ha_innodb.cc:
Auto merged
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/data/data0type.c | 4 | ||||
-rw-r--r-- | innobase/include/data0type.h | 31 | ||||
-rw-r--r-- | innobase/include/data0type.ic | 119 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 4 | ||||
-rw-r--r-- | innobase/include/row0mysql.ic | 15 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 23 |
6 files changed, 147 insertions, 49 deletions
diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index b1297fe7a5b..b8e4dd9c7f2 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -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; /************************************************************************* @@ -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); } diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index 02c874836fd..4c327d0b7ed 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -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 @@ -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 diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index 15833905761..761f7b3da7f 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -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. */ @@ -39,6 +70,7 @@ dtype_set( type->len = len; type->prec = prec; + dtype_set_mblen(type); ut_ad(dtype_validate(type)); } @@ -83,17 +115,6 @@ dtype_get_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 ulint @@ -120,6 +141,33 @@ dtype_get_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 ulint @@ -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); } /************************************************************************** @@ -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); } /*************************************************************************** @@ -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: diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 2ef260829fc..7ffa6ebf87d 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -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 */ diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index fc922b52d0a..1f5d0b0c990 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -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; @@ -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--; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 8512e796a72..c0141f896ce 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2410,14 +2410,9 @@ row_sel_store_mysql_rec( /* Pad with trailing spaces */ data = mysql_rec + templ->mysql_col_offset; - /* Handle UCS2 strings differently. As no new - collations will be introduced in 4.1, we - hardcode the charset-collation codes here. - 5.0 will use a different approach. */ - if (templ->charset == 35 - || templ->charset == 90 - || (templ->charset >= 128 - && templ->charset <= 144)) { + ut_ad(templ->mbminlen <= templ->mbmaxlen); + /* Handle UCS2 strings differently. */ + if (templ->mbminlen == 2) { /* space=0x0020 */ ulint col_len = templ->mysql_col_len; @@ -2436,6 +2431,7 @@ row_sel_store_mysql_rec( data[len++] = 0x20; } } else { + ut_ad(templ->mbminlen == 1); /* space=0x20 */ memset(data + len, 0x20, templ->mysql_col_len - len); @@ -2477,14 +2473,8 @@ row_sel_store_mysql_rec( pad_char = '\0'; } - /* Handle UCS2 strings differently. As no new - collations will be introduced in 4.1, - we hardcode the charset-collation codes here. - 5.0 will use a different approach. */ - if (templ->charset == 35 - || templ->charset == 90 - || (templ->charset >= 128 - && templ->charset <= 144)) { + /* Handle UCS2 strings differently. */ + if (templ->mbminlen == 2) { /* There are two bytes per char, so the length has to be an even number. */ ut_a(!(templ->mysql_col_len & 1)); @@ -2497,6 +2487,7 @@ row_sel_store_mysql_rec( len -= 2; } } else { + ut_ad(templ->mbminlen == 1); memset(mysql_rec + templ->mysql_col_offset, pad_char, templ->mysql_col_len); } |