MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:April 27 2006 3:32am
Subject:bk commit into 4.1 tree (cmiller:1.2466) BUG#19145
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 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
  1.2466 06/04/26 23:32:12 cmiller@zippy.(none) +3 -0
  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.

  sql/sql_table.cc
    1.308 06/04/26 23:32:09 cmiller@zippy.(none) +34 -7
    No longer blindly dereference a pointer of the string representation of the 
    value, where "NULL" is NULL.  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.

  mysql-test/t/null.test
    1.16 06/04/26 23:32:09 cmiller@zippy.(none) +47 -0
    Add test case.

  mysql-test/r/null.result
    1.27 06/04/26 23:32:09 cmiller@zippy.(none) +42 -0
    Add test case.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.(none)
# Root:	/home/cmiller/work/mysql/mysql-4.1__bug19145

--- 1.307/sql/sql_table.cc	2006-03-30 01:22:02 -05:00
+++ 1.308/sql/sql_table.cc	2006-04-26 23:32:09 -04:00
@@ -617,9 +617,22 @@
           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) {
+            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 +644,28 @@
       }
       else  /* FIELD_TYPE_ENUM */
       {
+        DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM);
         if (sql_field->def)
         {
           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))
+          DBUG_PRINT("info", ("mysql_prepare_table() enum sql_field-def is 0x%x", def));
+          if (def == 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);

--- 1.26/mysql-test/r/null.result	2004-11-10 05:05:22 -05:00
+++ 1.27/mysql-test/r/null.result	2006-04-26 23:32:09 -04:00
@@ -269,3 +269,45 @@
 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;

--- 1.15/mysql-test/t/null.test	2005-07-27 20:21:45 -04:00
+++ 1.16/mysql-test/t/null.test	2006-04-26 23:32:09 -04:00
@@ -187,4 +187,51 @@
 # 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
+#
+--exec sleep 20
+#create table bug19145 (e enum('a','b','c'), s set('x', 'y', 'z')) engine=MyISAM;
+#show create table bug19145;
+#drop table bug19145;
+
+
+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
Thread
bk commit into 4.1 tree (cmiller:1.2466) BUG#19145Chad MILLER27 Apr