1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-27 13:04:36 +03:00

BUG#19145: mysqld crashes if you set the default value of an enum field to NULL

Now test for NULLness the pointers returned from objects created from the
default value. Pushing patch on behalf of cmiller.


mysql-test/r/null.result:
  Add test case
mysql-test/t/null.test:
  Add test case
sql/sql_table.cc:
  No longer blindly dereference pointer of the string representation of the
  values, where "NULL" is NUL. Raise INVALID DEFAULT error messages where
  appropriate.
  
  Note that the -O1 optimization flag made debugging this extremely tricky, with
  misleading results, and that removing it from the Makefile during debugging can
  be invaluable.
This commit is contained in:
unknown
2006-04-28 12:15:29 -04:00
parent e92e1dace7
commit dd68976a24
3 changed files with 122 additions and 10 deletions

View File

@@ -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, &not_used, &not_used2, &not_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, &not_used, &not_used2, &not_found);
}
else /* not NULL */
{
(void) find_set(interval, def->ptr(), def->length(),
cs, &not_used, &not_used2, &not_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);