Merge dl145s.mysql.com:/data/bk/team_tree_merge/MERGE/mysql-4.1-opt
into dl145s.mysql.com:/data/bk/team_tree_merge/MERGE/mysql-5.0-opt
This commit is contained in:
commit
a9b3bd0eec
@ -840,34 +840,34 @@ drop table t1;
|
|||||||
create table t1(f1 date, f2 time, f3 datetime);
|
create table t1(f1 date, f2 time, f3 datetime);
|
||||||
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
|
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
|
||||||
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
|
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
|
||||||
select f1 from t1 where f1 between "2006-1-1" and 20060101;
|
select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
|
||||||
f1
|
f1
|
||||||
2006-01-01
|
2006-01-01
|
||||||
select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
|
select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
|
||||||
f1
|
f1
|
||||||
2006-01-01
|
2006-01-01
|
||||||
select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
|
select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date);
|
||||||
f1
|
f1
|
||||||
2006-01-01
|
2006-01-01
|
||||||
select f2 from t1 where f2 between "12:1:2" and "12:2:2";
|
select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
|
||||||
f2
|
f2
|
||||||
12:01:02
|
12:01:02
|
||||||
select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
|
select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time);
|
||||||
f2
|
f2
|
||||||
12:01:02
|
12:01:02
|
||||||
select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
|
select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
|
||||||
f3
|
f3
|
||||||
2006-01-01 12:01:01
|
2006-01-01 12:01:01
|
||||||
select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
|
select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
|
||||||
f3
|
f3
|
||||||
2006-01-01 12:01:01
|
2006-01-01 12:01:01
|
||||||
select f1 from t1 where "2006-1-1" between f1 and f3;
|
select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
|
||||||
f1
|
f1
|
||||||
2006-01-01
|
2006-01-01
|
||||||
select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
|
select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
|
||||||
f1
|
f1
|
||||||
2006-01-01
|
2006-01-01
|
||||||
select f1 from t1 where "2006-1-1" between f1 and 'zzz';
|
select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
|
||||||
f1
|
f1
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect date value: 'zzz' for column 'f1' at row 1
|
Warning 1292 Incorrect date value: 'zzz' for column 'f1' at row 1
|
||||||
|
@ -63,9 +63,9 @@ Warnings:
|
|||||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,values(`test`.`t1`.`a`) AS `VALUES(a)` from `test`.`t1`
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,values(`test`.`t1`.`a`) AS `VALUES(a)` from `test`.`t1`
|
||||||
explain extended select * from t1 where values(a);
|
explain extended select * from t1 where values(a);
|
||||||
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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1`
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where values(`test`.`t1`.`a`)
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
create table t1(a int primary key, b int);
|
create table t1(a int primary key, b int);
|
||||||
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
|
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
|
||||||
@ -197,3 +197,25 @@ PRIMARY KEY (a)
|
|||||||
) ENGINE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
|
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1
|
||||||
|
(
|
||||||
|
a BIGINT UNSIGNED,
|
||||||
|
b BIGINT UNSIGNED,
|
||||||
|
PRIMARY KEY (a)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
45 1
|
||||||
|
INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
45 2
|
||||||
|
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
45 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -27,12 +27,12 @@ INSERT INTO t1 VALUES ( "2000-1-2" );
|
|||||||
INSERT INTO t1 VALUES ( "2000-1-3" );
|
INSERT INTO t1 VALUES ( "2000-1-3" );
|
||||||
INSERT INTO t1 VALUES ( "2000-1-4" );
|
INSERT INTO t1 VALUES ( "2000-1-4" );
|
||||||
INSERT INTO t1 VALUES ( "2000-1-5" );
|
INSERT INTO t1 VALUES ( "2000-1-5" );
|
||||||
SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
|
SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date);
|
||||||
datum
|
datum
|
||||||
2000-01-02
|
2000-01-02
|
||||||
2000-01-03
|
2000-01-03
|
||||||
2000-01-04
|
2000-01-04
|
||||||
SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
|
SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY;
|
||||||
datum
|
datum
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
@ -104,3 +104,9 @@ SELECT * FROM t1;
|
|||||||
y
|
y
|
||||||
0000
|
0000
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1(start_date date, end_date date);
|
||||||
|
insert into t1 values ('2000-01-01','2000-01-02');
|
||||||
|
select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop table t1;
|
||||||
|
@ -419,20 +419,20 @@ drop table t1;
|
|||||||
#
|
#
|
||||||
# Bug#16377 result of DATE/TIME functions were compared as strings which
|
# Bug#16377 result of DATE/TIME functions were compared as strings which
|
||||||
# can lead to a wrong result.
|
# can lead to a wrong result.
|
||||||
#
|
# Now wrong dates should be compared only with CAST()
|
||||||
create table t1(f1 date, f2 time, f3 datetime);
|
create table t1(f1 date, f2 time, f3 datetime);
|
||||||
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
|
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
|
||||||
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
|
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
|
||||||
select f1 from t1 where f1 between "2006-1-1" and 20060101;
|
select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
|
||||||
select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
|
select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
|
||||||
select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
|
select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date);
|
||||||
select f2 from t1 where f2 between "12:1:2" and "12:2:2";
|
select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
|
||||||
select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
|
select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time);
|
||||||
select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
|
select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
|
||||||
select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
|
select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
|
||||||
select f1 from t1 where "2006-1-1" between f1 and f3;
|
select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
|
||||||
select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
|
select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
|
||||||
select f1 from t1 where "2006-1-1" between f1 and 'zzz';
|
select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
|
||||||
select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
|
select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
|
||||||
select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
|
select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -115,4 +115,27 @@ INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
CREATE TABLE t1
|
||||||
|
(
|
||||||
|
a BIGINT UNSIGNED,
|
||||||
|
b BIGINT UNSIGNED,
|
||||||
|
PRIMARY KEY (a)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
|
||||||
|
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -36,8 +36,8 @@ INSERT INTO t1 VALUES ( "2000-1-2" );
|
|||||||
INSERT INTO t1 VALUES ( "2000-1-3" );
|
INSERT INTO t1 VALUES ( "2000-1-3" );
|
||||||
INSERT INTO t1 VALUES ( "2000-1-4" );
|
INSERT INTO t1 VALUES ( "2000-1-4" );
|
||||||
INSERT INTO t1 VALUES ( "2000-1-5" );
|
INSERT INTO t1 VALUES ( "2000-1-5" );
|
||||||
SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
|
SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date);
|
||||||
SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
|
SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -115,4 +115,11 @@ INSERT INTO t1 VALUES ('abc');
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN
|
||||||
|
#
|
||||||
|
create table t1(start_date date, end_date date);
|
||||||
|
insert into t1 values ('2000-01-01','2000-01-02');
|
||||||
|
select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date;
|
||||||
|
drop table t1;
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
@ -2184,7 +2184,11 @@ public:
|
|||||||
{
|
{
|
||||||
return Item_field::save_in_field(field_arg, no_conversions);
|
return Item_field::save_in_field(field_arg, no_conversions);
|
||||||
}
|
}
|
||||||
table_map used_tables() const { return (table_map)0L; }
|
/*
|
||||||
|
We use RAND_TABLE_BIT to prevent Item_insert_value from
|
||||||
|
being treated as a constant and precalculated before execution
|
||||||
|
*/
|
||||||
|
table_map used_tables() const { return RAND_TABLE_BIT; }
|
||||||
|
|
||||||
bool walk(Item_processor processor, byte *args)
|
bool walk(Item_processor processor, byte *args)
|
||||||
{
|
{
|
||||||
|
@ -77,131 +77,14 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
|
|||||||
This function aggregates result types from the array of items. Found type
|
This function aggregates result types from the array of items. Found type
|
||||||
supposed to be used later for comparison of values of these items.
|
supposed to be used later for comparison of values of these items.
|
||||||
Aggregation itself is performed by the item_cmp_type() function.
|
Aggregation itself is performed by the item_cmp_type() function.
|
||||||
|
|
||||||
NOTES
|
|
||||||
Aggregation rules:
|
|
||||||
If there are DATE/TIME fields/functions in the list and no string
|
|
||||||
fields/functions in the list then:
|
|
||||||
The INT_RESULT type will be used for aggregation instead of original
|
|
||||||
result type of any DATE/TIME field/function in the list
|
|
||||||
All constant items in the list will be converted to a DATE/TIME using
|
|
||||||
found field or result field of found function.
|
|
||||||
|
|
||||||
Implementation notes:
|
|
||||||
The code is equivalent to:
|
|
||||||
1. Check the list for presence of a STRING field/function.
|
|
||||||
Collect the is_const flag.
|
|
||||||
2. Get a Field* object to use for type coercion
|
|
||||||
3. Perform type conversion.
|
|
||||||
1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
|
|
||||||
field/function and checks presence of a STRING field/function.
|
|
||||||
The second loop works only if a DATE/TIME field/function is found.
|
|
||||||
It checks presence of a STRING field/function in the rest of the list.
|
|
||||||
|
|
||||||
TODO
|
|
||||||
1) The current implementation can produce false comparison results for
|
|
||||||
expressions like:
|
|
||||||
date_time_field BETWEEN string_field_with_dates AND string_constant
|
|
||||||
if the string_constant will omit some of leading zeroes.
|
|
||||||
In order to fully implement correct comparison of DATE/TIME the new
|
|
||||||
DATETIME_RESULT result type should be introduced and agg_cmp_type()
|
|
||||||
should return the DATE/TIME field used for the conversion. Later
|
|
||||||
this field can be used by comparison functions like Item_func_between to
|
|
||||||
convert string values to ints on the fly and thus return correct results.
|
|
||||||
This modification will affect functions BETWEEN, IN and CASE.
|
|
||||||
|
|
||||||
2) If in the list a DATE field/function and a DATETIME field/function
|
|
||||||
are present in the list then the first found field/function will be
|
|
||||||
used for conversion. This may lead to wrong results and probably should
|
|
||||||
be fixed.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
|
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
Item::Type res= (Item::Type)0;
|
type[0]= items[0]->result_type();
|
||||||
/* Used only for date/time fields, max_length = 19 */
|
for (i= 1 ; i < nitems ; i++)
|
||||||
char buff[20];
|
type[0]= item_cmp_type(type[0], items[i]->result_type());
|
||||||
uchar null_byte;
|
|
||||||
Field *field= NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Do not convert items while creating a or showing a view in order
|
|
||||||
to store/display the original query in these cases.
|
|
||||||
*/
|
|
||||||
if (thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
|
|
||||||
thd->lex->sql_command != SQLCOM_SHOW_CREATE)
|
|
||||||
{
|
|
||||||
/* Search for date/time fields/functions */
|
|
||||||
for (i= 0; i < nitems; i++)
|
|
||||||
{
|
|
||||||
if (!items[i]->result_as_longlong())
|
|
||||||
{
|
|
||||||
/* Do not convert anything if a string field/function is present */
|
|
||||||
if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT)
|
|
||||||
{
|
|
||||||
i= nitems;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM &&
|
|
||||||
items[i]->result_type() != INT_RESULT)
|
|
||||||
{
|
|
||||||
field= ((Item_field *)items[i]->real_item())->field;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (res == Item::FUNC_ITEM)
|
|
||||||
{
|
|
||||||
field= items[i]->tmp_table_field_from_field_type(0);
|
|
||||||
if (field)
|
|
||||||
field->move_field(buff, &null_byte, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (field)
|
|
||||||
{
|
|
||||||
/* Check the rest of the list for presence of a string field/function. */
|
|
||||||
for (i++ ; i < nitems; i++)
|
|
||||||
{
|
|
||||||
if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT &&
|
|
||||||
!items[i]->result_as_longlong())
|
|
||||||
{
|
|
||||||
if (res == Item::FUNC_ITEM)
|
|
||||||
delete field;
|
|
||||||
field= 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
If the first item is a date/time function then its result should be
|
|
||||||
compared as int
|
|
||||||
*/
|
|
||||||
if (field)
|
|
||||||
/* Suppose we are comparing dates */
|
|
||||||
type[0]= INT_RESULT;
|
|
||||||
else
|
|
||||||
type[0]= items[0]->result_type();
|
|
||||||
|
|
||||||
for (i= 0; i < nitems ; i++)
|
|
||||||
{
|
|
||||||
Item_result result= items[i]->result_type();
|
|
||||||
/*
|
|
||||||
Use INT_RESULT as result type for DATE/TIME fields/functions and
|
|
||||||
for constants successfully converted to DATE/TIME
|
|
||||||
*/
|
|
||||||
if (field &&
|
|
||||||
((!items[i]->const_item() && items[i]->result_as_longlong()) ||
|
|
||||||
(items[i]->const_item() && convert_constant_item(thd, field,
|
|
||||||
&items[i]))))
|
|
||||||
result= INT_RESULT;
|
|
||||||
type[0]= item_cmp_type(type[0], result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == Item::FUNC_ITEM && field)
|
|
||||||
delete field;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1220,10 +1103,30 @@ void Item_func_between::fix_length_and_dec()
|
|||||||
if (!args[0] || !args[1] || !args[2])
|
if (!args[0] || !args[1] || !args[2])
|
||||||
return;
|
return;
|
||||||
agg_cmp_type(thd, &cmp_type, args, 3);
|
agg_cmp_type(thd, &cmp_type, args, 3);
|
||||||
args[0]->cmp_context= args[1]->cmp_context= args[2]->cmp_context= cmp_type;
|
if (cmp_type == STRING_RESULT &&
|
||||||
|
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
|
||||||
|
return;
|
||||||
|
|
||||||
if (cmp_type == STRING_RESULT)
|
/*
|
||||||
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1);
|
Make a special case of compare with date/time and longlong fields.
|
||||||
|
They are compared as integers, so for const item this time-consuming
|
||||||
|
conversion can be done only once, not for every single comparison
|
||||||
|
*/
|
||||||
|
if (args[0]->type() == FIELD_ITEM)
|
||||||
|
{
|
||||||
|
Field *field=((Item_field*) args[0])->field;
|
||||||
|
if (field->can_be_compared_as_longlong())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The following can't be recoded with || as convert_constant_item
|
||||||
|
changes the argument
|
||||||
|
*/
|
||||||
|
if (convert_constant_item(thd, field,&args[1]))
|
||||||
|
cmp_type=INT_RESULT; // Works for all types.
|
||||||
|
if (convert_constant_item(thd, field,&args[2]))
|
||||||
|
cmp_type=INT_RESULT; // Works for all types.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9114,10 +9114,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
keyinfo->rec_per_key=0;
|
keyinfo->rec_per_key=0;
|
||||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||||
keyinfo->name= (char*) "group_key";
|
keyinfo->name= (char*) "group_key";
|
||||||
for (; group ; group=group->next,key_part_info++)
|
ORDER *cur_group= group;
|
||||||
|
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
|
||||||
{
|
{
|
||||||
Field *field=(*group->item)->get_tmp_table_field();
|
Field *field=(*cur_group->item)->get_tmp_table_field();
|
||||||
bool maybe_null=(*group->item)->maybe_null;
|
bool maybe_null=(*cur_group->item)->maybe_null;
|
||||||
key_part_info->null_bit=0;
|
key_part_info->null_bit=0;
|
||||||
key_part_info->field= field;
|
key_part_info->field= field;
|
||||||
key_part_info->offset= field->offset();
|
key_part_info->offset= field->offset();
|
||||||
@ -9130,8 +9131,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
0 : FIELDFLAG_BINARY;
|
0 : FIELDFLAG_BINARY;
|
||||||
if (!using_unique_constraint)
|
if (!using_unique_constraint)
|
||||||
{
|
{
|
||||||
group->buff=(char*) group_buff;
|
cur_group->buff=(char*) group_buff;
|
||||||
if (!(group->field= field->new_key_field(thd->mem_root,table,
|
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
|
||||||
(char*) group_buff +
|
(char*) group_buff +
|
||||||
test(maybe_null),
|
test(maybe_null),
|
||||||
field->null_ptr,
|
field->null_ptr,
|
||||||
@ -9149,12 +9150,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
key_part_info->null_bit=field->null_bit;
|
key_part_info->null_bit=field->null_bit;
|
||||||
key_part_info->null_offset= (uint) (field->null_ptr -
|
key_part_info->null_offset= (uint) (field->null_ptr -
|
||||||
(uchar*) table->record[0]);
|
(uchar*) table->record[0]);
|
||||||
group->buff++; // Pointer to field data
|
cur_group->buff++; // Pointer to field data
|
||||||
group_buff++; // Skipp null flag
|
group_buff++; // Skipp null flag
|
||||||
}
|
}
|
||||||
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
|
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
|
||||||
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
|
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
|
||||||
group_buff+= group->field->pack_length();
|
group_buff+= cur_group->field->pack_length();
|
||||||
}
|
}
|
||||||
keyinfo->key_length+= key_part_info->length;
|
keyinfo->key_length+= key_part_info->length;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user