Commit cc2843e2 authored by unknown's avatar unknown

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
parents 28bb6893 93fd4590
...@@ -41,7 +41,7 @@ charset-collation code for them. */ ...@@ -41,7 +41,7 @@ charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999; ulint data_mysql_default_charset_coll = 99999999;
ulint data_mysql_latin1_swedish_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; dtype_t* dtype_binary = &dtype_binary_val;
/************************************************************************* /*************************************************************************
...@@ -216,6 +216,8 @@ dtype_validate( ...@@ -216,6 +216,8 @@ dtype_validate(
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
} }
ut_a(type->mbminlen <= type->mbmaxlen);
return(TRUE); return(TRUE);
} }
......
...@@ -271,6 +271,24 @@ dtype_get_prec( ...@@ -271,6 +271,24 @@ dtype_get_prec(
/*===========*/ /*===========*/
dtype_t* type); 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. */ Gets the padding character code for the type. */
UNIV_INLINE UNIV_INLINE
ulint ulint
...@@ -352,16 +370,25 @@ dtype_print( ...@@ -352,16 +370,25 @@ dtype_print(
/*========*/ /*========*/
dtype_t* type); /* in: type */ 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{ struct dtype_struct{
ulint mtype; /* main data type */ ulint mtype; /* main data type */
ulint prtype; /* precise type; MySQL 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 len; /* length */
ulint prec; /* precision */ ulint prec; /* precision */
ulint mbminlen; /* minimum length of a character, in bytes */
ulint mbmaxlen; /* maximum length of a character, in bytes */
}; };
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
......
...@@ -9,15 +9,46 @@ Created 1/16/1996 Heikki Tuuri ...@@ -9,15 +9,46 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h" #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 NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */ this function, you MUST change also the prototype here! */
extern extern
ibool void
innobase_is_mb_cset( innobase_get_cset_width(
/*================*/ /*====================*/
ulint cset); /* in: MySQL charset-collation code */ 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. */ Sets a data type structure. */
...@@ -39,6 +70,7 @@ dtype_set( ...@@ -39,6 +70,7 @@ dtype_set(
type->len = len; type->len = len;
type->prec = prec; type->prec = prec;
dtype_set_mblen(type);
ut_ad(dtype_validate(type)); ut_ad(dtype_validate(type));
} }
...@@ -82,17 +114,6 @@ dtype_get_prtype( ...@@ -82,17 +114,6 @@ dtype_get_prtype(
return(type->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. */ Gets the type length. */
UNIV_INLINE UNIV_INLINE
...@@ -119,6 +140,33 @@ dtype_get_prec( ...@@ -119,6 +140,33 @@ dtype_get_prec(
return(type->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. */ Gets the padding character code for the type. */
UNIV_INLINE UNIV_INLINE
...@@ -211,6 +259,7 @@ dtype_read_for_order_and_null_size( ...@@ -211,6 +259,7 @@ dtype_read_for_order_and_null_size(
type->prtype = dtype_form_prtype(type->prtype, type->prtype = dtype_form_prtype(type->prtype,
data_mysql_default_charset_coll); data_mysql_default_charset_coll);
dtype_set_mblen(type);
} }
/************************************************************************** /**************************************************************************
...@@ -262,6 +311,7 @@ dtype_new_read_for_order_and_null_size( ...@@ -262,6 +311,7 @@ dtype_new_read_for_order_and_null_size(
type->prtype = dtype_form_prtype(type->prtype, charset_coll); type->prtype = dtype_form_prtype(type->prtype, charset_coll);
} }
dtype_set_mblen(type);
} }
/*************************************************************************** /***************************************************************************
...@@ -305,11 +355,40 @@ dtype_get_fixed_size( ...@@ -305,11 +355,40 @@ dtype_get_fixed_size(
case DATA_FLOAT: case DATA_FLOAT:
case DATA_DOUBLE: case DATA_DOUBLE:
case DATA_MYSQL: case DATA_MYSQL:
if ((type->prtype & DATA_BINARY_TYPE) if (type->prtype & DATA_BINARY_TYPE) {
|| !innobase_is_mb_cset(
dtype_get_charset_coll(
type->prtype))) {
return(dtype_get_len(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 */ /* fall through for variable-length charsets */
case DATA_VARCHAR: case DATA_VARCHAR:
......
...@@ -458,6 +458,10 @@ struct mysql_row_templ_struct { ...@@ -458,6 +458,10 @@ struct mysql_row_templ_struct {
numbers DATA_CHAR... */ numbers DATA_CHAR... */
ulint charset; /* MySQL charset-collation code ulint charset; /* MySQL charset-collation code
of the column, or zero */ 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 ulint is_unsigned; /* if a column type is an integer
type and this field is != 0, then type and this field is != 0, then
it is an unsigned integer type */ it is an unsigned integer type */
......
...@@ -93,17 +93,11 @@ row_mysql_store_col_in_innobase_format( ...@@ -93,17 +93,11 @@ row_mysql_store_col_in_innobase_format(
|| type == DATA_BINARY) { || type == DATA_BINARY) {
/* Remove trailing spaces. */ /* Remove trailing spaces. */
/* Handle UCS2 strings differently. As no new /* Handle UCS2 strings differently. */
collations will be introduced in 4.1, we hardcode the ulint mbminlen = dtype_get_mbminlen(
charset-collation codes here. In 5.0, the logic will dfield_get_type(dfield));
be based on mbminlen. */
ulint cset = dtype_get_charset_coll(
dtype_get_prtype(dfield_get_type(dfield)));
ptr = row_mysql_read_var_ref(&col_len, mysql_data); ptr = row_mysql_read_var_ref(&col_len, mysql_data);
if (cset == 35/*ucs2_general_ci*/ if (mbminlen == 2) {
|| cset == 90/*ucs2_bin*/
|| (cset >= 128/*ucs2_unicode_ci*/
&& cset <= 144/*ucs2_persian_ci*/)) {
/* space=0x0020 */ /* space=0x0020 */
/* Trim "half-chars", just in case. */ /* Trim "half-chars", just in case. */
col_len &= ~1; col_len &= ~1;
...@@ -113,6 +107,7 @@ row_mysql_store_col_in_innobase_format( ...@@ -113,6 +107,7 @@ row_mysql_store_col_in_innobase_format(
col_len -= 2; col_len -= 2;
} }
} else { } else {
ut_a(mbminlen == 1);
/* space=0x20 */ /* space=0x20 */
while (col_len > 0 && ptr[col_len - 1] == 0x20) { while (col_len > 0 && ptr[col_len - 1] == 0x20) {
col_len--; col_len--;
......
...@@ -2410,14 +2410,9 @@ row_sel_store_mysql_rec( ...@@ -2410,14 +2410,9 @@ row_sel_store_mysql_rec(
/* Pad with trailing spaces */ /* Pad with trailing spaces */
data = mysql_rec + templ->mysql_col_offset; data = mysql_rec + templ->mysql_col_offset;
/* Handle UCS2 strings differently. As no new ut_ad(templ->mbminlen <= templ->mbmaxlen);
collations will be introduced in 4.1, we /* Handle UCS2 strings differently. */
hardcode the charset-collation codes here. if (templ->mbminlen == 2) {
5.0 will use a different approach. */
if (templ->charset == 35
|| templ->charset == 90
|| (templ->charset >= 128
&& templ->charset <= 144)) {
/* space=0x0020 */ /* space=0x0020 */
ulint col_len = templ->mysql_col_len; ulint col_len = templ->mysql_col_len;
...@@ -2436,6 +2431,7 @@ row_sel_store_mysql_rec( ...@@ -2436,6 +2431,7 @@ row_sel_store_mysql_rec(
data[len++] = 0x20; data[len++] = 0x20;
} }
} else { } else {
ut_ad(templ->mbminlen == 1);
/* space=0x20 */ /* space=0x20 */
memset(data + len, 0x20, memset(data + len, 0x20,
templ->mysql_col_len - len); templ->mysql_col_len - len);
...@@ -2477,14 +2473,8 @@ row_sel_store_mysql_rec( ...@@ -2477,14 +2473,8 @@ row_sel_store_mysql_rec(
pad_char = '\0'; pad_char = '\0';
} }
/* Handle UCS2 strings differently. As no new /* Handle UCS2 strings differently. */
collations will be introduced in 4.1, if (templ->mbminlen == 2) {
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)) {
/* There are two bytes per char, so the length /* There are two bytes per char, so the length
has to be an even number. */ has to be an even number. */
ut_a(!(templ->mysql_col_len & 1)); ut_a(!(templ->mysql_col_len & 1));
...@@ -2497,6 +2487,7 @@ row_sel_store_mysql_rec( ...@@ -2497,6 +2487,7 @@ row_sel_store_mysql_rec(
len -= 2; len -= 2;
} }
} else { } else {
ut_ad(templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset, memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len); pad_char, templ->mysql_col_len);
} }
......
...@@ -535,22 +535,31 @@ innobase_mysql_print_thd( ...@@ -535,22 +535,31 @@ innobase_mysql_print_thd(
} }
/********************************************************************** /**********************************************************************
Determines whether the given character set is of variable length. Get the variable length bounds of the given character set.
NOTE that the exact prototype of this function has to be in NOTE that the exact prototype of this function has to be in
/innobase/data/data0type.ic! */ /innobase/data/data0type.ic! */
extern "C" extern "C"
ibool void
innobase_is_mb_cset( innobase_get_cset_width(
/*================*/ /*====================*/
ulint cset) /* in: MySQL charset-collation code */ 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) */
{ {
CHARSET_INFO* cs; CHARSET_INFO* cs;
ut_ad(cset < 256); ut_ad(cset < 256);
ut_ad(mbminlen);
ut_ad(mbmaxlen);
cs = all_charsets[cset]; cs = all_charsets[cset];
if (cs) {
return(cs && cs->mbminlen != cs->mbmaxlen); *mbminlen = cs->mbminlen;
*mbmaxlen = cs->mbmaxlen;
} else {
ut_a(cset == 0);
*mbminlen = *mbmaxlen = 0;
}
} }
/********************************************************************** /**********************************************************************
...@@ -2480,6 +2489,8 @@ build_template( ...@@ -2480,6 +2489,8 @@ build_template(
templ->type = get_innobase_type_from_mysql_type(field); templ->type = get_innobase_type_from_mysql_type(field);
templ->charset = dtype_get_charset_coll_noninline( templ->charset = dtype_get_charset_coll_noninline(
index->table->cols[i].type.prtype); index->table->cols[i].type.prtype);
templ->mbminlen = index->table->cols[i].type.mbminlen;
templ->mbmaxlen = index->table->cols[i].type.mbmaxlen;
templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
if (templ->type == DATA_BLOB) { if (templ->type == DATA_BLOB) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment