Hi Chad and Martin
The patch is ok to push, in 5.0 and up, with minor changes listed below.
Chad:
When merging the code of sql_yacc.yy to 5.1 and 6.0,
please make sure to format the code as documented in sql_yacc.yy (see
'Indentation of grammar rules').
This is a very good parser fix, with equally good test coverage.
Thanks,
Marc
Chad MILLER wrote:
> Below is the list of changes that have just been committed into a local
> 5.0 repository of cmiller. When cmiller does a push these changes will
> be propagated to the main repository and, within 24 hours after the
> push, to the public repository.
> For information on how to access the public repository
> see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
>
> ChangeSet@stripped, 2007-08-31 15:24:43-04:00, cmiller@stripped +7 -0
> Bug#15776: 32-bit signed int used for length of blob
>
> Based on contributed patch from Martin Friebe, CLA from 2007-02-24.
>
Thanks
>
> 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@stripped, 2007-08-31 15:24:41-04:00,
> cmiller@stripped +147 -0
> 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@stripped, 2007-08-31 15:24:41-04:00,
> cmiller@stripped +161 -0
> Verify that blobs may be created with the size that is already
> documented.
>
> Additionally, test the limits of several other types.
>
> sql/field.cc@stripped, 2007-08-31 15:24:41-04:00, cmiller@stripped +14 -2
> atoi() insufficient to gauge the length of some fields. Change
> it to strtoul().
>
> sql/item_create.cc@stripped, 2007-08-31 15:24:41-04:00, cmiller@stripped +54
> -3
> 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@stripped, 2007-08-31 15:24:41-04:00, cmiller@stripped
> +30 -30
> Change ER_TOO_BIG_FIELDLENGTH so that it can accept sizes larger
> than 2**15 -- instead, 2**32.
>
> sql/sql_yacc.yy@stripped, 2007-08-31 15:24:41-04:00, cmiller@stripped +27
> -28
> Make lengths take, in addition to NUM, LONG_NUM, ULONGLONG_NUM,
> and DECIMAL_NUM.
>
> sql/unireg.h@stripped, 2007-08-31 15:24:41-04:00, cmiller@stripped +1 -0
> Define new constant.
>
>
(...)
> --- a/mysql-test/t/type_blob.test 2007-02-14 08:44:31 -05:00
> +++ b/mysql-test/t/type_blob.test 2007-08-31 15:24:41 -04:00
> @@ -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
>
Insert the following script here:
--disable_warnings
drop table if exists b15776;
--enable_warnings
in case the test is executed again from a not-so-clean state.
> +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
>
Make that 2**32
> +# 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
>
In case the code can return 2 errors, in a hard to predict way (timing
issues, etc),
we use the syntax:
-- error ER_XXX, ER_YYY
In case the implementation systematically returns the same error,
but 2 different errors are acceptable, my preference is to use the comments
to describe the 2 errors, and only use the following syntax:
-- error ER_XXX
This is just a minor remark, no change required.
> +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 -Nrup a/sql/field.cc b/sql/field.cc
> --- a/sql/field.cc 2007-07-25 18:28:50 -04:00
> +++ b/sql/field.cc 2007-08-31 15:24:41 -04:00
> @@ -8395,8 +8395,20 @@ bool create_field::init(THD *thd, char *
> (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 -Nrup a/sql/item_create.cc b/sql/item_create.cc
> --- a/sql/item_create.cc 2007-08-02 05:51:00 -04:00
> +++ b/sql/item_create.cc 2007-08-31 15:24:41 -04:00
> @@ -464,8 +464,42 @@ Item *create_func_cast(Item *a, Cast_tar
> 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_tar
> }
> 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 -Nrup a/sql/share/errmsg.txt b/sql/share/errmsg.txt
> --- a/sql/share/errmsg.txt 2007-06-05 19:42:39 -04:00
> +++ b/sql/share/errmsg.txt 2007-08-31 15:24:41 -04:00
>
(...)
> diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
> --- a/sql/sql_yacc.yy 2007-08-01 20:39:11 -04:00
> +++ b/sql/sql_yacc.yy 2007-08-31 15:24:41 -04:00
> @@ -1171,7 +1171,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
> 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? */
>
The parser uses bison, and is an ascendant parser,
so lists are *left* recursive, the original code is correct.
Remove the FIXME comment.
>
>
> 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 -Nrup a/sql/unireg.h b/sql/unireg.h
> --- a/sql/unireg.h 2007-07-05 06:34:11 -04:00
> +++ b/sql/unireg.h 2007-08-31 15:24:41 -04:00
> @@ -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 */
>
>