diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index e372c307ba781e3a53fe8a2a12963bf08021e6c2..a0c8f317db2c5cde1d7a7441990d524bc04e39dd 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -128,3 +128,20 @@ t2.value64=t1.value64;
 value64	value32	value64	value32
 9223372036854775807	2	9223372036854775807	4
 drop table t1, t2;
+create table t1 select 1 as 'a';
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` bigint(1) NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 select 9223372036854775809 as 'a';
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` bigint(19) unsigned NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t1;
+a
+9223372036854775809
+drop table t1;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 68eae1111110559282c5ffee54d7442d065609eb..d9a647ce2c3505ecf1453f61fe84ec45c4ea3132 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -182,3 +182,44 @@ coercibility(@v1)	coercibility(@v2)	coercibility(@v3)	coercibility(@v4)
 set session @honk=99;
 set one_shot @honk=99;
 ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
+set @first_var= NULL;
+create table t1 select @first_var;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `@first_var` longblob
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set @first_var= cast(NULL as signed integer);
+create table t1 select @first_var;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `@first_var` bigint(20) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set @first_var= NULL;
+create table t1 select @first_var;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `@first_var` bigint(20) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set @first_var= concat(NULL);
+create table t1 select @first_var;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `@first_var` longblob
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set @first_var=1;
+set @first_var= cast(NULL as CHAR);
+create table t1 select @first_var;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `@first_var` longtext
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index a26b78254e74501bcf66beb2d0555e8bde7f8a37..99c8a13d0b56e2db4c37337e07ec551005768f1a 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -104,3 +104,13 @@ t2.value64=t1.value64;
 
 drop table t1, t2;
 
+#
+# Test of CREATE ... SELECT and unsigned integers
+#
+create table t1 select 1 as 'a';
+show create table t1;
+drop table t1;
+create table t1 select 9223372036854775809 as 'a';
+show create table t1;
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index ef360f2231d294c1f4dd4a891f1881c8d6dff324..b9d06558f34b9d7e23eb5fd060a8a56d2ec1e4f7 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -119,3 +119,29 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
 set session @honk=99;
 --error 1382
 set one_shot @honk=99;
+
+#
+# Bug #6598: problem with cast(NULL as signed integer);
+#
+
+set @first_var= NULL;
+create table t1 select @first_var;
+show create table t1;
+drop table t1;
+set @first_var= cast(NULL as signed integer);
+create table t1 select @first_var;
+show create table t1;
+drop table t1;
+set @first_var= NULL;
+create table t1 select @first_var;
+show create table t1;
+drop table t1;
+set @first_var= concat(NULL);
+create table t1 select @first_var;
+show create table t1;
+drop table t1;
+set @first_var=1;
+set @first_var= cast(NULL as CHAR);
+create table t1 select @first_var;
+show create table t1;
+drop table t1;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index fb21551e22f882c0af1578dcdb1443116d17d2b4..6075f1f6bc3ba8b726ced54f61298e7a3f9dd426 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3271,7 +3271,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
     from the argument if the argument is NULL
     and the variable has previously been initialized.
   */
-  if (!entry->collation.collation || !args[0]->null_value)
+  null_item= (args[0]->type() == NULL_ITEM);
+  if (!entry->collation.collation || !null_item)
     entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
   collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
   cached_result_type= args[0]->result_type();
@@ -3315,8 +3316,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
     char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
     if (entry->value && entry->value != pos)
       my_free(entry->value,MYF(0));
-    entry->value=0;
-    entry->length=0;
+    entry->value= 0;
+    entry->length= 0;
   }
   else
   {
@@ -3355,9 +3356,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
     if (type == DECIMAL_RESULT)
       ((my_decimal*)entry->value)->fix_buffer_pointer();
     entry->length= length;
-    entry->type=type;
     entry->collation.set(cs, dv);
   }
+  entry->type=type;
   return 0;
 }
 
@@ -3366,6 +3367,12 @@ bool
 Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
                                     CHARSET_INFO *cs, Derivation dv)
 {
+  /*
+    If we set a variable explicitely to NULL then keep the old
+    result type of the variable
+  */
+  if ((null_value= args[0]->null_value) && null_item)
+    type= entry->type;                          // Don't change type of item
   if (::update_hash(entry, (null_value= args[0]->null_value),
                     ptr, length, type, cs, dv))
   {
diff --git a/sql/item_func.h b/sql/item_func.h
index 77b977fe7786fc11c6a16cf38acf5242309aa468..3f45cad7dc3c0ac4a0b40498fb36a5f32f9d45ee 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1071,6 +1071,7 @@ class Item_func_set_user_var :public Item_func
   char buffer[MAX_FIELD_WIDTH];
   String value;
   my_decimal decimal_buff;
+  bool null_item;
   union
   {
     longlong vint;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 929ca5c672e3055a53cc8edcb16ef932d34d3e48..95a383e0f01e564c7f09dc36f3d2a5d2272d2e6f 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -685,6 +685,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
   thd->count_cuted_fields= CHECK_FIELD_WARN;    // To find wrong default values
   while ((field=it++))
   {
+    /*
+      regfield don't have to be deleted as it's allocated with sql_alloc()
+    */
     Field *regfield=make_field((char*) buff+field->offset,field->length,
                                null_pos,
 			       null_count & 7,
@@ -696,7 +699,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
 			       field->interval,
 			       field->field_name,
 			       &table);
-    DBUG_ASSERT(regfield);
+    if (!regfield)
+      goto err;                                 // End of memory
 
     if (!(field->flags & NOT_NULL_FLAG))
       null_count++;
@@ -730,7 +734,6 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
       regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),system_charset_info);
     else
       regfield->reset();
-    delete regfield;
   }
 
   /* Fill not used startpos */