summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_blob.result6
-rw-r--r--mysql-test/t/type_blob.test4
-rw-r--r--sql/field.cc24
-rw-r--r--sql/unireg.h2
4 files changed, 26 insertions, 10 deletions
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 84f2d815bdd..4c9ee9b84e3 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -880,9 +880,13 @@ Warnings:
Warning 1287 'TIMESTAMP(4294967294)' is deprecated; use 'TIMESTAMP' instead
DROP TABLE b15776;
CREATE TABLE b15776 (a timestamp(4294967295));
-ERROR 42000: Display width out of range for column 'a' (max = 255)
+Warnings:
+Warning 1287 'TIMESTAMP(4294967295)' is deprecated; use 'TIMESTAMP' instead
+DROP TABLE b15776;
CREATE TABLE b15776 (a timestamp(4294967296));
ERROR 42000: Display width out of range for column 'a' (max = 4294967295)
+CREATE TABLE b15776 (a timestamp(-1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
CREATE TABLE b15776 (a timestamp(-2));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-2))' at line 1
CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test
index ad578a18979..d7af7c40d23 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -528,11 +528,13 @@ CREATE TABLE b15776 (a year(-2));
## For timestamp, we silently rewrite widths to 14 or 19.
CREATE TABLE b15776 (a timestamp(4294967294));
DROP TABLE b15776;
---error ER_TOO_BIG_DISPLAYWIDTH
CREATE TABLE b15776 (a timestamp(4294967295));
+DROP TABLE b15776;
--error ER_TOO_BIG_DISPLAYWIDTH
CREATE TABLE b15776 (a timestamp(4294967296));
--error ER_PARSE_ERROR
+CREATE TABLE b15776 (a timestamp(-1));
+--error ER_PARSE_ERROR
CREATE TABLE b15776 (a timestamp(-2));
diff --git a/sql/field.cc b/sql/field.cc
index 2950f349580..99b61ec1ee0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6848,6 +6848,7 @@ uint32 Field_blob::get_length(const char *pos)
return (uint32) tmp;
}
}
+ /* When expanding this, see also MAX_FIELD_BLOBLENGTH. */
return 0; // Impossible
}
@@ -8395,11 +8396,11 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP)
flags|= NO_DEFAULT_VALUE_FLAG;
- if (fld_length != 0)
+ if (fld_length != NULL)
{
errno= 0;
length= strtoul(fld_length, NULL, 10);
- if (errno != 0)
+ if ((errno != 0) || (length > MAX_FIELD_BLOBLENGTH))
{
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
DBUG_RETURN(TRUE);
@@ -8556,7 +8557,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
break;
case FIELD_TYPE_TIMESTAMP:
- if (!fld_length)
+ if (fld_length == NULL)
{
/* Compressed date YYYYMMDDHHMMSS */
length= MAX_DATETIME_COMPRESSED_WIDTH;
@@ -8565,12 +8566,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 */
@@ -8677,7 +8687,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
((length > max_field_charlength && fld_type != FIELD_TYPE_SET &&
fld_type != FIELD_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 != FIELD_TYPE_GEOMETRY)))
{
diff --git a/sql/unireg.h b/sql/unireg.h
index 0ab2a40048b..24e57b4e584 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -60,7 +60,7 @@
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FIELD_CHARLENGTH 255
#define MAX_FIELD_VARCHARLENGTH 65535
-#define MAX_FIELD_BLOBLENGTH UINT_MAX
+#define MAX_FIELD_BLOBLENGTH UINT_MAX32 /* cf field_blob::get_length() */
#define CONVERT_IF_BIGGER_TO_BLOB 512 /* Used for CREATE ... SELECT */
/* Max column width +1 */