summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc126
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