diff options
-rw-r--r-- | mysql-test/r/null.result | 42 | ||||
-rw-r--r-- | mysql-test/t/null.test | 41 | ||||
-rw-r--r-- | sql/sql_table.cc | 49 |
3 files changed, 122 insertions, 10 deletions
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 3e233eb512a..4d90aac0e68 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 731f0a4cb34..b405b8fb852 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 c9513ec71ab..0454cadc774 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); |