Commit 9ce74a80 authored by unknown's avatar unknown

ha_innodb.cc:

  Fix bug #9526 in InnoDB: the internal type of an ENUM or SET is an unsigned integer type, not a character string


sql/ha_innodb.cc:
  Fix bug #9526 in InnoDB: the internal type of an ENUM or SET is an unsigned integer type, not a character string
parent 07182f5a
...@@ -1923,8 +1923,11 @@ inline ...@@ -1923,8 +1923,11 @@ inline
ulint ulint
get_innobase_type_from_mysql_type( get_innobase_type_from_mysql_type(
/*==============================*/ /*==============================*/
/* out: DATA_BINARY, DATA_VARCHAR, ... */ /* out: DATA_BINARY, DATA_VARCHAR, ... */
Field* field) /* in: MySQL field */ ulint* unsigned_flag, /* out: DATA_UNSIGNED if an 'unsigned type';
at least ENUM and SET, and unsigned integer
types are 'unsigned types' */
Field* field) /* in: MySQL field */
{ {
/* The following asserts try to check that the MySQL type code fits in /* The following asserts try to check that the MySQL type code fits in
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to 8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
...@@ -1936,6 +1939,27 @@ get_innobase_type_from_mysql_type( ...@@ -1936,6 +1939,27 @@ get_innobase_type_from_mysql_type(
DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256); DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256);
DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256); DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256);
if (field->flags & UNSIGNED_FLAG) {
*unsigned_flag = DATA_UNSIGNED;
} else {
*unsigned_flag = 0;
}
if (field->real_type() == FIELD_TYPE_ENUM
|| field->real_type() == FIELD_TYPE_SET) {
/* MySQL has field->type() a string type for these, but the
data is actually internally stored as an unsigned integer
code! */
*unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
flag set to zero, even though
internally this is an unsigned
integer type */
return(DATA_INT);
}
switch (field->type()) { switch (field->type()) {
/* NOTE that we only allow string types in DATA_MYSQL /* NOTE that we only allow string types in DATA_MYSQL
and DATA_VARMYSQL */ and DATA_VARMYSQL */
...@@ -1968,8 +1992,6 @@ get_innobase_type_from_mysql_type( ...@@ -1968,8 +1992,6 @@ get_innobase_type_from_mysql_type(
case FIELD_TYPE_DATETIME: case FIELD_TYPE_DATETIME:
case FIELD_TYPE_YEAR: case FIELD_TYPE_YEAR:
case FIELD_TYPE_NEWDATE: case FIELD_TYPE_NEWDATE:
case FIELD_TYPE_ENUM:
case FIELD_TYPE_SET:
case FIELD_TYPE_TIME: case FIELD_TYPE_TIME:
case FIELD_TYPE_TIMESTAMP: case FIELD_TYPE_TIMESTAMP:
return(DATA_INT); return(DATA_INT);
...@@ -2247,10 +2269,10 @@ build_template( ...@@ -2247,10 +2269,10 @@ build_template(
get_field_offset(table, field); get_field_offset(table, field);
templ->mysql_col_len = (ulint) field->pack_length(); templ->mysql_col_len = (ulint) field->pack_length();
templ->type = get_innobase_type_from_mysql_type(field); templ->type = get_innobase_type_from_mysql_type(
&templ->is_unsigned, 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->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
if (templ->type == DATA_BLOB) { if (templ->type == DATA_BLOB) {
prebuilt->templ_contains_blob = TRUE; prebuilt->templ_contains_blob = TRUE;
...@@ -2676,9 +2698,8 @@ calc_row_difference( ...@@ -2676,9 +2698,8 @@ calc_row_difference(
o_len = field->pack_length(); o_len = field->pack_length();
n_len = field->pack_length(); n_len = field->pack_length();
col_type = get_innobase_type_from_mysql_type(field); col_type = get_innobase_type_from_mysql_type(&is_unsigned,
is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); field);
switch (col_type) { switch (col_type) {
case DATA_BLOB: case DATA_BLOB:
...@@ -3546,19 +3567,14 @@ create_table_def( ...@@ -3546,19 +3567,14 @@ create_table_def(
for (i = 0; i < n_cols; i++) { for (i = 0; i < n_cols; i++) {
field = form->field[i]; field = form->field[i];
col_type = get_innobase_type_from_mysql_type(field); col_type = get_innobase_type_from_mysql_type(&unsigned_type,
field);
if (field->null_ptr) { if (field->null_ptr) {
nulls_allowed = 0; nulls_allowed = 0;
} else { } else {
nulls_allowed = DATA_NOT_NULL; nulls_allowed = DATA_NOT_NULL;
} }
if (field->flags & UNSIGNED_FLAG) {
unsigned_type = DATA_UNSIGNED;
} else {
unsigned_type = 0;
}
if (field->binary()) { if (field->binary()) {
binary_type = DATA_BINARY_TYPE; binary_type = DATA_BINARY_TYPE;
} else { } else {
...@@ -3612,6 +3628,7 @@ create_index( ...@@ -3612,6 +3628,7 @@ create_index(
ulint ind_type; ulint ind_type;
ulint col_type; ulint col_type;
ulint prefix_len; ulint prefix_len;
ulint is_unsigned;
ulint i; ulint i;
ulint j; ulint j;
...@@ -3661,7 +3678,8 @@ create_index( ...@@ -3661,7 +3678,8 @@ create_index(
ut_a(j < form->fields); ut_a(j < form->fields);
col_type = get_innobase_type_from_mysql_type(key_part->field); col_type = get_innobase_type_from_mysql_type(
&is_unsigned, key_part->field);
if (DATA_BLOB == col_type if (DATA_BLOB == col_type
|| key_part->length < field->pack_length()) { || key_part->length < field->pack_length()) {
......
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