diff --git a/acinclude.m4 b/acinclude.m4 index 8a55c1fdb2009cafbbf52fd0acceef149efb439b..c8cad48ff0b877c8eb257595489e73ea36c270c4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -311,8 +311,9 @@ case $SYSTEM_TYPE in ;; *) # Just to be safe, we test for ".so" anyway + eval shrexts=\"$shrext_cmds\" if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \ - -f "$mysql_zlib_dir/lib/libz$shrext_cmds" \) \ + -f "$mysql_zlib_dir/lib/libz$shrexts" \) \ -a -f "$mysql_zlib_dir/include/zlib.h"; then ZLIB_INCLUDES="-I$mysql_zlib_dir/include" ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz" @@ -967,6 +968,7 @@ AC_DEFUN([MYSQL_CHECK_VIO], [ AC_DEFUN([MYSQL_FIND_OPENSSL], [ incs="$1" libs="$2" + eval shrexts=\"$shrext_cmds\" case "$incs---$libs" in ---) for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ @@ -981,7 +983,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \ /usr/freeware/lib32 /usr/local/lib/ ; do # Just to be safe, we test for ".so" anyway - if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext_cmds ; then + if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrexts ; then OPENSSL_LIB=$d fi done @@ -994,7 +996,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ OPENSSL_INCLUDE=-I$incs fi # Just to be safe, we test for ".so" anyway - if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext_cmds ; then + if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f "$libs/libssl$shrexts" ; then OPENSSL_LIB=$libs fi ;; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 3e233eb512af7b3814fc75a010aa9670874074a9..4d90aac0e68ee044e2e6446c2ce120a0b7c63abc 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -269,3 +269,45 @@ field('str1', null, 'STR1') as c05, c01 c02 c03 c04 c05 c08 c09 str str 0 1 2 1 1 set names latin1; +create table bug19145a (e enum('a','b','c') default 'b' , s set('x', 'y', 'z') default 'y' ) engine=MyISAM; +create table bug19145b (e enum('a','b','c') default null, s set('x', 'y', 'z') default null) engine=MyISAM; +create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM; +create table bug19145setnotnulldefaultnull (e enum('a','b','c') default null, s set('x', 'y', 'z') not null default null) engine=MyISAM; +ERROR 42000: Invalid default value for 's' +create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z') default null) engine=MyISAM; +ERROR 42000: Invalid default value for 'e' +alter table bug19145a alter column e set default null; +alter table bug19145a alter column s set default null; +alter table bug19145a add column (i int); +alter table bug19145b alter column e set default null; +alter table bug19145b alter column s set default null; +alter table bug19145b add column (i int); +alter table bug19145c alter column e set default null; +ERROR 42000: Invalid default value for 'e' +alter table bug19145c alter column s set default null; +ERROR 42000: Invalid default value for 's' +alter table bug19145c add column (i int); +show create table bug19145a; +Table Create Table +bug19145a CREATE TABLE `bug19145a` ( + `e` enum('a','b','c') default NULL, + `s` set('x','y','z') default NULL, + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table bug19145b; +Table Create Table +bug19145b CREATE TABLE `bug19145b` ( + `e` enum('a','b','c') default NULL, + `s` set('x','y','z') default NULL, + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table bug19145c; +Table Create Table +bug19145c CREATE TABLE `bug19145c` ( + `e` enum('a','b','c') NOT NULL default 'b', + `s` set('x','y','z') NOT NULL default 'y', + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table bug19145a; +drop table bug19145b; +drop table bug19145c; diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 731f0a4cb34244257385f6cb4383ece3bdbf908d..b405b8fb852e2259fee3ba6957289c9b4e3fd730 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -187,4 +187,45 @@ select # Restore charset to the default value. set names latin1; +# +# Bug#19145: mysqld crashes if you set the default value of an enum field to NULL +# +create table bug19145a (e enum('a','b','c') default 'b' , s set('x', 'y', 'z') default 'y' ) engine=MyISAM; +create table bug19145b (e enum('a','b','c') default null, s set('x', 'y', 'z') default null) engine=MyISAM; + +create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM; + +# Invalid default value for 's' +--error 1067 +create table bug19145setnotnulldefaultnull (e enum('a','b','c') default null, s set('x', 'y', 'z') not null default null) engine=MyISAM; + +# Invalid default value for 'e' +--error 1067 +create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z') default null) engine=MyISAM; + +alter table bug19145a alter column e set default null; +alter table bug19145a alter column s set default null; +alter table bug19145a add column (i int); + +alter table bug19145b alter column e set default null; +alter table bug19145b alter column s set default null; +alter table bug19145b add column (i int); + +# Invalid default value for 'e' +--error 1067 +alter table bug19145c alter column e set default null; + +# Invalid default value for 's' +--error 1067 +alter table bug19145c alter column s set default null; +alter table bug19145c add column (i int); + +show create table bug19145a; +show create table bug19145b; +show create table bug19145c; + +drop table bug19145a; +drop table bug19145b; +drop table bug19145c; + # End of 4.1 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c9513ec71abdb2090f582e1c289a9598ee547497..0454cadc774f5128109ca40cac2dfe1832106047 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -601,7 +601,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (need_to_change_arena) thd->restore_backup_item_arena(thd->current_arena, &backup_arena); - if (! sql_field->def) + if (sql_field->def == NULL) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -611,15 +611,30 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (sql_field->sql_type == FIELD_TYPE_SET) { - if (sql_field->def) + if (sql_field->def != NULL) { char *not_used; uint not_used2; bool not_found= 0; String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - (void) find_set(interval, def->ptr(), def->length(), - cs, ¬_used, ¬_used2, ¬_found); + if (def == NULL) /* SQL "NULL" maps to NULL */ + { + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, NULL is an allowed value */ + (void) find_set(interval, NULL, 0, + cs, ¬_used, ¬_used2, ¬_found); + } + else /* not NULL */ + { + (void) find_set(interval, def->ptr(), def->length(), + cs, ¬_used, ¬_used2, ¬_found); + } + if (not_found) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -631,14 +646,28 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } else /* FIELD_TYPE_ENUM */ { - if (sql_field->def) + DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM); + if (sql_field->def != NULL) { String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - if (!find_type2(interval, def->ptr(), def->length(), cs)) + if (def == NULL) /* SQL "NULL" maps to NULL */ { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, the defaults yield the correct length for NULLs. */ + } + else /* not NULL */ + { + def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); + if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } } } calculate_interval_lengths(cs, interval, &sql_field->length, &dummy);