Change of internal key_field=NULL handling to avoid error messages.
Optimized SELECT DISTINCT ... ORDER BY ... LIMIT Fixed reference to uninitalized variable mysql-test/r/distinct.result: Updated results for new tests mysql-test/r/func_math.result: Fixed test of RND() mysql-test/r/innodb.result: Updated results for new tests mysql-test/r/null.result: Updated results for new tests mysql-test/t/distinct.test: New distinct test mysql-test/t/func_math.test: Fixed test of RND() mysql-test/t/innodb.test: Test for bugs mysql-test/t/null.test: TEst for bugs sql/field.h: Change of NULL handling to avoid error messages sql/field_conv.cc: Change of NULL handling to avoid error messages sql/item.cc: Change of NULL handling to avoid error messages sql/item.h: Change of NULL handling to avoid error messages sql/item_cmpfunc.cc: Change of NULL handling to avoid error messages sql/item_func.cc: Change of NULL handling to avoid error messages sql/item_func.h: Cleaned up RND() handling sql/item_timefunc.cc: Change of NULL handling to avoid error messages sql/item_timefunc.h: Change of NULL handling to avoid error messages sql/opt_range.cc: Fixed bug in <=> NULL sql/password.c: Indentation cleanup sql/sql_base.cc: Change of NULL handling to avoid error messages sql/sql_class.cc: Fixed reference to uninitalized variable sql/sql_handler.cc: Change of NULL handling to avoid error messages sql/sql_select.cc: Change of NULL handling to avoid error messages Optimized SELECT DISTINCT ... ORDER BY ... LIMIT sql/sql_select.h: Change of NULL handling to avoid error messages sql/unireg.cc: Change of NULL handling to avoid error messages
This commit is contained in:
parent
4f221e351d
commit
80b143c111
@ -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)
|
|||||||
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
|
|||||||
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;
|
|||||||
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
|
|||||||
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;
|
|||||||
#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);
|
|||||||
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;
|
|||||||
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;
|
|||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void do_skip(Copy_field *copy __attribute__((unused)))
|
static void do_skip(Copy_field *copy __attribute__((unused)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
29
sql/item.cc
29
sql/item.cc
@ -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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
||||||
|
27
sql/item.h
27
sql/item.h
@ -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:
|
|||||||
}
|
}
|
||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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))))
|
||||||
(uint32) (tmp*0x10000001L));
|
randominit(rand,(uint32) (tmp*0x10001L+55555555L),
|
||||||
#ifdef DELETE_ITEMS
|
(uint32) (tmp*0x10000001L));
|
||||||
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()
|
|||||||
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:
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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(<ime,TIMESTAMP_FULL);
|
to->store_time(<ime,TIMESTAMP_FULL);
|
||||||
|
@ -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:
|
|||||||
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,
|
|||||||
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,
|
|||||||
/* 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
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
|
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
|
||||||
{ /* For mysql 3.21.# */
|
{ /* For mysql 3.21.# */
|
||||||
#ifdef HAVE_purify
|
#ifdef HAVE_purify
|
||||||
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
||||||
#endif
|
#endif
|
||||||
rand_st->max_value= 0x3FFFFFFFL;
|
rand_st->max_value= 0x3FFFFFFFL;
|
||||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||||
|
@ -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)
|
|||||||
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),
|
|||||||
{
|
{
|
||||||
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),
|
|||||||
|
|
||||||
void THD::init(void)
|
void THD::init(void)
|
||||||
{
|
{
|
||||||
server_status= SERVER_STATUS_AUTOCOMMIT;
|
|
||||||
update_lock_default= (variables.low_priority_updates ?
|
|
||||||
TL_WRITE_LOW_PRIORITY :
|
|
||||||
TL_WRITE);
|
|
||||||
options= thd_startup_options;
|
|
||||||
sql_mode=(uint) opt_sql_mode;
|
|
||||||
open_options=ha_open_options;
|
|
||||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||||
variables= global_system_variables;
|
variables= global_system_variables;
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||||
|
server_status= SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
options= thd_startup_options;
|
||||||
|
sql_mode=(uint) opt_sql_mode;
|
||||||
|
open_options=ha_open_options;
|
||||||
|
update_lock_default= (variables.low_priority_updates ?
|
||||||
|
TL_WRITE_LOW_PRIORITY :
|
||||||
|
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,
|
|||||||
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;
|
||||||
|
@ -130,7 +130,9 @@ static int setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
|||||||
List<Item> &all_fields, ORDER *order, bool *hidden);
|
List<Item> &all_fields, ORDER *order, bool *hidden);
|
||||||
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||||
List<Item> &all_fields,ORDER *new_order);
|
List<Item> &all_fields,ORDER *new_order);
|
||||||
static ORDER *create_distinct_group(ORDER *order, List<Item> &fields);
|
static ORDER *create_distinct_group(THD *thd, ORDER *order,
|
||||||
|
List<Item> &fields,
|
||||||
|
bool *all_order_by_fields_used);
|
||||||
static bool test_if_subpart(ORDER *a,ORDER *b);
|
static bool test_if_subpart(ORDER *a,ORDER *b);
|
||||||
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
|
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
|
||||||
static void calc_group_buffer(JOIN *join,ORDER *group);
|
static void calc_group_buffer(JOIN *join,ORDER *group);
|
||||||
@ -228,6 +230,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
bzero((char*) &keyuse,sizeof(keyuse));
|
bzero((char*) &keyuse,sizeof(keyuse));
|
||||||
thd->proc_info="init";
|
thd->proc_info="init";
|
||||||
thd->used_tables=0; // Updated by setup_fields
|
thd->used_tables=0; // Updated by setup_fields
|
||||||
|
/* select_limit is used to decide if we are likely to scan the whole table */
|
||||||
|
select_limit= thd->select_limit;
|
||||||
|
if (having || (select_options & OPTION_FOUND_ROWS))
|
||||||
|
select_limit= HA_POS_ERROR;
|
||||||
|
|
||||||
if (setup_tables(tables) ||
|
if (setup_tables(tables) ||
|
||||||
setup_fields(thd,tables,fields,1,&all_fields,1) ||
|
setup_fields(thd,tables,fields,1,&all_fields,1) ||
|
||||||
@ -436,6 +442,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
thd->proc_info="statistics";
|
thd->proc_info="statistics";
|
||||||
if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error)
|
if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
thd->proc_info="preparing";
|
thd->proc_info="preparing";
|
||||||
if (result->initialize_tables(&join))
|
if (result->initialize_tables(&join))
|
||||||
goto err;
|
goto err;
|
||||||
@ -444,7 +451,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
{
|
{
|
||||||
error=return_zero_rows(&join,result,tables,fields,
|
error=return_zero_rows(&join,result,tables,fields,
|
||||||
join.tmp_table_param.sum_func_count != 0 &&
|
join.tmp_table_param.sum_func_count != 0 &&
|
||||||
!group,0,"",having,procedure);
|
!group,0,"no matching row in const table",having,
|
||||||
|
procedure);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!(thd->options & OPTION_BIG_SELECTS) &&
|
if (!(thd->options & OPTION_BIG_SELECTS) &&
|
||||||
@ -504,21 +512,47 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
if (! hidden_group_fields)
|
if (! hidden_group_fields)
|
||||||
select_distinct=0;
|
select_distinct=0;
|
||||||
}
|
}
|
||||||
else if (select_distinct && join.tables - join.const_tables == 1 &&
|
else if (select_distinct && join.tables - join.const_tables == 1)
|
||||||
(thd->select_limit == HA_POS_ERROR ||
|
|
||||||
(join.select_options & OPTION_FOUND_ROWS) ||
|
|
||||||
order &&
|
|
||||||
!(skip_sort_order=
|
|
||||||
test_if_skip_sort_order(&join.join_tab[join.const_tables],
|
|
||||||
order, thd->select_limit,1))))
|
|
||||||
{
|
{
|
||||||
if ((group=create_distinct_group(order,fields)))
|
/*
|
||||||
|
We are only using one table. In this case we change DISTINCT to a
|
||||||
|
GROUP BY query if:
|
||||||
|
- The GROUP BY can be done through indexes (no sort) and the ORDER
|
||||||
|
BY only uses selected fields.
|
||||||
|
(In this case we can later optimize away GROUP BY and ORDER BY)
|
||||||
|
- We are scanning the whole table without LIMIT
|
||||||
|
This can happen if:
|
||||||
|
- We are using CALC_FOUND_ROWS
|
||||||
|
- We are using an ORDER BY that can't be optimized away.
|
||||||
|
|
||||||
|
We don't want to use this optimization when we are using LIMIT
|
||||||
|
because in this case we can just create a temporary table that
|
||||||
|
holds LIMIT rows and stop when this table is full.
|
||||||
|
*/
|
||||||
|
JOIN_TAB *tab= &join.join_tab[join.const_tables];
|
||||||
|
bool all_order_fields_used;
|
||||||
|
if (order)
|
||||||
|
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
|
||||||
|
if ((group=create_distinct_group(thd, order, fields,
|
||||||
|
&all_order_fields_used)))
|
||||||
{
|
{
|
||||||
select_distinct=0;
|
bool skip_group= (skip_sort_order &&
|
||||||
no_order= !order;
|
test_if_skip_sort_order(tab, group, select_limit,
|
||||||
join.group=1; // For end_write_group
|
1) != 0);
|
||||||
}
|
if ((skip_group && all_order_fields_used) ||
|
||||||
else if (thd->fatal_error) // End of memory
|
select_limit == HA_POS_ERROR ||
|
||||||
|
(order && !skip_sort_order))
|
||||||
|
{
|
||||||
|
/* Change DISTINCT to GROUP BY */
|
||||||
|
select_distinct= 0;
|
||||||
|
no_order= !order;
|
||||||
|
if (all_order_fields_used)
|
||||||
|
order=0;
|
||||||
|
join.group=1; // For end_write_group
|
||||||
|
}
|
||||||
|
else
|
||||||
|
group= 0;
|
||||||
|
} else if (thd->fatal_error) // End of memory
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
group=remove_const(&join,group,conds,&simple_group);
|
group=remove_const(&join,group,conds,&simple_group);
|
||||||
@ -622,10 +656,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
order=group;
|
order=group;
|
||||||
if (order &&
|
if (order &&
|
||||||
(join.const_tables == join.tables ||
|
(join.const_tables == join.tables ||
|
||||||
(simple_order &&
|
((simple_order || skip_sort_order) &&
|
||||||
test_if_skip_sort_order(&join.join_tab[join.const_tables], order,
|
test_if_skip_sort_order(&join.join_tab[join.const_tables], order,
|
||||||
(join.select_options & OPTION_FOUND_ROWS) ?
|
select_limit, 0))))
|
||||||
HA_POS_ERROR : thd->select_limit,0))))
|
|
||||||
order=0;
|
order=0;
|
||||||
select_describe(&join,need_tmp,
|
select_describe(&join,need_tmp,
|
||||||
order != 0 && !skip_sort_order,
|
order != 0 && !skip_sort_order,
|
||||||
@ -653,7 +686,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
group ? 0 : select_distinct,
|
group ? 0 : select_distinct,
|
||||||
group && simple_group,
|
group && simple_group,
|
||||||
(order == 0 || skip_sort_order) &&
|
(order == 0 || skip_sort_order) &&
|
||||||
!(join.select_options & OPTION_FOUND_ROWS),
|
select_limit != HA_POS_ERROR,
|
||||||
join.select_options)))
|
join.select_options)))
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
|
|
||||||
@ -706,9 +739,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
/* Optimize "select distinct b from t1 order by key_part_1 limit #" */
|
/* Optimize "select distinct b from t1 order by key_part_1 limit #" */
|
||||||
if (order && skip_sort_order)
|
if (order && skip_sort_order)
|
||||||
{
|
{
|
||||||
(void) test_if_skip_sort_order(&join.join_tab[join.const_tables],
|
/* Should always succeed */
|
||||||
order, thd->select_limit,0);
|
if (test_if_skip_sort_order(&join.join_tab[join.const_tables],
|
||||||
order=0;
|
order, thd->select_limit,0))
|
||||||
|
order=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,8 +911,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
DBUG_EXECUTE("where",print_where(conds,"having after sort"););
|
DBUG_EXECUTE("where",print_where(conds,"having after sort"););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
select_limit= thd->select_limit;
|
if (group)
|
||||||
if (having || group || (join.select_options & OPTION_FOUND_ROWS))
|
|
||||||
select_limit= HA_POS_ERROR;
|
select_limit= HA_POS_ERROR;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -953,13 +986,21 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the best possible join and initialize the join structure
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 ok
|
||||||
|
1 Fatal error
|
||||||
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
||||||
DYNAMIC_ARRAY *keyuse_array)
|
DYNAMIC_ARRAY *keyuse_array)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint i,table_count,const_count,found_ref,refs,key,const_ref,eq_part;
|
uint i,table_count,const_count,found_ref,refs,key,const_ref,eq_part;
|
||||||
table_map const_table_map,found_const_table_map,all_table_map;
|
table_map found_const_table_map,all_table_map;
|
||||||
TABLE **table_vector;
|
TABLE **table_vector;
|
||||||
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
|
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
@ -979,7 +1020,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
join->best_ref=stat_vector;
|
join->best_ref=stat_vector;
|
||||||
|
|
||||||
stat_end=stat+table_count;
|
stat_end=stat+table_count;
|
||||||
const_table_map=found_const_table_map=all_table_map=0;
|
found_const_table_map=all_table_map=0;
|
||||||
const_count=0;
|
const_count=0;
|
||||||
|
|
||||||
for (s=stat,i=0 ; tables ; s++,tables=tables->next,i++)
|
for (s=stat,i=0 ; tables ; s++,tables=tables->next,i++)
|
||||||
@ -1070,7 +1111,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* Read tables with 0 or 1 rows (system tables) */
|
/* Read tables with 0 or 1 rows (system tables) */
|
||||||
join->const_table_map=const_table_map;
|
join->const_table_map= 0;
|
||||||
|
|
||||||
for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
|
for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
|
||||||
p_pos < p_end ;
|
p_pos < p_end ;
|
||||||
@ -1107,16 +1148,16 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
if (s->dependent) // If dependent on some table
|
if (s->dependent) // If dependent on some table
|
||||||
{
|
{
|
||||||
// All dep. must be constants
|
// All dep. must be constants
|
||||||
if (s->dependent & ~(join->const_table_map))
|
if (s->dependent & ~(found_const_table_map))
|
||||||
continue;
|
continue;
|
||||||
if (table->file->records <= 1L &&
|
if (table->file->records <= 1L &&
|
||||||
!(table->file->table_flags() & HA_NOT_EXACT_COUNT))
|
!(table->file->table_flags() & HA_NOT_EXACT_COUNT))
|
||||||
{ // system table
|
{ // system table
|
||||||
int tmp;
|
int tmp= 0;
|
||||||
s->type=JT_SYSTEM;
|
s->type=JT_SYSTEM;
|
||||||
join->const_table_map|=table->map;
|
join->const_table_map|=table->map;
|
||||||
set_position(join,const_count++,s,(KEYUSE*) 0);
|
set_position(join,const_count++,s,(KEYUSE*) 0);
|
||||||
if ((tmp=join_read_const_table(s,join->positions+const_count-1)))
|
if ((tmp= join_read_const_table(s,join->positions+const_count-1)))
|
||||||
{
|
{
|
||||||
if (tmp > 0)
|
if (tmp > 0)
|
||||||
DBUG_RETURN(1); // Fatal error
|
DBUG_RETURN(1); // Fatal error
|
||||||
@ -1141,7 +1182,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
{
|
{
|
||||||
if (keyuse->val->type() != Item::NULL_ITEM)
|
if (keyuse->val->type() != Item::NULL_ITEM)
|
||||||
{
|
{
|
||||||
if (!((~join->const_table_map) & keyuse->used_tables))
|
if (!((~found_const_table_map) & keyuse->used_tables))
|
||||||
const_ref|= (key_map) 1 << keyuse->keypart;
|
const_ref|= (key_map) 1 << keyuse->keypart;
|
||||||
else
|
else
|
||||||
refs|=keyuse->used_tables;
|
refs|=keyuse->used_tables;
|
||||||
@ -1162,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
join->const_table_map|=table->map;
|
join->const_table_map|=table->map;
|
||||||
set_position(join,const_count++,s,start_keyuse);
|
set_position(join,const_count++,s,start_keyuse);
|
||||||
if (create_ref_for_key(join, s, start_keyuse,
|
if (create_ref_for_key(join, s, start_keyuse,
|
||||||
join->const_table_map))
|
found_const_table_map))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if ((tmp=join_read_const_table(s,
|
if ((tmp=join_read_const_table(s,
|
||||||
join->positions+const_count-1)))
|
join->positions+const_count-1)))
|
||||||
@ -1210,8 +1251,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
|
|||||||
{
|
{
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
if (!select)
|
if (!select)
|
||||||
select=make_select(s->table, join->const_table_map,
|
select=make_select(s->table, found_const_table_map,
|
||||||
join->const_table_map,
|
found_const_table_map,
|
||||||
and_conds(conds,s->on_expr),&error);
|
and_conds(conds,s->on_expr),&error);
|
||||||
records=get_quick_record_count(select,s->table, s->const_keys,
|
records=get_quick_record_count(select,s->table, s->const_keys,
|
||||||
join->row_limit);
|
join->row_limit);
|
||||||
@ -2373,12 +2414,13 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
|
|||||||
bool
|
bool
|
||||||
store_val_in_field(Field *field,Item *item)
|
store_val_in_field(Field *field,Item *item)
|
||||||
{
|
{
|
||||||
|
bool error;
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
ha_rows cuted_fields=thd->cuted_fields;
|
ha_rows cuted_fields=thd->cuted_fields;
|
||||||
thd->count_cuted_fields=1;
|
thd->count_cuted_fields=1;
|
||||||
item->save_in_field(field);
|
error= item->save_in_field(field, 1);
|
||||||
thd->count_cuted_fields=0;
|
thd->count_cuted_fields=0;
|
||||||
return cuted_fields != thd->cuted_fields;
|
return error || cuted_fields != thd->cuted_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6577,12 +6619,14 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static ORDER *
|
static ORDER *
|
||||||
create_distinct_group(ORDER *order_list,List<Item> &fields)
|
create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
|
||||||
|
bool *all_order_by_fields_used)
|
||||||
{
|
{
|
||||||
List_iterator<Item> li(fields);
|
List_iterator<Item> li(fields);
|
||||||
Item *item;
|
Item *item;
|
||||||
ORDER *order,*group,**prev;
|
ORDER *order,*group,**prev;
|
||||||
|
|
||||||
|
*all_order_by_fields_used= 1;
|
||||||
while ((item=li++))
|
while ((item=li++))
|
||||||
item->marker=0; /* Marker that field is not used */
|
item->marker=0; /* Marker that field is not used */
|
||||||
|
|
||||||
@ -6591,13 +6635,15 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
|
|||||||
{
|
{
|
||||||
if (order->in_field_list)
|
if (order->in_field_list)
|
||||||
{
|
{
|
||||||
ORDER *ord=(ORDER*) sql_memdup(order,sizeof(ORDER));
|
ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER));
|
||||||
if (!ord)
|
if (!ord)
|
||||||
return 0;
|
return 0;
|
||||||
*prev=ord;
|
*prev=ord;
|
||||||
prev= &ord->next;
|
prev= &ord->next;
|
||||||
(*ord->item)->marker=1;
|
(*ord->item)->marker=1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*all_order_by_fields_used= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.rewind();
|
li.rewind();
|
||||||
@ -6607,7 +6653,7 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
|
|||||||
continue;
|
continue;
|
||||||
if (!item->marker)
|
if (!item->marker)
|
||||||
{
|
{
|
||||||
ORDER *ord=(ORDER*) sql_calloc(sizeof(ORDER));
|
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
|
||||||
if (!ord)
|
if (!ord)
|
||||||
return 0;
|
return 0;
|
||||||
ord->item=li.ref();
|
ord->item=li.ref();
|
||||||
@ -7059,7 +7105,7 @@ copy_sum_funcs(Item_sum **func_ptr)
|
|||||||
{
|
{
|
||||||
Item_sum *func;
|
Item_sum *func;
|
||||||
for (; (func = *func_ptr) ; func_ptr++)
|
for (; (func = *func_ptr) ; func_ptr++)
|
||||||
(void) func->save_in_field(func->result_field);
|
(void) func->save_in_field(func->result_field, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7090,7 +7136,7 @@ copy_funcs(Item_result_field **func_ptr)
|
|||||||
{
|
{
|
||||||
Item_result_field *func;
|
Item_result_field *func;
|
||||||
for (; (func = *func_ptr) ; func_ptr++)
|
for (; (func = *func_ptr) ; func_ptr++)
|
||||||
(void) func->save_in_field(func->result_field);
|
(void) func->save_in_field(func->result_field, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,12 +247,12 @@ class store_key_field: public store_key
|
|||||||
copy_field.set(to_field,from_field,0);
|
copy_field.set(to_field,from_field,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool copy()
|
bool copy()
|
||||||
{
|
{
|
||||||
copy_field.do_copy(©_field);
|
copy_field.do_copy(©_field);
|
||||||
return err != 0;
|
return err != 0;
|
||||||
}
|
}
|
||||||
const char *name() const { return field_name; }
|
const char *name() const { return field_name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -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:
|
|||||||
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,
|
|||||||
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))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user