mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Setting a variable to CAST(NULL as X) set the result type of the variable to X. (Bug #6598)
mysql-test/r/bigint.result: Test to show show that the parser threats big longlong values as unsigned mysql-test/r/user_var.result: Test of CAST(NULL as SIGNED/UNSIGNED) mysql-test/t/bigint.test: Test to show show that the parser threats big longlong values as unsigned mysql-test/t/user_var.test: Test of CAST(NULL as SIGNED/UNSIGNED) sql/item_func.cc: Setting a variable to CAST(NULL as X) set the result type of the variable to X. (Bug #6598) Setting a variable to NULL doesn't change the old result type. sql/item_func.h: Detect setting a variable to NULL sql/unireg.cc: Safety fix
This commit is contained in:
@ -128,3 +128,20 @@ t2.value64=t1.value64;
|
|||||||
value64 value32 value64 value32
|
value64 value32 value64 value32
|
||||||
9223372036854775807 2 9223372036854775807 4
|
9223372036854775807 2 9223372036854775807 4
|
||||||
drop table t1, t2;
|
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;
|
||||||
|
@ -182,3 +182,44 @@ coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
|
|||||||
set session @honk=99;
|
set session @honk=99;
|
||||||
set one_shot @honk=99;
|
set one_shot @honk=99;
|
||||||
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
|
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;
|
||||||
|
@ -104,3 +104,13 @@ t2.value64=t1.value64;
|
|||||||
|
|
||||||
drop table t1, t2;
|
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;
|
||||||
|
@ -119,3 +119,29 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
|
|||||||
set session @honk=99;
|
set session @honk=99;
|
||||||
--error 1382
|
--error 1382
|
||||||
set one_shot @honk=99;
|
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;
|
||||||
|
@ -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
|
from the argument if the argument is NULL
|
||||||
and the variable has previously been initialized.
|
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);
|
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
|
||||||
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
|
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
|
||||||
cached_result_type= args[0]->result_type();
|
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));
|
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
|
||||||
if (entry->value && entry->value != pos)
|
if (entry->value && entry->value != pos)
|
||||||
my_free(entry->value,MYF(0));
|
my_free(entry->value,MYF(0));
|
||||||
entry->value=0;
|
entry->value= 0;
|
||||||
entry->length=0;
|
entry->length= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3355,9 +3356,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
|||||||
if (type == DECIMAL_RESULT)
|
if (type == DECIMAL_RESULT)
|
||||||
((my_decimal*)entry->value)->fix_buffer_pointer();
|
((my_decimal*)entry->value)->fix_buffer_pointer();
|
||||||
entry->length= length;
|
entry->length= length;
|
||||||
entry->type=type;
|
|
||||||
entry->collation.set(cs, dv);
|
entry->collation.set(cs, dv);
|
||||||
}
|
}
|
||||||
|
entry->type=type;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3366,6 +3367,12 @@ bool
|
|||||||
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
|
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
|
||||||
CHARSET_INFO *cs, Derivation dv)
|
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),
|
if (::update_hash(entry, (null_value= args[0]->null_value),
|
||||||
ptr, length, type, cs, dv))
|
ptr, length, type, cs, dv))
|
||||||
{
|
{
|
||||||
|
@ -1071,6 +1071,7 @@ class Item_func_set_user_var :public Item_func
|
|||||||
char buffer[MAX_FIELD_WIDTH];
|
char buffer[MAX_FIELD_WIDTH];
|
||||||
String value;
|
String value;
|
||||||
my_decimal decimal_buff;
|
my_decimal decimal_buff;
|
||||||
|
bool null_item;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
longlong vint;
|
longlong vint;
|
||||||
|
@ -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
|
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
|
||||||
while ((field=it++))
|
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,
|
Field *regfield=make_field((char*) buff+field->offset,field->length,
|
||||||
null_pos,
|
null_pos,
|
||||||
null_count & 7,
|
null_count & 7,
|
||||||
@ -696,7 +699,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
|
|||||||
field->interval,
|
field->interval,
|
||||||
field->field_name,
|
field->field_name,
|
||||||
&table);
|
&table);
|
||||||
DBUG_ASSERT(regfield);
|
if (!regfield)
|
||||||
|
goto err; // End of memory
|
||||||
|
|
||||||
if (!(field->flags & NOT_NULL_FLAG))
|
if (!(field->flags & NOT_NULL_FLAG))
|
||||||
null_count++;
|
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);
|
regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),system_charset_info);
|
||||||
else
|
else
|
||||||
regfield->reset();
|
regfield->reset();
|
||||||
delete regfield;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill not used startpos */
|
/* Fill not used startpos */
|
||||||
|
Reference in New Issue
Block a user