Commit 8830eb4a authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Change of internal key_field=NULL handling to avoid error messages.

Optimized SELECT DISTINCT ... ORDER BY ... LIMIT
Fixed reference to uninitalized variable
parent ce56f927
...@@ -198,6 +198,30 @@ a ...@@ -198,6 +198,30 @@ a
select distinct 1 from t1,t3 where t1.a=t3.a; select distinct 1 from t1,t3 where t1.a=t3.a;
1 1
1 1
explain SELECT distinct t1.a from t1;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 2 Using index
explain SELECT distinct t1.a from t1 order by a desc;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 2 Using index
explain SELECT t1.a from t1 group by a order by a desc;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 2 Using index
explain SELECT distinct t1.a from t1 order by a desc limit 1;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 2 Using index
explain SELECT distinct a from t3 order by a desc limit 2;
table type possible_keys key key_len ref rows Extra
t3 index NULL a 5 NULL 204 Using index
explain SELECT distinct a,b from t3 order by a+1;
table type possible_keys key key_len ref rows Extra
t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
explain SELECT distinct a,b from t3 order by a limit 10;
table type possible_keys key key_len ref rows Extra
t3 index NULL a 5 NULL 204 Using temporary
explain SELECT a,b from t3 group by a,b order by a+1;
table type possible_keys key key_len ref rows Extra
t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
CREATE TABLE t1 (name varchar(255)); CREATE TABLE t1 (name varchar(255));
INSERT INTO t1 VALUES ('aa'),('ab'),('ac'),('ad'),('ae'); INSERT INTO t1 VALUES ('aa'),('ab'),('ac'),('ad'),('ae');
......
...@@ -31,9 +31,10 @@ log10(100) log10(18) log10(-4) log10(0) log10(NULL) ...@@ -31,9 +31,10 @@ log10(100) log10(18) log10(-4) log10(0) log10(NULL)
select pow(10,log10(10)),power(2,4); select pow(10,log10(10)),power(2,4);
pow(10,log10(10)) power(2,4) pow(10,log10(10)) power(2,4)
10.000000 16.000000 10.000000 16.000000
set @@rand_seed1=10000000,@@rand_seed2=1000000;
select rand(999999),rand(); select rand(999999),rand();
rand(999999) rand() rand(999999) rand()
0.014231365187309 0.8078568166195 0.014231365187309 0.028870999839968
select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1); select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
PI() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1) PI() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1)
3.141593 1.000000 0.000000 0.000000 0.64209262 1.570796 1.570796 0.785398 3.141593 1.000000 0.000000 0.000000 0.64209262 1.570796 1.570796 0.785398
......
...@@ -1036,3 +1036,25 @@ n d ...@@ -1036,3 +1036,25 @@ n d
1 30 1 30
2 20 2 20
drop table t1,t2; drop table t1,t2;
create table t1 (a int, b int) type=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a;
b ifnull(t2.b,"this is null")
NULL this is null
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
b ifnull(t2.b,"this is null")
NULL this is null
insert into t1 values(10,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
b ifnull(t2.b,"this is null")
NULL this is null
NULL this is null
drop table t1;
create table t1 (a varchar(10) not null) type=myisam;
create table t2 (b varchar(10) not null unique) type=innodb;
select t1.a from t1,t2 where t1.a=t2.b;
a
drop table t1,t2;
...@@ -6,7 +6,7 @@ select 1 | NULL,1 & NULL,1+NULL,1-NULL; ...@@ -6,7 +6,7 @@ select 1 | NULL,1 & NULL,1+NULL,1-NULL;
NULL NULL NULL NULL NULL NULL NULL NULL
select NULL=NULL,NULL<>NULL,IFNULL(NULL,1.1)+0,IFNULL(NULL,1) | 0; select NULL=NULL,NULL<>NULL,IFNULL(NULL,1.1)+0,IFNULL(NULL,1) | 0;
NULL=NULL NULL<>NULL IFNULL(NULL,1.1)+0 IFNULL(NULL,1) | 0 NULL=NULL NULL<>NULL IFNULL(NULL,1.1)+0 IFNULL(NULL,1) | 0
NULL NULL 1.1 1 NULL NULL 1 1
select strcmp("a",NULL),(1<NULL)+0.0,NULL regexp "a",null like "a%","a%" like null; select strcmp("a",NULL),(1<NULL)+0.0,NULL regexp "a",null like "a%","a%" like null;
strcmp("a",NULL) (1<NULL)+0.0 NULL regexp "a" null like "a%" "a%" like null strcmp("a",NULL) (1<NULL)+0.0 NULL regexp "a" null like "a%" "a%" like null
NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
...@@ -56,3 +56,20 @@ indexed_field ...@@ -56,3 +56,20 @@ indexed_field
NULL NULL
NULL NULL
DROP TABLE t1; DROP TABLE t1;
create table t1 (a int, b int) type=myisam;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a;
b ifnull(t2.b,"this is null")
NULL this is null
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
b ifnull(t2.b,"this is null")
NULL this is null
insert into t1 values(10,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
b ifnull(t2.b,"this is null")
NULL this is null
NULL this is null
drop table t1;
...@@ -88,6 +88,16 @@ select distinct t1.a from t1,t3 where t1.a=t3.a; ...@@ -88,6 +88,16 @@ select distinct t1.a from t1,t3 where t1.a=t3.a;
#flush status; #flush status;
select distinct 1 from t1,t3 where t1.a=t3.a; select distinct 1 from t1,t3 where t1.a=t3.a;
#show status like 'Handler%'; #show status like 'Handler%';
explain SELECT distinct t1.a from t1;
explain SELECT distinct t1.a from t1 order by a desc;
explain SELECT t1.a from t1 group by a order by a desc;
explain SELECT distinct t1.a from t1 order by a desc limit 1;
explain SELECT distinct a from t3 order by a desc limit 2;
explain SELECT distinct a,b from t3 order by a+1;
explain SELECT distinct a,b from t3 order by a limit 10;
explain SELECT a,b from t3 group by a,b order by a+1;
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
CREATE TABLE t1 (name varchar(255)); CREATE TABLE t1 (name varchar(255));
......
...@@ -13,6 +13,7 @@ select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL); ...@@ -13,6 +13,7 @@ select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL);
select log2(8),log2(15),log2(-2),log2(0),log2(NULL); select log2(8),log2(15),log2(-2),log2(0),log2(NULL);
select log10(100),log10(18),log10(-4),log10(0),log10(NULL); select log10(100),log10(18),log10(-4),log10(0),log10(NULL);
select pow(10,log10(10)),power(2,4); select pow(10,log10(10)),power(2,4);
set @@rand_seed1=10000000,@@rand_seed2=1000000;
select rand(999999),rand(); select rand(999999),rand();
select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1); select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
select degrees(pi()),radians(360); select degrees(pi()),radians(360);
...@@ -673,3 +673,26 @@ UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n; ...@@ -673,3 +673,26 @@ UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
select * from t1; select * from t1;
select * from t2; select * from t2;
drop table t1,t2; drop table t1,t2;
#
# Testing of IFNULL
#
create table t1 (a int, b int) type=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a;
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
insert into t1 values(10,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
drop table t1;
#
# Test of read_through not existing const_table
#
create table t1 (a varchar(10) not null) type=myisam;
create table t2 (b varchar(10) not null unique) type=innodb;
select t1.a from t1,t2 where t1.a=t2.b;
drop table t1,t2;
...@@ -34,3 +34,17 @@ SELECT * FROM t1 WHERE indexed_field=NULL; ...@@ -34,3 +34,17 @@ SELECT * FROM t1 WHERE indexed_field=NULL;
SELECT * FROM t1 WHERE indexed_field IS NULL; SELECT * FROM t1 WHERE indexed_field IS NULL;
SELECT * FROM t1 WHERE indexed_field<=>NULL; SELECT * FROM t1 WHERE indexed_field<=>NULL;
DROP TABLE t1; DROP TABLE t1;
#
# Testing of IFNULL
#
create table t1 (a int, b int) type=myisam;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a;
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
insert into t1 values(10,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
t2.b=t3.a order by 1;
drop table t1;
...@@ -1058,7 +1058,7 @@ Field *make_field(char *ptr, uint32 field_length, ...@@ -1058,7 +1058,7 @@ Field *make_field(char *ptr, uint32 field_length,
uint pack_length_to_packflag(uint type); uint pack_length_to_packflag(uint type);
uint32 calc_pack_length(enum_field_types type,uint32 length); uint32 calc_pack_length(enum_field_types type,uint32 length);
bool set_field_to_null(Field *field); bool set_field_to_null(Field *field);
bool set_field_to_null_with_conversions(Field *field); bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
uint find_enum(TYPELIB *typelib,const char *x, uint length); uint find_enum(TYPELIB *typelib,const char *x, uint length);
ulonglong find_set(TYPELIB *typelib,const char *x, uint length); ulonglong find_set(TYPELIB *typelib,const char *x, uint length);
bool test_if_int(const char *str,int length); bool test_if_int(const char *str,int length);
......
...@@ -122,8 +122,26 @@ set_field_to_null(Field *field) ...@@ -122,8 +122,26 @@ set_field_to_null(Field *field)
} }
/*
Set field to NULL or TIMESTAMP or to next auto_increment number
SYNOPSIS
set_field_to_null_with_conversions()
field Field to update
no_conversion Set to 1 if we should return 1 if field can't
take null values.
If set to 0 we will do store the 'default value'
if the field is a special field. If not we will
give an error.
RETURN VALUES
0 Field could take 0 or an automatic conversion was used
1 Field could not take NULL and no conversion was used.
If no_conversion was not set, an error message is printed
*/
bool bool
set_field_to_null_with_conversions(Field *field) set_field_to_null_with_conversions(Field *field, bool no_conversions)
{ {
if (field->real_maybe_null()) if (field->real_maybe_null())
{ {
...@@ -131,6 +149,8 @@ set_field_to_null_with_conversions(Field *field) ...@@ -131,6 +149,8 @@ set_field_to_null_with_conversions(Field *field)
field->reset(); field->reset();
return 0; return 0;
} }
if (no_conversions)
return 1;
/* /*
Check if this is a special type, which will get a special walue Check if this is a special type, which will get a special walue
...@@ -156,8 +176,6 @@ set_field_to_null_with_conversions(Field *field) ...@@ -156,8 +176,6 @@ set_field_to_null_with_conversions(Field *field)
} }
static void do_skip(Copy_field *copy __attribute__((unused))) static void do_skip(Copy_field *copy __attribute__((unused)))
{ {
} }
......
...@@ -419,7 +419,7 @@ void Item_field::save_org_in_field(Field *to) ...@@ -419,7 +419,7 @@ void Item_field::save_org_in_field(Field *to)
if (field->is_null()) if (field->is_null())
{ {
null_value=1; null_value=1;
set_field_to_null_with_conversions(to); set_field_to_null_with_conversions(to, 1);
} }
else else
{ {
...@@ -429,12 +429,12 @@ void Item_field::save_org_in_field(Field *to) ...@@ -429,12 +429,12 @@ void Item_field::save_org_in_field(Field *to)
} }
} }
bool Item_field::save_in_field(Field *to) bool Item_field::save_in_field(Field *to, bool no_conversions)
{ {
if (result_field->is_null()) if (result_field->is_null())
{ {
null_value=1; null_value=1;
return set_field_to_null_with_conversions(to); return set_field_to_null_with_conversions(to, no_conversions);
} }
else else
{ {
...@@ -461,9 +461,9 @@ bool Item_field::save_in_field(Field *to) ...@@ -461,9 +461,9 @@ bool Item_field::save_in_field(Field *to)
1 Field doesn't support NULL values and can't handle 'field = NULL' 1 Field doesn't support NULL values and can't handle 'field = NULL'
*/ */
bool Item_null::save_in_field(Field *field) bool Item_null::save_in_field(Field *field, bool no_conversions)
{ {
return set_field_to_null_with_conversions(field); return set_field_to_null_with_conversions(field, no_conversions);
} }
...@@ -485,7 +485,7 @@ bool Item_null::save_safe_in_field(Field *field) ...@@ -485,7 +485,7 @@ bool Item_null::save_safe_in_field(Field *field)
} }
bool Item::save_in_field(Field *field) bool Item::save_in_field(Field *field, bool no_conversions)
{ {
if (result_type() == STRING_RESULT || if (result_type() == STRING_RESULT ||
result_type() == REAL_RESULT && result_type() == REAL_RESULT &&
...@@ -496,7 +496,7 @@ bool Item::save_in_field(Field *field) ...@@ -496,7 +496,7 @@ bool Item::save_in_field(Field *field)
str_value.set_quick(buff,sizeof(buff)); str_value.set_quick(buff,sizeof(buff));
result=val_str(&str_value); result=val_str(&str_value);
if (null_value) if (null_value)
return set_field_to_null_with_conversions(field); return set_field_to_null_with_conversions(field, no_conversions);
field->set_notnull(); field->set_notnull();
field->store(result->ptr(),result->length()); field->store(result->ptr(),result->length());
str_value.set_quick(0, 0); str_value.set_quick(0, 0);
...@@ -513,7 +513,7 @@ bool Item::save_in_field(Field *field) ...@@ -513,7 +513,7 @@ bool Item::save_in_field(Field *field)
{ {
longlong nr=val_int(); longlong nr=val_int();
if (null_value) if (null_value)
return set_field_to_null_with_conversions(field); return set_field_to_null_with_conversions(field, no_conversions);
field->set_notnull(); field->set_notnull();
field->store(nr); field->store(nr);
} }
...@@ -521,7 +521,7 @@ bool Item::save_in_field(Field *field) ...@@ -521,7 +521,7 @@ bool Item::save_in_field(Field *field)
} }
bool Item_string::save_in_field(Field *field) bool Item_string::save_in_field(Field *field, bool no_conversions)
{ {
String *result; String *result;
result=val_str(&str_value); result=val_str(&str_value);
...@@ -532,7 +532,7 @@ bool Item_string::save_in_field(Field *field) ...@@ -532,7 +532,7 @@ bool Item_string::save_in_field(Field *field)
return 0; return 0;
} }
bool Item_int::save_in_field(Field *field) bool Item_int::save_in_field(Field *field, bool no_conversions)
{ {
longlong nr=val_int(); longlong nr=val_int();
if (null_value) if (null_value)
...@@ -542,7 +542,7 @@ bool Item_int::save_in_field(Field *field) ...@@ -542,7 +542,7 @@ bool Item_int::save_in_field(Field *field)
return 0; return 0;
} }
bool Item_real::save_in_field(Field *field) bool Item_real::save_in_field(Field *field, bool no_conversions)
{ {
double nr=val(); double nr=val();
if (null_value) if (null_value)
...@@ -597,7 +597,7 @@ longlong Item_varbinary::val_int() ...@@ -597,7 +597,7 @@ longlong Item_varbinary::val_int()
} }
bool Item_varbinary::save_in_field(Field *field) bool Item_varbinary::save_in_field(Field *field, bool no_conversions)
{ {
field->set_notnull(); field->set_notnull();
if (field->result_type() == STRING_RESULT) if (field->result_type() == STRING_RESULT)
...@@ -658,9 +658,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -658,9 +658,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables)
return 0; return 0;
} }
/* /*
** If item is a const function, calculate it and return a const item If item is a const function, calculate it and return a const item
** The original item is freed if not returned The original item is freed if not returned
*/ */
Item_result item_cmp_type(Item_result a,Item_result b) Item_result item_cmp_type(Item_result a,Item_result b)
......
...@@ -53,11 +53,11 @@ public: ...@@ -53,11 +53,11 @@ public:
void set_name(char* str,uint length=0); void set_name(char* str,uint length=0);
void init_make_field(Send_field *tmp_field,enum enum_field_types type); void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual bool fix_fields(THD *,struct st_table_list *); virtual bool fix_fields(THD *,struct st_table_list *);
virtual bool save_in_field(Field *field); virtual bool save_in_field(Field *field, bool no_conversions);
virtual void save_org_in_field(Field *field) virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); } { (void) save_in_field(field, 1); }
virtual bool save_safe_in_field(Field *field) virtual bool save_safe_in_field(Field *field)
{ return save_in_field(field); } { return save_in_field(field, 1); }
virtual bool send(THD *thd, String *str); virtual bool send(THD *thd, String *str);
virtual bool eq(const Item *, bool binary_cmp) const; virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; } virtual Item_result result_type () const { return REAL_RESULT; }
...@@ -130,7 +130,7 @@ public: ...@@ -130,7 +130,7 @@ public:
} }
void make_field(Send_field *field); void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field); bool save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field); void save_org_in_field(Field *field);
table_map used_tables() const; table_map used_tables() const;
enum Item_result result_type () const enum Item_result result_type () const
...@@ -156,7 +156,7 @@ public: ...@@ -156,7 +156,7 @@ public:
longlong val_int(); longlong val_int();
String *val_str(String *str); String *val_str(String *str);
void make_field(Send_field *field); void make_field(Send_field *field);
bool save_in_field(Field *field); bool save_in_field(Field *field, bool no_conversions);
bool save_safe_in_field(Field *field); bool save_safe_in_field(Field *field);
enum Item_result result_type () const enum Item_result result_type () const
{ return STRING_RESULT; } { return STRING_RESULT; }
...@@ -190,7 +190,7 @@ public: ...@@ -190,7 +190,7 @@ public:
double val() { return (double) value; } double val() { return (double) value; }
String *val_str(String*); String *val_str(String*);
void make_field(Send_field *field); void make_field(Send_field *field);
bool save_in_field(Field *field); bool save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); } Item *new_item() { return new Item_int(name,value,max_length); }
void print(String *str); void print(String *str);
...@@ -232,7 +232,7 @@ public: ...@@ -232,7 +232,7 @@ public:
max_length=length; max_length=length;
} }
Item_real(double value_par) :value(value_par) {} Item_real(double value_par) :value(value_par) {}
bool save_in_field(Field *field); bool save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; } enum Type type() const { return REAL_ITEM; }
double val() { return value; } double val() { return value; }
longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5));} longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5));}
...@@ -277,7 +277,7 @@ public: ...@@ -277,7 +277,7 @@ public:
double val() { return atof(str_value.ptr()); } double val() { return atof(str_value.ptr()); }
longlong val_int() { return strtoll(str_value.ptr(),(char**) 0,10); } longlong val_int() { return strtoll(str_value.ptr(),(char**) 0,10); }
String *val_str(String*) { return (String*) &str_value; } String *val_str(String*) { return (String*) &str_value; }
bool save_in_field(Field *field); bool save_in_field(Field *field, bool no_conversions);
void make_field(Send_field *field); void make_field(Send_field *field);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
...@@ -298,7 +298,7 @@ public: ...@@ -298,7 +298,7 @@ public:
Item_default() { name= (char*) "DEFAULT"; } Item_default() { name= (char*) "DEFAULT"; }
enum Type type() const { return DEFAULT_ITEM; } enum Type type() const { return DEFAULT_ITEM; }
void make_field(Send_field *field) {} void make_field(Send_field *field) {}
bool save_in_field(Field *field) bool save_in_field(Field *field, bool no_conversions)
{ {
field->set_default(); field->set_default();
return 0; return 0;
...@@ -339,7 +339,7 @@ public: ...@@ -339,7 +339,7 @@ public:
double val() { return (double) Item_varbinary::val_int(); } double val() { return (double) Item_varbinary::val_int(); }
longlong val_int(); longlong val_int();
String *val_str(String*) { return &str_value; } String *val_str(String*) { return &str_value; }
bool save_in_field(Field *field); bool save_in_field(Field *field, bool no_conversions);
void make_field(Send_field *field); void make_field(Send_field *field);
enum Item_result result_type () const { return INT_RESULT; } enum Item_result result_type () const { return INT_RESULT; }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
...@@ -401,7 +401,8 @@ public: ...@@ -401,7 +401,8 @@ public:
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
void make_field(Send_field *field) { (*ref)->make_field(field); } void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field) { return (*ref)->save_in_field(field); } bool save_in_field(Field *field, bool no_conversions)
{ return (*ref)->save_in_field(field, no_conversions); }
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); } enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); } table_map used_tables() const { return (*ref)->used_tables(); }
...@@ -421,9 +422,9 @@ class Item_int_with_ref :public Item_int ...@@ -421,9 +422,9 @@ class Item_int_with_ref :public Item_int
public: public:
Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg) Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
{} {}
bool save_in_field(Field *field) bool save_in_field(Field *field, bool no_conversions)
{ {
return ref->save_in_field(field); return ref->save_in_field(field, no_conversions);
} }
unsigned int size_of() { return sizeof(*this);} unsigned int size_of() { return sizeof(*this);}
}; };
......
...@@ -48,7 +48,7 @@ static bool convert_constant_item(Field *field, Item **item) ...@@ -48,7 +48,7 @@ static bool convert_constant_item(Field *field, Item **item)
{ {
if ((*item)->const_item() && (*item)->type() != Item::INT_ITEM) if ((*item)->const_item() && (*item)->type() != Item::INT_ITEM)
{ {
if (!(*item)->save_in_field(field) && if (!(*item)->save_in_field(field, 1) &&
!((*item)->null_value)) !((*item)->null_value))
{ {
Item *tmp=new Item_int_with_ref(field->val_int(), *item); Item *tmp=new Item_int_with_ref(field->val_int(), *item);
...@@ -444,15 +444,29 @@ longlong Item_func_between::val_int() ...@@ -444,15 +444,29 @@ longlong Item_func_between::val_int()
return 0; return 0;
} }
static Item_result item_store_type(Item_result a,Item_result b)
{
if (a == STRING_RESULT || b == STRING_RESULT)
return STRING_RESULT;
else if (a == REAL_RESULT || b == REAL_RESULT)
return REAL_RESULT;
else
return INT_RESULT;
}
void void
Item_func_ifnull::fix_length_and_dec() Item_func_ifnull::fix_length_and_dec()
{ {
maybe_null=args[1]->maybe_null; maybe_null=args[1]->maybe_null;
max_length=max(args[0]->max_length,args[1]->max_length); max_length=max(args[0]->max_length,args[1]->max_length);
decimals=max(args[0]->decimals,args[1]->decimals); decimals=max(args[0]->decimals,args[1]->decimals);
cached_result_type=args[0]->result_type(); if ((cached_result_type=item_store_type(args[0]->result_type(),
args[1]->result_type())) !=
REAL_RESULT)
decimals= 0;
} }
double double
Item_func_ifnull::val() Item_func_ifnull::val()
{ {
......
...@@ -696,21 +696,20 @@ double Item_func_round::val() ...@@ -696,21 +696,20 @@ double Item_func_round::val()
} }
double Item_func_rand::val() void Item_func_rand::fix_length_and_dec()
{ {
THD* thd = current_thd; decimals=NOT_FIXED_DEC;
max_length=float_length(decimals);
if (arg_count) if (arg_count)
{ // Only use argument once in query { // Only use argument once in query
uint32 tmp= (uint32) (args[0]->val_int()); uint32 tmp= (uint32) (args[0]->val_int());
randominit(&thd->rand,(uint32) (tmp*0x10001L+55555555L), if ((rand= (struct rand_struct*) sql_alloc(sizeof(*rand))))
randominit(rand,(uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L)); (uint32) (tmp*0x10000001L));
#ifdef DELETE_ITEMS
delete args[0];
#endif
arg_count=0;
} }
else if (!thd->rand_used) else
{ {
THD *thd= current_thd;
/* /*
No need to send a Rand log event if seed was given eg: RAND(seed), No need to send a Rand log event if seed was given eg: RAND(seed),
as it will be replicated in the query as such. as it will be replicated in the query as such.
...@@ -722,8 +721,14 @@ double Item_func_rand::val() ...@@ -722,8 +721,14 @@ double Item_func_rand::val()
thd->rand_used=1; thd->rand_used=1;
thd->rand_saved_seed1=thd->rand.seed1; thd->rand_saved_seed1=thd->rand.seed1;
thd->rand_saved_seed2=thd->rand.seed2; thd->rand_saved_seed2=thd->rand.seed2;
rand= &thd->rand;
} }
return rnd(&thd->rand); }
double Item_func_rand::val()
{
return rnd(rand);
} }
longlong Item_func_sign::val_int() longlong Item_func_sign::val_int()
......
...@@ -459,20 +459,20 @@ public: ...@@ -459,20 +459,20 @@ public:
const char *func_name() const { return truncate ? "truncate" : "round"; } const char *func_name() const { return truncate ? "truncate" : "round"; }
double val(); double val();
void fix_length_and_dec(); void fix_length_and_dec();
unsigned int size_of() { return sizeof(*this);}
}; };
class Item_func_rand :public Item_real_func class Item_func_rand :public Item_real_func
{ {
struct rand_struct *rand;
public: public:
Item_func_rand(Item *a) :Item_real_func(a) {} Item_func_rand(Item *a) :Item_real_func(a) {}
Item_func_rand() :Item_real_func() {} Item_func_rand() :Item_real_func() {}
double val(); double val();
const char *func_name() const { return "rand"; } const char *func_name() const { return "rand"; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
bool const_item() const { return 0; } bool const_item() const { return 0; }
table_map used_tables() const { return RAND_TABLE_BIT; } table_map used_tables() const { return RAND_TABLE_BIT; }
void fix_length_and_dec();
}; };
......
...@@ -403,7 +403,7 @@ String *Item_date::val_str(String *str) ...@@ -403,7 +403,7 @@ String *Item_date::val_str(String *str)
} }
bool Item_date::save_in_field(Field *field) bool Item_date::save_in_field(Field *field, bool no_conversions)
{ {
TIME ltime; TIME ltime;
timestamp_type t_type=TIMESTAMP_FULL; timestamp_type t_type=TIMESTAMP_FULL;
...@@ -518,7 +518,7 @@ bool Item_func_now::get_date(TIME *res, ...@@ -518,7 +518,7 @@ bool Item_func_now::get_date(TIME *res,
} }
bool Item_func_now::save_in_field(Field *to) bool Item_func_now::save_in_field(Field *to, bool no_conversions)
{ {
to->set_notnull(); to->set_notnull();
to->store_time(&ltime,TIMESTAMP_FULL); to->store_time(&ltime,TIMESTAMP_FULL);
......
...@@ -231,7 +231,7 @@ public: ...@@ -231,7 +231,7 @@ public:
double val() { return (double) val_int(); } double val() { return (double) val_int(); }
const char *func_name() const { return "date"; } const char *func_name() const { return "date"; }
void fix_length_and_dec() { decimals=0; max_length=10; } void fix_length_and_dec() { decimals=0; max_length=10; }
bool save_in_field(Field *to); bool save_in_field(Field *to, bool no_conversions);
void make_field(Send_field *tmp_field) void make_field(Send_field *tmp_field)
{ {
init_make_field(tmp_field,FIELD_TYPE_DATE); init_make_field(tmp_field,FIELD_TYPE_DATE);
...@@ -316,7 +316,7 @@ public: ...@@ -316,7 +316,7 @@ public:
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
double val() { return (double) value; } double val() { return (double) value; }
longlong val_int() { return value; } longlong val_int() { return value; }
bool save_in_field(Field *to); bool save_in_field(Field *to, bool no_conversions);
String *val_str(String *str) String *val_str(String *str)
{ str_value.set(buff,buff_length); return &str_value; } { str_value.set(buff,buff_length); return &str_value; }
const char *func_name() const { return "now"; } const char *func_name() const { return "now"; }
......
...@@ -1029,7 +1029,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, ...@@ -1029,7 +1029,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
field->cmp_type() != value->result_type()) field->cmp_type() != value->result_type())
DBUG_RETURN(0); DBUG_RETURN(0);
if (value->save_in_field(field)) if (value->save_in_field(field, 1))
{ {
/* This happens when we try to insert a NULL field in a not null column */ /* This happens when we try to insert a NULL field in a not null column */
// TODO; Check if we can we remove the following block. // TODO; Check if we can we remove the following block.
...@@ -1038,9 +1038,9 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, ...@@ -1038,9 +1038,9 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
/* convert column_name <=> NULL -> column_name IS NULL */ /* convert column_name <=> NULL -> column_name IS NULL */
// Get local copy of key // Get local copy of key
char *str= (char*) alloc_root(param->mem_root,1); char *str= (char*) alloc_root(param->mem_root,1);
if (!*str) if (!str)
DBUG_RETURN(0); DBUG_RETURN(0);
*str = 1; *str= 1;
DBUG_RETURN(new SEL_ARG(field,str,str)); DBUG_RETURN(new SEL_ARG(field,str,str));
} }
DBUG_RETURN(&null_element); // cmp with NULL is never true DBUG_RETURN(&null_element); // cmp with NULL is never true
......
...@@ -2098,7 +2098,7 @@ fill_record(List<Item> &fields,List<Item> &values) ...@@ -2098,7 +2098,7 @@ fill_record(List<Item> &fields,List<Item> &values)
while ((field=(Item_field*) f++)) while ((field=(Item_field*) f++))
{ {
value=v++; value=v++;
if (value->save_in_field(field->field)) if (value->save_in_field(field->field, 0))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -2116,7 +2116,7 @@ fill_record(Field **ptr,List<Item> &values) ...@@ -2116,7 +2116,7 @@ fill_record(Field **ptr,List<Item> &values)
while ((field = *ptr++)) while ((field = *ptr++))
{ {
value=v++; value=v++;
if (value->save_in_field(field)) if (value->save_in_field(field, 0))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -158,9 +158,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -158,9 +158,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
{ {
pthread_mutex_lock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_thread_count);
ulong tmp=(ulong) (rnd(&sql_rand) * 3000000); ulong tmp=(ulong) (rnd(&sql_rand) * 3000000);
randominit(&rand, tmp + (ulong) start_time,
tmp + (ulong) thread_id);
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
randominit(&rand, tmp + (ulong) start_time, tmp + (ulong) thread_id);
} }
} }
...@@ -171,16 +170,16 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -171,16 +170,16 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
void THD::init(void) void THD::init(void)
{ {
pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables;
pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT; server_status= SERVER_STATUS_AUTOCOMMIT;
update_lock_default= (variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY :
TL_WRITE);
options= thd_startup_options; options= thd_startup_options;
sql_mode=(uint) opt_sql_mode; sql_mode=(uint) opt_sql_mode;
open_options=ha_open_options; open_options=ha_open_options;
pthread_mutex_lock(&LOCK_global_system_variables); update_lock_default= (variables.low_priority_updates ?
variables= global_system_variables; TL_WRITE_LOW_PRIORITY :
pthread_mutex_unlock(&LOCK_global_system_variables); TL_WRITE);
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation; session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
} }
......
...@@ -180,10 +180,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -180,10 +180,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
Item *item; Item *item;
for (key_len=0 ; (item=it_ke++) ; key_part++) for (key_len=0 ; (item=it_ke++) ; key_part++)
{ {
item->save_in_field(key_part->field); item->save_in_field(key_part->field, 1);
key_len+=key_part->store_length; key_len+=key_part->store_length;
} }
if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
{ {
send_error(&thd->net,ER_OUTOFMEMORY); send_error(&thd->net,ER_OUTOFMEMORY);
goto err; goto err;
......
This diff is collapsed.
...@@ -269,8 +269,7 @@ public: ...@@ -269,8 +269,7 @@ public:
{} {}
bool copy() bool copy()
{ {
item->save_in_field(to_field); return item->save_in_field(to_field, 1) || err != 0;
return err != 0;
} }
const char *name() const { return "func"; } const char *name() const { return "func"; }
}; };
...@@ -293,7 +292,8 @@ public: ...@@ -293,7 +292,8 @@ public:
if (!inited) if (!inited)
{ {
inited=1; inited=1;
item->save_in_field(to_field); if (item->save_in_field(to_field, 1))
err= 1;
} }
return err != 0; return err != 0;
} }
......
...@@ -574,7 +574,7 @@ static bool make_empty_rec(File file,enum db_type table_type, ...@@ -574,7 +574,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
if (field->def && if (field->def &&
(regfield->real_type() != FIELD_TYPE_YEAR || (regfield->real_type() != FIELD_TYPE_YEAR ||
field->def->val_int() != 0)) field->def->val_int() != 0))
field->def->save_in_field(regfield); field->def->save_in_field(regfield, 1);
else if (regfield->real_type() == FIELD_TYPE_ENUM && else if (regfield->real_type() == FIELD_TYPE_ENUM &&
(field->flags & NOT_NULL_FLAG)) (field->flags & NOT_NULL_FLAG))
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment