From 13fea36d03529eefceadaa16b8a9d1faf3802eed Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 31 Aug 2007 15:24:43 -0400 Subject: [PATCH 1/4] Bug#15776: 32-bit signed int used for length of blob Based on contributed patch from Martin Friebe, CLA from 2007-02-24. The parser lacked support for field sizes after signed long, when it should extend to 2**32-1. Now, we correct that limitation, and also make the error handling consistent for casts. mysql-test/r/type_blob.result: Verify that blobs may be created with the size that is already documented. Additionally, test the limits of several other types. mysql-test/t/type_blob.test: Verify that blobs may be created with the size that is already documented. Additionally, test the limits of several other types. sql/field.cc: atoi() insufficient to gauge the length of some fields. Change it to strtoul(). sql/item_create.cc: atoi() insufficient to gauge the length of some fields. Change it to strtoul(). If a casted length is too long, raise an error. sql/share/errmsg.txt: Change ER_TOO_BIG_FIELDLENGTH so that it can accept sizes larger than 2**15 -- instead, 2**32. sql/sql_yacc.yy: Make lengths take, in addition to NUM, LONG_NUM, ULONGLONG_NUM, and DECIMAL_NUM. sql/unireg.h: Define new constant. --- mysql-test/r/type_blob.result | 147 +++++++++++++++++++++++++++++++ mysql-test/t/type_blob.test | 161 ++++++++++++++++++++++++++++++++++ sql/field.cc | 16 +++- sql/item_create.cc | 57 +++++++++++- sql/share/errmsg.txt | 60 ++++++------- sql/sql_yacc.yy | 55 ++++++------ sql/unireg.h | 1 + 7 files changed, 434 insertions(+), 63 deletions(-) diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index c72ee005428..599a2224472 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -807,4 +807,151 @@ set @@sql_mode='TRADITIONAL'; create table t1 (a text default ''); ERROR 42000: BLOB/TEXT column 'a' can't have a default value set @@sql_mode=''; +create table b15776 (data blob(2147483647)); +drop table b15776; +create table b15776 (data blob(-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 (data blob(2147483648)); +drop table b15776; +create table b15776 (data blob(4294967294)); +drop table b15776; +create table b15776 (data blob(4294967295)); +drop table b15776; +create table b15776 (data blob(4294967296)); +ERROR 42000: Display width out of range for column 'data' (max = 4294967295) +CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) ); +show columns from b15776; +Field Type Null Key Default Extra +a longblob YES NULL +b longblob YES NULL +c longblob YES NULL +a1 longtext YES NULL +b1 longtext YES NULL +c1 longtext YES NULL +drop table b15776; +CREATE TABLE b15776 (a blob(4294967296)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a text(4294967296)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a int(0)); +INSERT INTO b15776 values (NULL), (1), (42), (654); +SELECT * from b15776 ORDER BY a; +a +NULL +1 +42 +654 +DROP TABLE b15776; +CREATE TABLE b15776 (a int(-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 int(255)); +DROP TABLE b15776; +CREATE TABLE b15776 (a int(256)); +ERROR 42000: Display width out of range for column 'a' (max = 255) +CREATE TABLE b15776 (data blob(-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 char(2147483647)); +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead +CREATE TABLE b15776 (a char(2147483648)); +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead +CREATE TABLE b15776 (a char(4294967295)); +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead +CREATE TABLE b15776 (a char(4294967296)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a year(4294967295)); +INSERT INTO b15776 VALUES (42); +SELECT * FROM b15776; +a +2042 +DROP TABLE b15776; +CREATE TABLE b15776 (a year(4294967296)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a year(0)); +DROP TABLE b15776; +CREATE TABLE b15776 (a year(-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 timestamp(4294967294)); +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) +CREATE TABLE b15776 (a timestamp(4294967296)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +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)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 (a timestamp(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'a' (max = 4294967295) +CREATE TABLE b15776 select cast(null as char(4294967295)); +show columns from b15776; +Field Type Null Key Default Extra +cast(null as char(4294967295)) char(0) YES NULL +drop table b15776; +CREATE TABLE b15776 select cast(null as nchar(4294967295)); +show columns from b15776; +Field Type Null Key Default Extra +cast(null as nchar(4294967295)) char(0) YES NULL +drop table b15776; +CREATE TABLE b15776 select cast(null as binary(4294967295)); +show columns from b15776; +Field Type Null Key Default Extra +cast(null as binary(4294967295)) binary(0) YES NULL +drop table b15776; +explain select cast(1 as char(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select cast(1 as nchar(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select cast(1 as binary(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select cast(1 as char(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select cast(1 as nchar(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select cast(1 as binary(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select cast(1 as decimal(-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 +explain select cast(1 as decimal(64, 30)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select cast(1 as decimal(64, 999999999999999999999999999999)); +Got one of the listed errors +explain select cast(1 as decimal(4294967296)); +Got one of the listed errors +explain select cast(1 as decimal(999999999999999999999999999999999999)); +Got one of the listed errors +explain select convert(1, char(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select convert(1, char(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select convert(1, nchar(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select convert(1, nchar(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select convert(1, binary(4294967295)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain select convert(1, binary(4294967296)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) +explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +ERROR 42000: Display width out of range for column 'cast as char' (max = 4294967295) End of 5.0 tests diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index ba9f374a24c..097c749f977 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -436,4 +436,165 @@ set @@sql_mode='TRADITIONAL'; create table t1 (a text default ''); set @@sql_mode=''; +# +# Bug#15776: 32-bit signed int used for length of blob +# """LONGBLOB: A BLOB column with a maximum length of 4,294,967,295 or 4GB.""" +# +# Conditions should be in this order: +# A size is not in the allowed bounds. +# If the type is char-ish AND size is within the max blob size: +# raise ER_TOO_BIG_FIELDLENGTH (suggest using BLOB) +# If size is too small: +# raise ER_PARSE_ERROR +# raise ER_TOO_BIG_DISPLAYWIDTH + +# BLOB and TEXT types +create table b15776 (data blob(2147483647)); +drop table b15776; +--error ER_PARSE_ERROR +create table b15776 (data blob(-1)); +create table b15776 (data blob(2147483648)); +drop table b15776; +create table b15776 (data blob(4294967294)); +drop table b15776; +create table b15776 (data blob(4294967295)); +drop table b15776; +--error ER_TOO_BIG_DISPLAYWIDTH +create table b15776 (data blob(4294967296)); + +CREATE TABLE b15776 (a blob(2147483647), b blob(2147483648), c blob(4294967295), a1 text(2147483647), b1 text(2147483648), c1 text(4294967295) ); +show columns from b15776; +drop table b15776; + +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a blob(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a text(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a blob(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a text(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); + +# Int types +# "Another extension is supported by MySQL for optionally specifying the +# display width of integer data types in parentheses following the base keyword +# for the type (for example, INT(4)). This optional display width is used to +# display integer values having a width less than the width specified for the +# column by left-padding them with spaces." § Numeric Types +CREATE TABLE b15776 (a int(0)); # 0 is special case, means default size +INSERT INTO b15776 values (NULL), (1), (42), (654); +SELECT * from b15776 ORDER BY a; +DROP TABLE b15776; +--error ER_PARSE_ERROR +CREATE TABLE b15776 (a int(-1)); +CREATE TABLE b15776 (a int(255)); +DROP TABLE b15776; +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a int(256)); +--error ER_PARSE_ERROR +CREATE TABLE b15776 (data blob(-1)); + +# Char types +# Recommend BLOB +--error ER_TOO_BIG_FIELDLENGTH +CREATE TABLE b15776 (a char(2147483647)); +--error ER_TOO_BIG_FIELDLENGTH +CREATE TABLE b15776 (a char(2147483648)); +--error ER_TOO_BIG_FIELDLENGTH +CREATE TABLE b15776 (a char(4294967295)); +# Even BLOB won't hold +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a char(4294967296)); + + +# Other numeric-ish types +## For year, widths not "2" or "4" are silently rewritten to "4". But +## When we complain about it, we say that the max is 255. We may be +## talking about different things. It's confusing. +CREATE TABLE b15776 (a year(4294967295)); +INSERT INTO b15776 VALUES (42); +SELECT * FROM b15776; +DROP TABLE b15776; +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a year(4294967296)); +CREATE TABLE b15776 (a year(0)); # 0 is special case, means default size +DROP TABLE b15776; +--error ER_PARSE_ERROR +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)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a timestamp(4294967296)); +--error ER_PARSE_ERROR +CREATE TABLE b15776 (a timestamp(-2)); + + +# We've already tested the case, but this should visually show that +# widths that are too large to be interpreted cause DISPLAYWIDTH errors. +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a int(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a year(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a timestamp(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); + +## Do not select, too much memory needed. +CREATE TABLE b15776 select cast(null as char(4294967295)); +show columns from b15776; +drop table b15776; +CREATE TABLE b15776 select cast(null as nchar(4294967295)); +show columns from b15776; +drop table b15776; +CREATE TABLE b15776 select cast(null as binary(4294967295)); +show columns from b15776; +drop table b15776; + +explain select cast(1 as char(4294967295)); +explain select cast(1 as nchar(4294967295)); +explain select cast(1 as binary(4294967295)); + +--error ER_TOO_BIG_DISPLAYWIDTH +explain select cast(1 as char(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select cast(1 as nchar(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select cast(1 as binary(4294967296)); + +--error ER_PARSE_ERROR +explain select cast(1 as decimal(-1)); +explain select cast(1 as decimal(64, 30)); +# It's not as important which errors are raised for these, since the +# limit is nowhere near 3**32. We may fix these eventually to take +# 4294967295 and still reject it because it's greater than 64 or 30, +# but that's not a high priority and the parser needn't worry about +# such a weird case. +--error ER_TOO_BIG_SCALE,ER_PARSE_ERROR +explain select cast(1 as decimal(64, 999999999999999999999999999999)); +--error ER_TOO_BIG_PRECISION,ER_PARSE_ERROR +explain select cast(1 as decimal(4294967296)); +--error ER_TOO_BIG_PRECISION,ER_PARSE_ERROR +explain select cast(1 as decimal(999999999999999999999999999999999999)); + +explain select convert(1, char(4294967295)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, char(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, char(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +explain select convert(1, nchar(4294967295)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, nchar(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, nchar(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); +explain select convert(1, binary(4294967295)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, binary(4294967296)); +--error ER_TOO_BIG_DISPLAYWIDTH +explain select convert(1, binary(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)); + --echo End of 5.0 tests diff --git a/sql/field.cc b/sql/field.cc index 3f74210807b..2950f349580 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8395,8 +8395,20 @@ 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 && !(length= (uint) atoi(fld_length))) - fld_length= 0; /* purecov: inspected */ + if (fld_length != 0) + { + errno= 0; + length= strtoul(fld_length, NULL, 10); + if (errno != 0) + { + 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) { diff --git a/sql/item_create.cc b/sql/item_create.cc index 561613032bc..b7a9a1d7feb 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -464,8 +464,42 @@ Item *create_func_cast(Item *a, Cast_target cast_type, case ITEM_CAST_TIME: res= new Item_time_typecast(a); break; case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break; case ITEM_CAST_DECIMAL: - len= c_len ? atoi(c_len) : 0; - dec= c_dec ? atoi(c_dec) : 0; + if (c_len == NULL) + { + len= 0; + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_len, NULL, 10); + if (errno != 0) + { + my_error(ER_TOO_BIG_PRECISION, MYF(0), c_len, a->name, + DECIMAL_MAX_PRECISION); + return NULL; + } + len= decoded_size; + } + + if (c_dec == NULL) + { + dec= 0; + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_dec, NULL, 10); + if ((errno != 0) || (decoded_size > UINT_MAX)) + { + my_error(ER_TOO_BIG_SCALE, MYF(0), c_dec, a->name, + DECIMAL_MAX_SCALE); + return NULL; + } + dec= decoded_size; + } + my_decimal_trim(&len, &dec); if (len < dec) { @@ -486,8 +520,25 @@ Item *create_func_cast(Item *a, Cast_target cast_type, } res= new Item_decimal_typecast(a, len, dec); break; + case ITEM_CAST_CHAR: - len= c_len ? atoi(c_len) : -1; + if (c_len == NULL) + { + len= LL(-1); + } + else + { + ulong decoded_size; + errno= 0; + decoded_size= strtoul(c_len, NULL, 10); + if (errno != 0) + { + my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH); + return NULL; + } + len= decoded_size; + } + res= new Item_char_typecast(a, len, cs ? cs : current_thd->variables.collation_connection); break; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index a52ffa8216c..80ed9c788cc 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -1771,30 +1771,30 @@ ER_BLOB_USED_AS_KEY 42000 S1009 swe "En BLOB '%-.64s' kan inte vara nyckel med den anvnda tabelltypen" ukr "BLOB '%-.64s' Φ Ц æ" ER_TOO_BIG_FIELDLENGTH 42000 S1009 - cze "P-Bli velk dlka sloupce '%-.64s' (nejvce %d). Pouijte BLOB" - dan "For stor feltlngde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet" - nla "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB" - eng "Column length too big for column '%-.64s' (max = %d); use BLOB or TEXT instead" - jps "column '%-.64s' ,mۂ column ̑傫܂. (ő %d ܂). BLOB ɎgpĂ.", - est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB vljatpi" - fre "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB" - ger "Feldlnge fr Feld '%-.64s' zu gro (maximal %d). BLOB- oder TEXT-Spaltentyp verwenden!" - greek " '%-.64s' (max = %d). BLOB" - hun "A(z) '%-.64s' oszlop tul hosszu. (maximum = %d). Hasznaljon BLOB tipust inkabb." - ita "La colonna '%-.64s' e` troppo grande (max=%d). Utilizza un BLOB." - jpn "column '%-.64s' ,ݤ column 礭¿ޤ. ( %d ޤ). BLOB 򤫤˻ѤƤ." - kor "Į '%-.64s' Į ̰ ʹ ϴ (ִ = %d). ſ BLOB ϼ." - nor "For stor nkkellengde for kolonne '%-.64s' (maks = %d). Bruk BLOB istedenfor" - norwegian-ny "For stor nykkellengde for felt '%-.64s' (maks = %d). Bruk BLOB istadenfor" - pol "Zbyt dua dugo? kolumny '%-.64s' (maks. = %d). W zamian uyj typu BLOB" - por "Comprimento da coluna '%-.64s' grande demais (max = %d); use BLOB em seu lugar" - rum "Lungimea coloanei '%-.64s' este prea lunga (maximum = %d). Foloseste BLOB mai bine" - rus " '%-.64s' ( = %d). BLOB TEXT " - serbian "Previe podataka za kolonu '%-.64s' (maksimum je %d). Upotrebite BLOB polje" - slo "Prli vek dka pre pole '%-.64s' (maximum = %d). Pouite BLOB" - spa "Longitud de columna demasiado grande para la columna '%-.64s' (maximo = %d).Usar BLOB en su lugar" - swe "Fr stor kolumnlngd angiven fr '%-.64s' (max= %d). Anvnd en BLOB instllet" - ukr " '%-.64s' (max = %d). BLOB" + cze "P-Bli velk dlka sloupce '%-.64s' (nejvce %lu). Pouijte BLOB" + dan "For stor feltlngde for kolonne '%-.64s' (maks = %lu). Brug BLOB i stedet" + nla "Te grote kolomlengte voor '%-.64s' (max = %lu). Maak hiervoor gebruik van het type BLOB" + eng "Column length too big for column '%-.64s' (max = %lu); use BLOB or TEXT instead" + jps "column '%-.64s' ,mۂ column ̑傫܂. (ő %lu ܂). BLOB ɎgpĂ.", + est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %lu). Kasuta BLOB vljatpi" + fre "Champ '%-.64s' trop long (max = %lu). Utilisez un BLOB" + ger "Feldlnge fr Feld '%-.64s' zu gro (maximal %lu). BLOB- oder TEXT-Spaltentyp verwenden!" + greek " '%-.64s' (max = %lu). BLOB" + hun "A(z) '%-.64s' oszlop tul hosszu. (maximum = %lu). Hasznaljon BLOB tipust inkabb." + ita "La colonna '%-.64s' e` troppo grande (max=%lu). Utilizza un BLOB." + jpn "column '%-.64s' ,ݤ column 礭¿ޤ. ( %lu ޤ). BLOB 򤫤˻ѤƤ." + kor "Į '%-.64s' Į ̰ ʹ ϴ (ִ = %lu). ſ BLOB ϼ." + nor "For stor nkkellengde for kolonne '%-.64s' (maks = %lu). Bruk BLOB istedenfor" + norwegian-ny "For stor nykkellengde for felt '%-.64s' (maks = %lu). Bruk BLOB istadenfor" + pol "Zbyt dua dugo? kolumny '%-.64s' (maks. = %lu). W zamian uyj typu BLOB" + por "Comprimento da coluna '%-.64s' grande demais (max = %lu); use BLOB em seu lugar" + rum "Lungimea coloanei '%-.64s' este prea lunga (maximum = %lu). Foloseste BLOB mai bine" + rus " '%-.64s' ( = %lu). BLOB TEXT " + serbian "Previe podataka za kolonu '%-.64s' (maksimum je %lu). Upotrebite BLOB polje" + slo "Prli vek dka pre pole '%-.64s' (maximum = %lu). Pouite BLOB" + spa "Longitud de columna demasiado grande para la columna '%-.64s' (maximo = %lu).Usar BLOB en su lugar" + swe "Fr stor kolumnlngd angiven fr '%-.64s' (max= %lu). Anvnd en BLOB instllet" + ukr " '%-.64s' (max = %lu). BLOB" ER_WRONG_AUTO_KEY 42000 S1009 cze "M-Bete mt pouze jedno AUTO pole a to mus bt definovno jako kl" dan "Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal vre indekseret" @@ -5508,11 +5508,11 @@ ER_SP_NO_RECURSION eng "Recursive stored functions and triggers are not allowed." ger "Rekursive gespeicherte Routinen und Triggers sind nicht erlaubt" ER_TOO_BIG_SCALE 42000 S1009 - eng "Too big scale %d specified for column '%-.64s'. Maximum is %d." - ger "Zu groer Skalierungsfaktor %d fr Feld '%-.64s' angegeben. Maximum ist %d" + eng "Too big scale %lu specified for column '%-.64s'. Maximum is %d." + ger "Zu groer Skalierungsfaktor %lu fr Feld '%-.64s' angegeben. Maximum ist %d" ER_TOO_BIG_PRECISION 42000 S1009 - eng "Too big precision %d specified for column '%-.64s'. Maximum is %d." - ger "Zu groe Genauigkeit %d fr Feld '%-.64s' angegeben. Maximum ist %d" + eng "Too big precision %lu specified for column '%-.64s'. Maximum is %lu." + ger "Zu groe Genauigkeit %lu fr Feld '%-.64s' angegeben. Maximum ist %lu" ER_M_BIGGER_THAN_D 42000 S1009 eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')." ger "Fr FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.64s')" @@ -5550,8 +5550,8 @@ ER_WARN_CANT_DROP_DEFAULT_KEYCACHE eng "Cannot drop default keycache" ger "Der vorgabemige Schlssel-Cache kann nicht gelscht werden" ER_TOO_BIG_DISPLAYWIDTH 42000 S1009 - eng "Display width out of range for column '%-.64s' (max = %d)" - ger "Anzeigebreite auerhalb des zulssigen Bereichs fr Spalte '%-.64s' (Maximum: %d)" + eng "Display width out of range for column '%-.64s' (max = %lu)" + ger "Anzeigebreite auerhalb des zulssigen Bereichs fr Spalte '%-.64s' (Maximum: %lu)" ER_XAER_DUPID XAE08 eng "XAER_DUPID: The XID already exists" ger "XAER_DUPID: Die XID existiert bereits" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 638da3b1bb0..c270e005454 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1171,7 +1171,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); single_multi table_wild_list table_wild_one opt_wild union_clause union_list precision subselect_start opt_and charset - subselect_end select_var_list select_var_list_init help opt_len + subselect_end select_var_list select_var_list_init help opt_field_length field_length opt_extended_describe prepare prepare_src execute deallocate statement sp_suid @@ -3010,7 +3010,7 @@ udf_type: field_list: field_list_item - | field_list ',' field_list_item; + | field_list ',' field_list_item; /* FIXME: Should this be backward? */ field_list_item: @@ -3111,45 +3111,38 @@ field_spec: }; type: - int_type opt_len field_options { $$=$1; } + int_type opt_field_length field_options { $$=$1; } | real_type opt_precision field_options { $$=$1; } | FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; } | BIT_SYM { Lex->length= (char*) "1"; $$=FIELD_TYPE_BIT; } - | BIT_SYM '(' NUM ')' { Lex->length= $3.str; - $$=FIELD_TYPE_BIT; } + | BIT_SYM field_length { $$=FIELD_TYPE_BIT; } | BOOL_SYM { Lex->length=(char*) "1"; $$=FIELD_TYPE_TINY; } | BOOLEAN_SYM { Lex->length=(char*) "1"; $$=FIELD_TYPE_TINY; } - | char '(' NUM ')' opt_binary { Lex->length=$3.str; - $$=FIELD_TYPE_STRING; } + | char field_length opt_binary { $$=FIELD_TYPE_STRING; } | char opt_binary { Lex->length=(char*) "1"; $$=FIELD_TYPE_STRING; } - | nchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; - $$=FIELD_TYPE_STRING; + | nchar field_length opt_bin_mod { $$=FIELD_TYPE_STRING; Lex->charset=national_charset_info; } | nchar opt_bin_mod { Lex->length=(char*) "1"; $$=FIELD_TYPE_STRING; Lex->charset=national_charset_info; } - | BINARY '(' NUM ')' { Lex->length=$3.str; - Lex->charset=&my_charset_bin; + | BINARY field_length { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_STRING; } | BINARY { Lex->length= (char*) "1"; Lex->charset=&my_charset_bin; $$=FIELD_TYPE_STRING; } - | varchar '(' NUM ')' opt_binary { Lex->length=$3.str; - $$= MYSQL_TYPE_VARCHAR; } - | nvarchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; - $$= MYSQL_TYPE_VARCHAR; + | varchar field_length opt_binary { $$= MYSQL_TYPE_VARCHAR; } + | nvarchar field_length opt_bin_mod { $$= MYSQL_TYPE_VARCHAR; Lex->charset=national_charset_info; } - | VARBINARY '(' NUM ')' { Lex->length=$3.str; - Lex->charset=&my_charset_bin; + | VARBINARY field_length { Lex->charset=&my_charset_bin; $$= MYSQL_TYPE_VARCHAR; } - | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } + | YEAR_SYM opt_field_length field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP opt_len + | TIMESTAMP opt_field_length { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -3165,7 +3158,7 @@ type: | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } - | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; + | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_BLOB; } | spatial_type { @@ -3187,7 +3180,7 @@ type: $$=FIELD_TYPE_MEDIUM_BLOB; } | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; } - | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; } + | TEXT_SYM opt_field_length opt_binary { $$=FIELD_TYPE_BLOB; } | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; } | DECIMAL_SYM float_options field_options @@ -3260,7 +3253,7 @@ real_type: float_options: /* empty */ { Lex->dec=Lex->length= (char*)0; } - | '(' NUM ')' { Lex->length=$2.str; Lex->dec= (char*)0; } + | field_length { Lex->dec= (char*)0; } | precision {}; precision: @@ -3283,9 +3276,15 @@ field_option: | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; -opt_len: - /* empty */ { Lex->length=(char*) 0; } /* use default length */ - | '(' NUM ')' { Lex->length= $2.str; }; +opt_field_length: + /* empty */ { Lex->length=(char*) NULL; } /* use default length */ + | field_length {}; + +field_length: + '(' LONG_NUM ')' { Lex->length= $2.str; } + | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; } + | '(' DECIMAL_NUM ')' { Lex->length= $2.str; } + | '(' NUM ')' { Lex->length= $2.str; }; opt_precision: /* empty */ {} @@ -5466,9 +5465,9 @@ in_sum_expr: }; cast_type: - BINARY opt_len { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } - | CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; Lex->dec= 0; } - | NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } + BINARY opt_field_length { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } + | CHAR_SYM opt_field_length opt_binary { $$=ITEM_CAST_CHAR; Lex->dec= 0; } + | NCHAR_SYM opt_field_length { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } diff --git a/sql/unireg.h b/sql/unireg.h index 81ca18c1d32..0ab2a40048b 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -60,6 +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 CONVERT_IF_BIGGER_TO_BLOB 512 /* Used for CREATE ... SELECT */ /* Max column width +1 */ From 73e1c5ae10994373df5d929974be02edffae70e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Mar 2008 14:52:10 -0400 Subject: [PATCH 2/4] Fix minor complaints of Marc Alff, for patch against B-g#15776. mysql-test/t/type_blob.test: Drop table in case we start from a bad state. sql/sql_yacc.yy: yacc/bison is left-recursive, so FIXME statement is wrong. --- mysql-test/t/type_blob.test | 5 ++++- sql/sql_yacc.yy | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 097c749f977..ad578a18979 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -449,6 +449,9 @@ set @@sql_mode=''; # raise ER_TOO_BIG_DISPLAYWIDTH # BLOB and TEXT types +--disable_warnings +drop table if exists b15776; +--enable_warnings create table b15776 (data blob(2147483647)); drop table b15776; --error ER_PARSE_ERROR @@ -570,7 +573,7 @@ explain select cast(1 as binary(4294967296)); explain select cast(1 as decimal(-1)); explain select cast(1 as decimal(64, 30)); # It's not as important which errors are raised for these, since the -# limit is nowhere near 3**32. We may fix these eventually to take +# limit is nowhere near 2**32. We may fix these eventually to take # 4294967295 and still reject it because it's greater than 64 or 30, # but that's not a high priority and the parser needn't worry about # such a weird case. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c270e005454..d47e6679269 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3010,7 +3010,7 @@ udf_type: field_list: field_list_item - | field_list ',' field_list_item; /* FIXME: Should this be backward? */ + | field_list ',' field_list_item; field_list_item: From a9e658408fd40ed9485654539b334b92272361c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Apr 2008 12:26:12 -0400 Subject: [PATCH 3/4] Test updated. --- mysql-test/r/type_blob.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 599a2224472..84f2d815bdd 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -807,6 +807,7 @@ set @@sql_mode='TRADITIONAL'; create table t1 (a text default ''); ERROR 42000: BLOB/TEXT column 'a' can't have a default value set @@sql_mode=''; +drop table if exists b15776; create table b15776 (data blob(2147483647)); drop table b15776; create table b15776 (data blob(-1)); From 2bc7179d2d0019fd2b4666de0990faf3f19b9582 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Apr 2008 12:27:30 -0400 Subject: [PATCH 4/4] Follow-up to B-g#15776, test failures on 64-bit linux. Make maximum blob size to be 2**32-1, regardless of word size. Fix failure of timestamp with size of 2**31-1. The method of rounding up to the nearest even number would overflow. mysql-test/r/type_blob.result: 2**32-1 is not a special case for timestamp. Test 2**32-1 and 2**64 as the reliable test points for both 32- and 64-bit machines. I'd like to test 2**32, but that would make tests that vary between architectures. I'd like to generalize the tests by pulling the max blob size from the server, and then "eval"ing N-1, N, and N+1 instead of all these literal numbers, but I have not found a way to get UINT_MAX. mysql-test/t/type_blob.test: 2**32-1 is not a special case for timestamp. Test 2**32-1 and 2**64 as the reliable test points for both 32- and 64-bit machines. I'd like to test 2**32, but that would make tests that vary between architectures. I'd like to generalize the tests by pulling the max blob size from the server, and then "eval"ing N-1, N, and N+1 instead of all these literal numbers, but I have not found a way to get UINT_MAX. sql/field.cc: Fix a bug where the round-to-even code for TIMESTAMP fields failed where the size would overflow the size to zero and then fail. Also, since we silently truncate the size of TIMESTAMP fields, set the maximum size we report is allowable to be the largest parsable number. sql/unireg.h: Make BLOB size the maximum that the packed value in field_blob::get_length() allows. --- mysql-test/r/type_blob.result | 6 +++++- mysql-test/t/type_blob.test | 4 +++- sql/field.cc | 24 +++++++++++++++++------- sql/unireg.h | 2 +- 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 */