Commit 9ce74a80 authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+35 −17
Original line number Diff line number Diff line
@@ -1924,6 +1924,9 @@ ulint
get_innobase_type_from_mysql_type(
/*==============================*/
				/* out: DATA_BINARY, DATA_VARCHAR, ... */
	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
@@ -1936,6 +1939,27 @@ get_innobase_type_from_mysql_type(
	DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 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()) {
	        /* NOTE that we only allow string types in DATA_MYSQL
		and DATA_VARMYSQL */
@@ -1968,8 +1992,6 @@ get_innobase_type_from_mysql_type(
		case FIELD_TYPE_DATETIME:
		case FIELD_TYPE_YEAR:
		case FIELD_TYPE_NEWDATE:
		case FIELD_TYPE_ENUM:
		case FIELD_TYPE_SET:
		case FIELD_TYPE_TIME:
		case FIELD_TYPE_TIMESTAMP:
					return(DATA_INT);
@@ -2247,10 +2269,10 @@ build_template(
					get_field_offset(table, field);

		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(
				index->table->cols[i].type.prtype);
		templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);

		if (templ->type == DATA_BLOB) {
			prebuilt->templ_contains_blob = TRUE;
@@ -2676,9 +2698,8 @@ calc_row_difference(
		o_len = field->pack_length();
		n_len = field->pack_length();

		col_type = get_innobase_type_from_mysql_type(field);
		is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);

		col_type = get_innobase_type_from_mysql_type(&is_unsigned,
									field);
		switch (col_type) {

		case DATA_BLOB:
@@ -3546,19 +3567,14 @@ create_table_def(
	for (i = 0; i < n_cols; 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) {
			nulls_allowed = 0;
		} else {
			nulls_allowed = DATA_NOT_NULL;
		}

		if (field->flags & UNSIGNED_FLAG) {
			unsigned_type = DATA_UNSIGNED;
		} else {
			unsigned_type = 0;
		}

		if (field->binary()) {
			binary_type = DATA_BINARY_TYPE;
		} else {
@@ -3612,6 +3628,7 @@ create_index(
	ulint		ind_type;
	ulint		col_type;
	ulint		prefix_len;
	ulint		is_unsigned;
  	ulint		i;
  	ulint		j;

@@ -3661,7 +3678,8 @@ create_index(

		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
		    || key_part->length < field->pack_length()) {