summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorMagnus Svensson <msvensson@mysql.com>2008-05-30 11:12:07 +0200
committerMagnus Svensson <msvensson@mysql.com>2008-05-30 11:12:07 +0200
commita78afaac128edbe775fa56b3efbd65b0965ec406 (patch)
tree2c436ada208ddcfb89206130a251a9bc72631891 /sql/field.cc
parentf10d64a7ebff6fbd010e679e6b53f4340fec7867 (diff)
parent4941a70245247d008e1fee4febb607c7309e9dcb (diff)
downloadmariadb-git-a78afaac128edbe775fa56b3efbd65b0965ec406.tar.gz
Merge 5.1->5.1-rpl
Fix paths and name of a few files to make it work with new mtr.pl
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc54
1 files changed, 41 insertions, 13 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 32bf5855d8b..9bf6df55b30 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6328,6 +6328,7 @@ check_string_copy_error(Field_str *field,
Field_longstr::report_if_important_data()
ptr - Truncated rest of string
end - End of truncated string
+ count_spaces - Treat traling spaces as important data
RETURN VALUES
0 - None was truncated (or we don't count cut fields)
@@ -6337,10 +6338,12 @@ check_string_copy_error(Field_str *field,
Check if we lost any important data (anything in a binary string,
or any non-space in others). If only trailing spaces was lost,
send a truncation note, otherwise send a truncation error.
+ Silently ignore traling spaces if the count_space parameter is FALSE.
*/
int
-Field_longstr::report_if_important_data(const char *ptr, const char *end)
+Field_longstr::report_if_important_data(const char *ptr, const char *end,
+ bool count_spaces)
{
if ((ptr < end) && table->in_use->count_cuted_fields)
{
@@ -6350,10 +6353,13 @@ Field_longstr::report_if_important_data(const char *ptr, const char *end)
set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
else
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ return 2;
}
- else /* If we lost only spaces then produce a NOTE, not a WARNING */
+ else if (count_spaces)
+ { /* If we lost only spaces then produce a NOTE, not a WARNING */
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- return 2;
+ return 2;
+ }
}
return 0;
}
@@ -6390,7 +6396,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, FALSE);
}
@@ -6965,7 +6971,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, TRUE);
}
@@ -7568,6 +7574,7 @@ uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg, bool low_by
return (uint32) tmp;
}
}
+ /* When expanding this, see also MAX_FIELD_BLOBLENGTH. */
return 0; // Impossible
}
@@ -7668,7 +7675,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, TRUE);
oom_error:
/* Fatal OOM error */
@@ -9449,8 +9456,20 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != MYSQL_TYPE_TIMESTAMP)
flags|= NO_DEFAULT_VALUE_FLAG;
- if (fld_length && !(length= (uint) atoi(fld_length)))
- fld_length= 0; /* purecov: inspected */
+ if (fld_length != NULL)
+ {
+ errno= 0;
+ length= strtoul(fld_length, NULL, 10);
+ if ((errno != 0) || (length > MAX_FIELD_BLOBLENGTH))
+ {
+ my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (length == 0)
+ fld_length= 0; /* purecov: inspected */
+ }
+
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
switch (fld_type) {
@@ -9598,7 +9617,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
break;
case MYSQL_TYPE_TIMESTAMP:
- if (!fld_length)
+ if (fld_length == NULL)
{
/* Compressed date YYYYMMDDHHMMSS */
length= MAX_DATETIME_COMPRESSED_WIDTH;
@@ -9607,12 +9626,21 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
{
/*
We support only even TIMESTAMP lengths less or equal than 14
- and 19 as length of 4.1 compatible representation.
+ and 19 as length of 4.1 compatible representation. Silently
+ shrink it to MAX_DATETIME_COMPRESSED_WIDTH.
*/
- length= ((length+1)/2)*2; /* purecov: inspected */
- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH); /* purecov: inspected */
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+ length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
}
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+ Since we silently rewrite down to MAX_DATETIME_COMPRESSED_WIDTH bytes,
+ the parser should not raise errors unless bizzarely large.
+ */
+ max_field_charlength= UINT_MAX;
+
if (fld_default_value)
{
/* Grammar allows only NOW() value for ON UPDATE clause */
@@ -9719,7 +9747,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
((length > max_field_charlength && fld_type != MYSQL_TYPE_SET &&
fld_type != MYSQL_TYPE_ENUM &&
(fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) ||
- (!length &&
+ ((length == 0) &&
fld_type != MYSQL_TYPE_STRING &&
fld_type != MYSQL_TYPE_VARCHAR && fld_type != MYSQL_TYPE_GEOMETRY)))
{