diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 126 |
1 files changed, 64 insertions, 62 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 18c90d549ec..f6bdb595b2a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -38,6 +38,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, bool ignore, uint order_num, ORDER *order, ha_rows *copied,ha_rows *deleted); +static bool prepare_blob_field(THD *thd, create_field *sql_field); /* delete (drop) tables. @@ -700,21 +701,20 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, String conv, *tmp; for (uint i= 0; (tmp= it++); i++) { + uint lengthsp; if (String::needs_conversion(tmp->length(), tmp->charset(), cs, &dummy)) { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - char *buf= (char*) sql_alloc(conv.length()+1); - memcpy(buf, conv.ptr(), conv.length()); - buf[conv.length()]= '\0'; - interval->type_names[i]= buf; + interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(), + conv.length()); interval->type_lengths[i]= conv.length(); } // Strip trailing spaces. - uint lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], - interval->type_lengths[i]); + lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], + interval->type_lengths[i]); interval->type_lengths[i]= lengthsp; ((uchar *)interval->type_names[i])[lengthsp]= '\0'; } @@ -781,37 +781,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } sql_field->create_length_to_internal_length(); - if (sql_field->length > MAX_FIELD_VARCHARLENGTH && - !(sql_field->flags & BLOB_FLAG)) - { - /* Convert long VARCHAR columns to TEXT or BLOB */ - char warn_buff[MYSQL_ERRMSG_SIZE]; - - if (sql_field->def) - { - my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, - MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); - DBUG_RETURN(-1); - } - sql_field->sql_type= FIELD_TYPE_BLOB; - sql_field->flags|= BLOB_FLAG; - sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, - "VARCHAR", - (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, - warn_buff); - } - - if ((sql_field->flags & BLOB_FLAG) && sql_field->length) - { - if (sql_field->sql_type == FIELD_TYPE_BLOB) - { - /* The user has given a length to the blob column */ - sql_field->sql_type= get_blob_type_from_length(sql_field->length); - sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0); - } - sql_field->length= 0; // Probably from an item - } + if (prepare_blob_field(thd, sql_field)) + DBUG_RETURN(-1); if (!(sql_field->flags & NOT_NULL_FLAG)) null_fields++; @@ -1352,6 +1323,58 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* + Extend long VARCHAR fields to blob & prepare field if it's a blob + + SYNOPSIS + prepare_blob_field() + sql_field Field to check + + RETURN + 0 ok + 1 Error (sql_field can't be converted to blob) + In this case the error is given +*/ + +static bool prepare_blob_field(THD *thd, create_field *sql_field) +{ + DBUG_ENTER("prepare_blob_field"); + + if (sql_field->length > MAX_FIELD_VARCHARLENGTH && + !(sql_field->flags & BLOB_FLAG)) + { + /* Convert long VARCHAR columns to TEXT or BLOB */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + + if (sql_field->def) + { + my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, + MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); + DBUG_RETURN(1); + } + sql_field->sql_type= FIELD_TYPE_BLOB; + sql_field->flags|= BLOB_FLAG; + sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, + "VARCHAR", + (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT"); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, + warn_buff); + } + + if ((sql_field->flags & BLOB_FLAG) && sql_field->length) + { + if (sql_field->sql_type == FIELD_TYPE_BLOB) + { + /* The user has given a length to the blob column */ + sql_field->sql_type= get_blob_type_from_length(sql_field->length); + sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0); + } + sql_field->length= 0; + } + DBUG_RETURN(0); +} + + +/* Preparation of create_field for SP function return values. Based on code used in the inner loop of mysql_prepare_table() above @@ -1395,33 +1418,12 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) FIELDFLAG_TREAT_BIT_AS_CHAR; } sql_field->create_length_to_internal_length(); + DBUG_ASSERT(sql_field->def == 0); + /* Can't go wrong as sql_field->def is not defined */ + (void) prepare_blob_field(thd, sql_field); +} - if (sql_field->length > MAX_FIELD_VARCHARLENGTH && - !(sql_field->flags & BLOB_FLAG)) - { - /* Convert long VARCHAR columns to TEXT or BLOB */ - char warn_buff[MYSQL_ERRMSG_SIZE]; - - sql_field->sql_type= FIELD_TYPE_BLOB; - sql_field->flags|= BLOB_FLAG; - sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, - "VARCHAR", - (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, - warn_buff); - } - if ((sql_field->flags & BLOB_FLAG) && sql_field->length) - { - if (sql_field->sql_type == FIELD_TYPE_BLOB) - { - /* The user has given a length to the blob column */ - sql_field->sql_type= get_blob_type_from_length(sql_field->length); - sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0); - } - sql_field->length= 0; // Probably from an item - } -} /* Create a table |