postmerge 4.1->5.0 fixes
This commit is contained in:
parent
05d4ed14e4
commit
1029e533df
@ -696,7 +696,7 @@ from t1 x3, t1 x4, t1 C, t1 D where x3.a < 3 and x4.a < 4 and D.a < 4;
|
|||||||
delete from t2 where a = 2 and b = 'val-2' limit 30;
|
delete from t2 where a = 2 and b = 'val-2' limit 30;
|
||||||
explain select c from t2 where a = 2 and b = 'val-2' group by c;
|
explain select c from t2 where a = 2 and b = 'val-2' group by c;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t2 ref PRIMARY,a PRIMARY 400 const,const 6 Using where
|
1 SIMPLE t2 ref PRIMARY,a PRIMARY 402 const,const 6 Using where
|
||||||
select c from t2 where a = 2 and b = 'val-2' group by c;
|
select c from t2 where a = 2 and b = 'val-2' group by c;
|
||||||
c
|
c
|
||||||
val-74
|
val-74
|
||||||
|
@ -565,7 +565,7 @@ a
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` decimal(20,1) NOT NULL default '0.0'
|
`a` decimal(19,1) NOT NULL default '0.0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t2 (it1 tinyint, it2 tinyint not null, i int not null, ib bigint, f float, d double, y year, da date, dt datetime, sc char(10), sv varchar(10), b blob, tx text);
|
create table t2 (it1 tinyint, it2 tinyint not null, i int not null, ib bigint, f float, d double, y year, da date, dt datetime, sc char(10), sv varchar(10), b blob, tx text);
|
||||||
@ -1226,7 +1226,7 @@ drop table t2;
|
|||||||
create table t2 select a from t1 union select a from t1;
|
create table t2 select a from t1 union select a from t1;
|
||||||
show columns from t2;
|
show columns from t2;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
a char(1)
|
a varchar(1) NO
|
||||||
drop table t2;
|
drop table t2;
|
||||||
create table t2 select a from t1 union select c from t1;
|
create table t2 select a from t1 union select c from t1;
|
||||||
ERROR HY000: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation 'UNION'
|
ERROR HY000: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation 'UNION'
|
||||||
|
@ -874,7 +874,7 @@ select * from v1;
|
|||||||
col1
|
col1
|
||||||
describe v1;
|
describe v1;
|
||||||
Field Type Null Key Default Extra
|
Field Type Null Key Default Extra
|
||||||
col1 char(2) YES NULL
|
col1 varchar(2) YES NULL
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table `t1a``b`;
|
drop table `t1a``b`;
|
||||||
create table t1 (col1 char(5),col2 char(5));
|
create table t1 (col1 char(5),col2 char(5));
|
||||||
|
@ -1726,7 +1726,7 @@ select (select a from t1) = (1,2);
|
|||||||
select (1,2,3) = (select * from t1);
|
select (1,2,3) = (select * from t1);
|
||||||
-- error 1241
|
-- error 1241
|
||||||
select (select * from t1) = (1,2,3);
|
select (select * from t1) = (1,2,3);
|
||||||
drop table t1
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
#decimal-related tests
|
#decimal-related tests
|
||||||
|
639
sql/field.cc
639
sql/field.cc
File diff suppressed because it is too large
Load Diff
@ -468,7 +468,6 @@ public:
|
|||||||
{ return field_length + 1 + (dec ? 1 : 0) + (field_length == dec ? 1 : 0); }
|
{ return field_length + 1 + (dec ? 1 : 0) + (field_length == dec ? 1 : 0); }
|
||||||
uint32 representation_length()
|
uint32 representation_length()
|
||||||
{ return field_length + 1 + (dec ? 1 : 0) + (field_length == dec ? 1 : 0); };
|
{ return field_length + 1 + (dec ? 1 : 0) + (field_length == dec ? 1 : 0); };
|
||||||
field_cast_enum field_cast_type() { return FIELD_CAST_NEWDECIMAL; }
|
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
uint32 pack_length() const { return (uint32) bin_size; }
|
uint32 pack_length() const { return (uint32) bin_size; }
|
||||||
};
|
};
|
||||||
@ -1002,7 +1001,7 @@ public:
|
|||||||
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
field_cast_enum field_cast_type() { return FIELD_CAST_STRING; }
|
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1305,7 +1304,6 @@ public:
|
|||||||
{ return (uint32) field_length + (bit_len > 0); }
|
{ return (uint32) field_length + (bit_len > 0); }
|
||||||
uint32 pack_length_in_rec() const { return field_length; }
|
uint32 pack_length_in_rec() const { return field_length; }
|
||||||
void sql_type(String &str) const;
|
void sql_type(String &str) const;
|
||||||
field_cast_enum field_cast_type() { return FIELD_CAST_BIT; }
|
|
||||||
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
||||||
const char *unpack(char* to, const char *from);
|
const char *unpack(char* to, const char *from);
|
||||||
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
|
53
sql/item.cc
53
sql/item.cc
@ -4690,6 +4690,9 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
|||||||
maybe_null= item->maybe_null;
|
maybe_null= item->maybe_null;
|
||||||
collation.set(item->collation);
|
collation.set(item->collation);
|
||||||
get_full_info(item);
|
get_full_info(item);
|
||||||
|
/* fix variable decimals which always is NOT_FIXED_DEC */
|
||||||
|
if (Field::result_merge_type(fld_type) == INT_RESULT)
|
||||||
|
decimals= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4748,7 +4751,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FUNC_ITEM:
|
case FUNC_ITEM:
|
||||||
if (((Item_func *) item)->functype() == Item_func::VAR_VALUE_FUNC)
|
if (((Item_func *) item)->functype() == Item_func::GUSERVAR_FUNC)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
There are work around of problem with changing variable type on the
|
There are work around of problem with changing variable type on the
|
||||||
@ -4764,6 +4767,8 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
|
|||||||
return MYSQL_TYPE_LONGLONG;
|
return MYSQL_TYPE_LONGLONG;
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
return MYSQL_TYPE_DOUBLE;
|
return MYSQL_TYPE_DOUBLE;
|
||||||
|
case DECIMAL_RESULT:
|
||||||
|
return MYSQL_TYPE_NEWDECIMAL;
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@ -4793,8 +4798,38 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
|
|||||||
|
|
||||||
bool Item_type_holder::join_types(THD *thd, Item *item)
|
bool Item_type_holder::join_types(THD *thd, Item *item)
|
||||||
{
|
{
|
||||||
max_length= max(max_length, display_length(item));
|
DBUG_ENTER("Item_type_holder::join_types");
|
||||||
|
DBUG_PRINT("info:", ("was type %d len %d, dec %d name %s",
|
||||||
|
fld_type, max_length, decimals,
|
||||||
|
(name ? name : "<NULL>")));
|
||||||
|
DBUG_PRINT("info:", ("in type %d len %d, dec %d",
|
||||||
|
get_real_type(item),
|
||||||
|
item->max_length, item->decimals));
|
||||||
fld_type= Field::field_type_merge(fld_type, get_real_type(item));
|
fld_type= Field::field_type_merge(fld_type, get_real_type(item));
|
||||||
|
{
|
||||||
|
int item_decimals= item->decimals;
|
||||||
|
/* fix variable decimals which always is NOT_FIXED_DEC */
|
||||||
|
if (Field::result_merge_type(fld_type) == INT_RESULT)
|
||||||
|
item_decimals= 0;
|
||||||
|
decimals= max(decimals, item_decimals);
|
||||||
|
}
|
||||||
|
if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
|
||||||
|
{
|
||||||
|
int item_length= display_length(item);
|
||||||
|
int intp1= item_length - min(item->decimals, NOT_FIXED_DEC - 1);
|
||||||
|
int intp2= max_length - min(decimals, NOT_FIXED_DEC - 1);
|
||||||
|
/* can't be overflow because it work only for decimals (no strings) */
|
||||||
|
int dec_length= max(intp1, intp2) + decimals;
|
||||||
|
max_length= max(max_length, max(item_length, dec_length));
|
||||||
|
/*
|
||||||
|
we can't allow decimals to be NOT_FIXED_DEC, to prevent creation
|
||||||
|
decimal with max precision (see Field_new_decimal constcuctor)
|
||||||
|
*/
|
||||||
|
if (decimals >= NOT_FIXED_DEC)
|
||||||
|
decimals= NOT_FIXED_DEC - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
max_length= max(max_length, display_length(item));
|
||||||
if (Field::result_merge_type(fld_type) == STRING_RESULT)
|
if (Field::result_merge_type(fld_type) == STRING_RESULT)
|
||||||
{
|
{
|
||||||
const char *old_cs, *old_derivation;
|
const char *old_cs, *old_derivation;
|
||||||
@ -4807,13 +4842,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
item->collation.collation->name,
|
item->collation.collation->name,
|
||||||
item->collation.derivation_name(),
|
item->collation.derivation_name(),
|
||||||
"UNION");
|
"UNION");
|
||||||
return TRUE;
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decimals= max(decimals, item->decimals);
|
|
||||||
maybe_null|= item->maybe_null;
|
maybe_null|= item->maybe_null;
|
||||||
get_full_info(item);
|
get_full_info(item);
|
||||||
return FALSE;
|
DBUG_PRINT("info:", ("become type %d len %d, dec %d",
|
||||||
|
fld_type, max_length, decimals));
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4841,6 +4877,9 @@ uint32 Item_type_holder::display_length(Item *item)
|
|||||||
case MYSQL_TYPE_DATETIME:
|
case MYSQL_TYPE_DATETIME:
|
||||||
case MYSQL_TYPE_YEAR:
|
case MYSQL_TYPE_YEAR:
|
||||||
case MYSQL_TYPE_NEWDATE:
|
case MYSQL_TYPE_NEWDATE:
|
||||||
|
case MYSQL_TYPE_VARCHAR:
|
||||||
|
case MYSQL_TYPE_BIT:
|
||||||
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
case MYSQL_TYPE_ENUM:
|
case MYSQL_TYPE_ENUM:
|
||||||
case MYSQL_TYPE_SET:
|
case MYSQL_TYPE_SET:
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
@ -4906,10 +4945,6 @@ Field *Item_type_holder::make_field_by_type(TABLE *table)
|
|||||||
Field::NONE, name,
|
Field::NONE, name,
|
||||||
table, get_set_pack_length(enum_set_typelib->count),
|
table, get_set_pack_length(enum_set_typelib->count),
|
||||||
enum_set_typelib, collation.collation);
|
enum_set_typelib, collation.collation);
|
||||||
case MYSQL_TYPE_VAR_STRING:
|
|
||||||
table->db_create_options|= HA_OPTION_PACK_RECORD;
|
|
||||||
return new Field_string(max_length, maybe_null, name, table,
|
|
||||||
collation.collation);
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ public:
|
|||||||
FALSE value is false or NULL
|
FALSE value is false or NULL
|
||||||
TRUE value is true (not equal to 0)
|
TRUE value is true (not equal to 0)
|
||||||
*/
|
*/
|
||||||
bool val_bool();
|
virtual bool val_bool();
|
||||||
/* Helper functions, see item_sum.cc */
|
/* Helper functions, see item_sum.cc */
|
||||||
String *val_string_from_real(String *str);
|
String *val_string_from_real(String *str);
|
||||||
String *val_string_from_int(String *str);
|
String *val_string_from_int(String *str);
|
||||||
|
@ -708,7 +708,7 @@ longlong Item_in_optimizer::val_int()
|
|||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
longlong tmp= args[1]->val_int_result();
|
bool tmp= args[1]->val_bool_result();
|
||||||
null_value= args[1]->null_value;
|
null_value= args[1]->null_value;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
|
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
|
||||||
NOT_FUNC, NOT_ALL_FUNC,
|
NOT_FUNC, NOT_ALL_FUNC,
|
||||||
NOW_FUNC, TRIG_COND_FUNC,
|
NOW_FUNC, TRIG_COND_FUNC,
|
||||||
GUSERVAR_FUNC, VAR_VALUE_FUNC};
|
GUSERVAR_FUNC};
|
||||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||||
OPTIMIZE_EQUAL };
|
OPTIMIZE_EQUAL };
|
||||||
enum Type type() const { return FUNC_ITEM; }
|
enum Type type() const { return FUNC_ITEM; }
|
||||||
@ -1124,7 +1124,6 @@ public:
|
|||||||
select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b)
|
select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b)
|
||||||
*/
|
*/
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||||
enum Functype functype() const { return VAR_VALUE_FUNC; }
|
|
||||||
const char *func_name() const { return "get_user_var"; }
|
const char *func_name() const { return "get_user_var"; }
|
||||||
bool const_item() const;
|
bool const_item() const;
|
||||||
table_map used_tables() const
|
table_map used_tables() const
|
||||||
|
@ -637,18 +637,13 @@ String *Item_exists_subselect::val_str(String *str)
|
|||||||
reset();
|
reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
str->set(value,&my_charset_bin);
|
str->set((ulonglong)value,&my_charset_bin);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
|
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
As far as Item_in_subselect called only from Item_in_optimizer this
|
|
||||||
method should not be used
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
@ -731,11 +726,46 @@ String *Item_in_subselect::val_str(String *str)
|
|||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
str->set(value, &my_charset_bin);
|
str->set((ulonglong)value, &my_charset_bin);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_in_subselect::val_bool()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if (exec())
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
null_value= 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (was_null && !value)
|
||||||
|
null_value= 1;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
||||||
|
method should not be used
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if (exec())
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
null_value= 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (was_null && !value)
|
||||||
|
null_value= 1;
|
||||||
|
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
||||||
|
return decimal_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Rewrite a single-column IN/ALL/ANY subselect. */
|
/* Rewrite a single-column IN/ALL/ANY subselect. */
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
|
@ -179,7 +179,7 @@ public:
|
|||||||
class Item_exists_subselect :public Item_subselect
|
class Item_exists_subselect :public Item_subselect
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
longlong value; /* value of this item (boolean: exists/not-exists) */
|
bool value; /* value of this item (boolean: exists/not-exists) */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_exists_subselect(st_select_lex *select_lex);
|
Item_exists_subselect(st_select_lex *select_lex);
|
||||||
@ -243,6 +243,8 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
double val_real();
|
double val_real();
|
||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
|
my_decimal *val_decimal(my_decimal *);
|
||||||
|
bool val_bool();
|
||||||
void top_level_item() { abort_on_null=1; }
|
void top_level_item() { abort_on_null=1; }
|
||||||
bool test_limit(st_select_lex_unit *unit);
|
bool test_limit(st_select_lex_unit *unit);
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
|
@ -115,7 +115,7 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
|
|||||||
DBUG_RETURN(1); // out of memory
|
DBUG_RETURN(1); // out of memory
|
||||||
|
|
||||||
// st_select_lex_unit::prepare correctly work for single select
|
// st_select_lex_unit::prepare correctly work for single select
|
||||||
if ((res= unit->prepare(thd, derived_result, 0, org_table_list->alias)))
|
if ((res= unit->prepare(thd, derived_result, 0, orig_table_list->alias)))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ bool mysql_create_view(THD *thd,
|
|||||||
|
|
||||||
/* prepare select to resolve all fields */
|
/* prepare select to resolve all fields */
|
||||||
lex->view_prepare_mode= 1;
|
lex->view_prepare_mode= 1;
|
||||||
if (unit->prepare(thd, 0, 0))
|
if (unit->prepare(thd, 0, 0, view->view_name.str))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
some errors from prepare are reported to user, if is not then
|
some errors from prepare are reported to user, if is not then
|
||||||
|
Loading…
x
Reference in New Issue
Block a user