diff options
-rw-r--r-- | mysql-test/r/bigint.result | 17 | ||||
-rw-r--r-- | mysql-test/r/user_var.result | 41 | ||||
-rw-r--r-- | mysql-test/t/bigint.test | 10 | ||||
-rw-r--r-- | mysql-test/t/user_var.test | 26 | ||||
-rw-r--r-- | sql/item_func.cc | 15 | ||||
-rw-r--r-- | sql/item_func.h | 1 | ||||
-rw-r--r-- | sql/unireg.cc | 7 |
7 files changed, 111 insertions, 6 deletions
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index e372c307ba7..a0c8f317db2 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 68eae111111..d9a647ce2c3 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 a26b78254e7..99c8a13d0b5 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 ef360f2231d..b9d06558f34 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 fb21551e22f..6075f1f6bc3 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 77b977fe778..3f45cad7dc3 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 929ca5c672e..95a383e0f01 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 */ |